workflow-direct: no panic if no changes
This commit is contained in:
@@ -46,13 +46,14 @@ type GitStatusLister interface {
|
|||||||
|
|
||||||
type Git interface {
|
type Git interface {
|
||||||
// error if git, but wrong remote
|
// error if git, but wrong remote
|
||||||
GitClone(repo, branch, remoteUrl string) error // clone, or check if path is already checked out remote and force pulls, error otherwise.
|
GitClone(repo, branch, remoteUrl string) (string, error) // clone, or check if path is already checked out remote and force pulls, error otherwise. Return remotename, errror
|
||||||
|
|
||||||
GitParseCommits(cwd string, commitIDs []string) (parsedCommits []GitCommit, err error)
|
GitParseCommits(cwd string, commitIDs []string) (parsedCommits []GitCommit, err error)
|
||||||
GitCatFile(cwd, commitId, filename string) (data []byte, err error)
|
GitCatFile(cwd, commitId, filename string) (data []byte, err error)
|
||||||
GetPath() string
|
GetPath() string
|
||||||
|
|
||||||
GitBranchHead(gitDir, branchName string) (string, error)
|
GitBranchHead(gitDir, branchName string) (string, error)
|
||||||
|
GitRemoteHead(gitDir, remoteName, branchName string) (string, error)
|
||||||
io.Closer
|
io.Closer
|
||||||
|
|
||||||
GitSubmoduleLister
|
GitSubmoduleLister
|
||||||
@@ -125,12 +126,9 @@ func (s *gitHandlerGeneratorImpl) CreateGitHandler(org string) (Git, error) {
|
|||||||
if fs, err := os.Stat(path); (err != nil && !os.IsNotExist(err)) || (err == nil && !fs.IsDir()) {
|
if fs, err := os.Stat(path); (err != nil && !os.IsNotExist(err)) || (err == nil && !fs.IsDir()) {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if err != nil && os.IsNotExist(err) {
|
} else if err != nil && os.IsNotExist(err) {
|
||||||
log.Println("creating dirs")
|
|
||||||
if err := os.MkdirAll(path, 0o777); err != nil && !os.IsExist(err) {
|
if err := os.MkdirAll(path, 0o777); err != nil && !os.IsExist(err) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
log.Println(fs, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.ReadExistingPath(org)
|
return s.ReadExistingPath(org)
|
||||||
@@ -200,10 +198,10 @@ func (refs *GitReferences) addReference(id, branch string) {
|
|||||||
refs.refs = append(refs.refs, GitReference{Branch: branch, Id: id})
|
refs.refs = append(refs.refs, GitReference{Branch: branch, Id: id})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) error {
|
func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) (string, error) {
|
||||||
remoteUrlComp, err := ParseGitRemoteUrl(remoteUrl)
|
remoteUrlComp, err := ParseGitRemoteUrl(remoteUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Cannot parse remote URL: %w", err)
|
return "", fmt.Errorf("Cannot parse remote URL: %w", err)
|
||||||
}
|
}
|
||||||
if len(branch) == 0 {
|
if len(branch) == 0 {
|
||||||
branch = remoteUrlComp.Commit
|
branch = remoteUrlComp.Commit
|
||||||
@@ -217,10 +215,10 @@ func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) error {
|
|||||||
|
|
||||||
if fi, err := os.Stat(path.Join(e.GitPath, repo)); os.IsNotExist(err) {
|
if fi, err := os.Stat(path.Join(e.GitPath, repo)); os.IsNotExist(err) {
|
||||||
if err = e.GitExec("", "clone", "--origin", remoteName, remoteUrl, repo); err != nil {
|
if err = e.GitExec("", "clone", "--origin", remoteName, remoteUrl, repo); err != nil {
|
||||||
return err
|
return remoteName, err
|
||||||
}
|
}
|
||||||
} else if err != nil || !fi.IsDir() {
|
} else if err != nil || !fi.IsDir() {
|
||||||
return fmt.Errorf("Clone location not a directory or Stat error: %w", err)
|
return remoteName, fmt.Errorf("Clone location not a directory or Stat error: %w", err)
|
||||||
} else {
|
} else {
|
||||||
clonedRemote := strings.TrimSpace(e.GitExecWithOutputOrPanic(repo, "remote", "get-url", remoteName))
|
clonedRemote := strings.TrimSpace(e.GitExecWithOutputOrPanic(repo, "remote", "get-url", remoteName))
|
||||||
if clonedRemote != remoteUrl {
|
if clonedRemote != remoteUrl {
|
||||||
@@ -229,7 +227,7 @@ func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) error {
|
|||||||
|
|
||||||
e.GitExecOrPanic(repo, "fetch", remoteName, branch)
|
e.GitExecOrPanic(repo, "fetch", remoteName, branch)
|
||||||
}
|
}
|
||||||
return e.GitExec(repo, "checkout", "-B", branch, "refs/remotes/"+remoteName+"/"+branch)
|
return remoteName, e.GitExec(repo, "checkout", "-B", branch, "refs/remotes/"+remoteName+"/"+branch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *GitHandlerImpl) GitBranchHead(gitDir, branchName string) (string, error) {
|
func (e *GitHandlerImpl) GitBranchHead(gitDir, branchName string) (string, error) {
|
||||||
@@ -241,6 +239,15 @@ func (e *GitHandlerImpl) GitBranchHead(gitDir, branchName string) (string, error
|
|||||||
return strings.TrimSpace(id), nil
|
return strings.TrimSpace(id), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *GitHandlerImpl) GitRemoteHead(gitDir, remote, branchName string) (string, error) {
|
||||||
|
id, err := e.GitExecWithOutput(gitDir, "show-ref", "--hash", "--verify", "refs/remotes/"+remote+"/"+branchName)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("Can't find default branch: %s", branchName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.TrimSpace(id), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (e *GitHandlerImpl) Close() error {
|
func (e *GitHandlerImpl) Close() error {
|
||||||
e.lock.Unlock()
|
e.lock.Unlock()
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ func TestGitClone(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := g.GitClone(test.repo, test.branch, "file://"+d+test.remoteUrl); err != nil {
|
if _, err := g.GitClone(test.repo, test.branch, "file://"+d+test.remoteUrl); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -201,6 +201,10 @@ func (gitea *GiteaTransport) GetPullRequest(org, project string, num int64) (*mo
|
|||||||
func (gitea *GiteaTransport) GetRepository(org, pkg string) (*models.Repository, error) {
|
func (gitea *GiteaTransport) GetRepository(org, pkg string) (*models.Repository, error) {
|
||||||
repo, err := gitea.client.Repository.RepoGet(repository.NewRepoGetParams().WithDefaults().WithOwner(org).WithRepo(pkg), gitea.transport.DefaultAuthentication)
|
repo, err := gitea.client.Repository.RepoGet(repository.NewRepoGetParams().WithDefaults().WithOwner(org).WithRepo(pkg), gitea.transport.DefaultAuthentication)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
switch err.(type) {
|
||||||
|
case *repository.RepoGetNotFound:
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -627,6 +631,10 @@ func (gitea *GiteaTransport) GetRecentCommits(org, repo, branch string, commitNo
|
|||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
switch err.(type) {
|
||||||
|
case *repository.RepoGetAllCommitsNotFound:
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package main
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
@@ -107,9 +106,8 @@ func processConfiguredRepositoryAction(action *common.RepositoryWebhookEvent, co
|
|||||||
return fmt.Errorf("Error accessing/creating prjgit: %s/%s#%d err: %w", gitOrg, gitPrj, gitBranch, err)
|
return fmt.Errorf("Error accessing/creating prjgit: %s/%s#%d err: %w", gitOrg, gitPrj, gitBranch, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := fs.Stat(os.DirFS(git.GetPath()), config.GitProjectName); errors.Is(err, os.ErrNotExist) {
|
_, err = git.GitClone(gitPrj, gitBranch, prjGitRepo.SSHURL)
|
||||||
common.PanicOnError(git.GitClone(gitPrj, gitBranch, prjGitRepo.SSHURL))
|
common.PanicOnError(err)
|
||||||
}
|
|
||||||
|
|
||||||
switch action.Action {
|
switch action.Action {
|
||||||
case "created":
|
case "created":
|
||||||
@@ -194,9 +192,16 @@ func processConfiguredPushAction(action *common.PushWebhookEvent, config *common
|
|||||||
return fmt.Errorf("Error accessing/creating prjgit: %s/%s err: %w", gitOrg, gitPrj, err)
|
return fmt.Errorf("Error accessing/creating prjgit: %s/%s err: %w", gitOrg, gitPrj, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := fs.Stat(os.DirFS(git.GetPath()), gitPrj); errors.Is(err, os.ErrNotExist) {
|
remoteName, err := git.GitClone(gitPrj, gitBranch, prjGitRepo.SSHURL)
|
||||||
common.PanicOnError(git.GitClone(gitPrj, gitBranch, prjGitRepo.SSHURL))
|
common.PanicOnError(err)
|
||||||
|
headCommitId, err := git.GitRemoteHead(gitPrj, remoteName, gitBranch)
|
||||||
|
common.PanicOnError(err)
|
||||||
|
commit, ok := git.GitSubmoduleCommitId(gitPrj, action.Repository.Name, headCommitId)
|
||||||
|
for ok && action.Head_Commit.Id == commit {
|
||||||
|
log.Println(" -- nothing to do, commit already in ProjectGit")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if stat, err := os.Stat(filepath.Join(git.GetPath(), gitPrj, action.Repository.Name)); err != nil || !stat.IsDir() {
|
if stat, err := os.Stat(filepath.Join(git.GetPath(), gitPrj, action.Repository.Name)); err != nil || !stat.IsDir() {
|
||||||
if DebugMode {
|
if DebugMode {
|
||||||
log.Println("Pushed to package that is not part of the project. Ignoring:", err)
|
log.Println("Pushed to package that is not part of the project. Ignoring:", err)
|
||||||
@@ -209,17 +214,15 @@ func processConfiguredPushAction(action *common.PushWebhookEvent, config *common
|
|||||||
if err := git.GitExec(filepath.Join(gitPrj, action.Repository.Name), "fetch", "--depth", "1", "--force", "origin", config.Branch+":"+config.Branch); err != nil {
|
if err := git.GitExec(filepath.Join(gitPrj, action.Repository.Name), "fetch", "--depth", "1", "--force", "origin", config.Branch+":"+config.Branch); err != nil {
|
||||||
return fmt.Errorf("error fetching branch %s. ignoring as non-existent. err: %w", config.Branch, err) // no branch? so ignore repo here
|
return fmt.Errorf("error fetching branch %s. ignoring as non-existent. err: %w", config.Branch, err) // no branch? so ignore repo here
|
||||||
}
|
}
|
||||||
id, err := git.GitBranchHead(filepath.Join(gitPrj, action.Repository.Name), config.Branch)
|
id, err := git.GitRemoteHead(filepath.Join(gitPrj, action.Repository.Name), "origin", config.Branch)
|
||||||
common.PanicOnError(err)
|
common.PanicOnError(err)
|
||||||
for _, commitId := range action.Commits {
|
if action.Head_Commit.Id == id {
|
||||||
if commitId.Id == id {
|
git.GitExecOrPanic(filepath.Join(gitPrj, action.Repository.Name), "checkout", id)
|
||||||
git.GitExecOrPanic(filepath.Join(gitPrj, action.Repository.Name), "checkout", id)
|
git.GitExecOrPanic(gitPrj, "commit", "-a", "-m", "Automatic update via push via Direct Workflow")
|
||||||
git.GitExecOrPanic(gitPrj, "commit", "-a", "-m", "Automatic update via push via Direct Workflow")
|
if !noop {
|
||||||
if !noop {
|
git.GitExecOrPanic(gitPrj, "push")
|
||||||
git.GitExecOrPanic(gitPrj, "push")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("push of refs not on the configured branch", config.Branch, ". ignoring.")
|
log.Println("push of refs not on the configured branch", config.Branch, ". ignoring.")
|
||||||
@@ -243,9 +246,8 @@ func verifyProjectState(git common.Git, org string, config *common.AutogitConfig
|
|||||||
return fmt.Errorf("Error fetching or creating '%s/%s' -- aborting verifyProjectState(). Err: %w", gitOrg, gitPrj, err)
|
return fmt.Errorf("Error fetching or creating '%s/%s' -- aborting verifyProjectState(). Err: %w", gitOrg, gitPrj, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := fs.Stat(os.DirFS(git.GetPath()), gitPrj); errors.Is(err, os.ErrNotExist) {
|
_, err = git.GitClone(gitPrj, gitBranch, repo.SSHURL)
|
||||||
common.PanicOnError(git.GitClone(gitPrj, gitBranch, repo.SSHURL))
|
common.PanicOnError(err)
|
||||||
}
|
|
||||||
defer func() { common.PanicOnError(git.GitExec(gitPrj, "submodule", "deinit", "--all")) }()
|
defer func() { common.PanicOnError(git.GitExec(gitPrj, "submodule", "deinit", "--all")) }()
|
||||||
|
|
||||||
log.Println(" * Getting submodule list")
|
log.Println(" * Getting submodule list")
|
||||||
@@ -281,20 +283,18 @@ next_package:
|
|||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
|
|
||||||
log.Println(" verifying package:", filename, commitId, config.Branch)
|
log.Printf(" verifying package: %s -> %s(%s)", commitId, filename, config.Branch)
|
||||||
commits, err := gitea.GetRecentCommits(org, filename, config.Branch, 10)
|
commits, err := gitea.GetRecentCommits(org, filename, config.Branch, 10)
|
||||||
if err != nil {
|
if len(commits) == 0 {
|
||||||
// assumption that package does not exist, remove from project
|
if repo, err := gitea.GetRepository(org, filename); repo == nil && err == nil {
|
||||||
// https://github.com/go-gitea/gitea/issues/31976
|
git.GitExecOrPanic(gitPrj, "rm", filename)
|
||||||
if err := git.GitExec(gitPrj, "rm", filename); err != nil {
|
isGitUpdated = true
|
||||||
return fmt.Errorf("Failed to remove deleted submodule. Err: %w", err)
|
|
||||||
}
|
}
|
||||||
isGitUpdated = true
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Println(" -> failed to fetch recent commits for package:", filename, " Err:", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// if err != nil {
|
|
||||||
// return fmt.Errorf("Failed to fetch recent commits for package: '%s'. Err: %w", filename, err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
idx := 1000
|
idx := 1000
|
||||||
for i, c := range commits {
|
for i, c := range commits {
|
||||||
@@ -340,10 +340,11 @@ next_package:
|
|||||||
common.PanicOnError(git.GitExec(gitPrj, "submodule", "update", "--init", "--depth", "1", "--checkout", filename))
|
common.PanicOnError(git.GitExec(gitPrj, "submodule", "update", "--init", "--depth", "1", "--checkout", filename))
|
||||||
common.PanicOnError(git.GitExec(filepath.Join(gitPrj, filename), "fetch", "--depth", "1", "origin", commits[0].SHA))
|
common.PanicOnError(git.GitExec(filepath.Join(gitPrj, filename), "fetch", "--depth", "1", "origin", commits[0].SHA))
|
||||||
common.PanicOnError(git.GitExec(filepath.Join(gitPrj, filename), "checkout", commits[0].SHA))
|
common.PanicOnError(git.GitExec(filepath.Join(gitPrj, filename), "checkout", commits[0].SHA))
|
||||||
|
log.Println(" -> updated to", commits[0].SHA)
|
||||||
isGitUpdated = true
|
isGitUpdated = true
|
||||||
} else {
|
} else {
|
||||||
// probably need `merge-base` or `rev-list` here instead, or the project updated already
|
// probably need `merge-base` or `rev-list` here instead, or the project updated already
|
||||||
return fmt.Errorf("Cannot find SHA of last matching update for package: '%s'. idx: %d", filename, idx)
|
log.Println(" *** Cannot find SHA of last matching update for package:", filename, " Ignoring")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user