workflow-direct: no panic if no changes

This commit is contained in:
2025-04-17 15:12:51 +02:00
parent bfeac63c57
commit f0de3ad54a
4 changed files with 55 additions and 39 deletions

View File

@@ -46,13 +46,14 @@ type GitStatusLister interface {
type Git interface {
// 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)
GitCatFile(cwd, commitId, filename string) (data []byte, err error)
GetPath() string
GitBranchHead(gitDir, branchName string) (string, error)
GitRemoteHead(gitDir, remoteName, branchName string) (string, error)
io.Closer
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()) {
return nil, err
} else if err != nil && os.IsNotExist(err) {
log.Println("creating dirs")
if err := os.MkdirAll(path, 0o777); err != nil && !os.IsExist(err) {
return nil, err
}
} else {
log.Println(fs, err)
}
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})
}
func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) error {
func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) (string, error) {
remoteUrlComp, err := ParseGitRemoteUrl(remoteUrl)
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 {
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 err = e.GitExec("", "clone", "--origin", remoteName, remoteUrl, repo); err != nil {
return err
return remoteName, err
}
} 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 {
clonedRemote := strings.TrimSpace(e.GitExecWithOutputOrPanic(repo, "remote", "get-url", remoteName))
if clonedRemote != remoteUrl {
@@ -229,7 +227,7 @@ func (e *GitHandlerImpl) GitClone(repo, branch, remoteUrl string) error {
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) {
@@ -241,6 +239,15 @@ func (e *GitHandlerImpl) GitBranchHead(gitDir, branchName string) (string, error
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 {
e.lock.Unlock()
return nil

View File

@@ -77,7 +77,7 @@ func TestGitClone(t *testing.T) {
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)
}

View File

@@ -201,6 +201,10 @@ func (gitea *GiteaTransport) GetPullRequest(org, project string, num int64) (*mo
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)
if err != nil {
switch err.(type) {
case *repository.RepoGetNotFound:
return nil, nil
}
return nil, err
}
@@ -627,6 +631,10 @@ func (gitea *GiteaTransport) GetRecentCommits(org, repo, branch string, commitNo
)
if err != nil {
switch err.(type) {
case *repository.RepoGetAllCommitsNotFound:
return nil, nil
}
return nil, err
}

View File

@@ -19,7 +19,6 @@ package main
*/
import (
"errors"
"flag"
"fmt"
"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)
}
if _, err := fs.Stat(os.DirFS(git.GetPath()), config.GitProjectName); errors.Is(err, os.ErrNotExist) {
common.PanicOnError(git.GitClone(gitPrj, gitBranch, prjGitRepo.SSHURL))
}
_, err = git.GitClone(gitPrj, gitBranch, prjGitRepo.SSHURL)
common.PanicOnError(err)
switch action.Action {
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)
}
if _, err := fs.Stat(os.DirFS(git.GetPath()), gitPrj); errors.Is(err, os.ErrNotExist) {
common.PanicOnError(git.GitClone(gitPrj, gitBranch, prjGitRepo.SSHURL))
remoteName, err := 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 DebugMode {
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 {
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)
for _, commitId := range action.Commits {
if commitId.Id == id {
git.GitExecOrPanic(filepath.Join(gitPrj, action.Repository.Name), "checkout", id)
git.GitExecOrPanic(gitPrj, "commit", "-a", "-m", "Automatic update via push via Direct Workflow")
if !noop {
git.GitExecOrPanic(gitPrj, "push")
}
return nil
if action.Head_Commit.Id == id {
git.GitExecOrPanic(filepath.Join(gitPrj, action.Repository.Name), "checkout", id)
git.GitExecOrPanic(gitPrj, "commit", "-a", "-m", "Automatic update via push via Direct Workflow")
if !noop {
git.GitExecOrPanic(gitPrj, "push")
}
return nil
}
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)
}
if _, err := fs.Stat(os.DirFS(git.GetPath()), gitPrj); errors.Is(err, os.ErrNotExist) {
common.PanicOnError(git.GitClone(gitPrj, gitBranch, repo.SSHURL))
}
_, err = git.GitClone(gitPrj, gitBranch, repo.SSHURL)
common.PanicOnError(err)
defer func() { common.PanicOnError(git.GitExec(gitPrj, "submodule", "deinit", "--all")) }()
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)
if err != nil {
// assumption that package does not exist, remove from project
// https://github.com/go-gitea/gitea/issues/31976
if err := git.GitExec(gitPrj, "rm", filename); err != nil {
return fmt.Errorf("Failed to remove deleted submodule. Err: %w", err)
if len(commits) == 0 {
if repo, err := gitea.GetRepository(org, filename); repo == nil && err == nil {
git.GitExecOrPanic(gitPrj, "rm", filename)
isGitUpdated = true
}
isGitUpdated = true
}
if err != nil {
log.Println(" -> failed to fetch recent commits for package:", filename, " Err:", err)
continue
}
// if err != nil {
// return fmt.Errorf("Failed to fetch recent commits for package: '%s'. Err: %w", filename, err)
// }
idx := 1000
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(filepath.Join(gitPrj, filename), "fetch", "--depth", "1", "origin", commits[0].SHA))
common.PanicOnError(git.GitExec(filepath.Join(gitPrj, filename), "checkout", commits[0].SHA))
log.Println(" -> updated to", commits[0].SHA)
isGitUpdated = true
} else {
// 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")
}
}
}