From 8bedcc5195b00db92c27d0291c7cffecdc4f9d6d42af382317533979f08bf473 Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Thu, 7 Nov 2024 18:25:35 +0100 Subject: [PATCH] wip --- .gitignore | 2 + bots-common/Makefile | 3 +- bots-common/gitea_utils.go | 2 + bots-common/go.mod | 1 + bots-common/go.sum | 2 + bots-common/listen.go | 6 +- obs-staging-bot/main.go | 6 +- workflow-pr/go.mod | 5 +- workflow-pr/go.sum | 2 + workflow-pr/main.go | 155 +++++++------------------------------ workflow-pr/main_test.go | 54 +++++++++++++ workflow-pr/pr_closed.go | 36 +++++++++ workflow-pr/pr_opened.go | 58 ++++++++++++++ workflow-pr/pr_sync.go | 59 ++++++++++++++ 14 files changed, 258 insertions(+), 133 deletions(-) create mode 100644 .gitignore create mode 100644 workflow-pr/pr_closed.go create mode 100644 workflow-pr/pr_opened.go create mode 100644 workflow-pr/pr_sync.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1a63f15 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +mock + diff --git a/bots-common/Makefile b/bots-common/Makefile index debbcc1..23407ea 100644 --- a/bots-common/Makefile +++ b/bots-common/Makefile @@ -7,7 +7,8 @@ gitea-generated/client/gitea_api_client.go:: api.json [ -d gitea-generated ] || mkdir gitea-generated podman run --rm -v $$(pwd):/api ghcr.io/go-swagger/go-swagger generate client -f /api/api.json -t /api/gitea-generated -api: gitea-generated/client/gitea_api_client.go +api: gitea-generated/client/gitea_api_client.go mock_gitea_utils.go + go generate build: api go build diff --git a/bots-common/gitea_utils.go b/bots-common/gitea_utils.go index 3af0713..d2de081 100644 --- a/bots-common/gitea_utils.go +++ b/bots-common/gitea_utils.go @@ -36,6 +36,8 @@ import ( "src.opensuse.org/autogits/common/gitea-generated/models" ) +//go:generate mockgen -source=gitea_utils.go -destination=mock/gitea_utils.go -typed + const PrPattern = "PR: %s/%s#%d" const ( diff --git a/bots-common/go.mod b/bots-common/go.mod index 4784317..8f23084 100644 --- a/bots-common/go.mod +++ b/bots-common/go.mod @@ -9,6 +9,7 @@ require ( github.com/go-openapi/swag v0.23.0 github.com/go-openapi/validate v0.24.0 github.com/rabbitmq/amqp091-go v1.10.0 + go.uber.org/mock v0.5.0 ) require ( diff --git a/bots-common/go.sum b/bots-common/go.sum index 43e5142..4cfecde 100644 --- a/bots-common/go.sum +++ b/bots-common/go.sum @@ -68,6 +68,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= diff --git a/bots-common/listen.go b/bots-common/listen.go index 88b6568..7747b88 100644 --- a/bots-common/listen.go +++ b/bots-common/listen.go @@ -54,7 +54,9 @@ const RequestType_PRReviewRequest = "pull_request_review_request" const RequestType_PRReviewComment = "pull_request_review_comment" const RequestType_Wiki = "wiki" -type RequestProcessor func(*Request) error +type RequestProcessor interface { + ProcessFunc(*Request) error +} type ListenDefinitions struct { RabbitURL string // amqps://user:password@host/queue @@ -181,7 +183,7 @@ func ProcessEvent(f RequestProcessor, request *Request) { } }() - if err := f(request); err != nil { + if err := f.ProcessFunc(request); err != nil { log.Println(err) } diff --git a/obs-staging-bot/main.go b/obs-staging-bot/main.go index 372a68f..2892cc4 100644 --- a/obs-staging-bot/main.go +++ b/obs-staging-bot/main.go @@ -234,7 +234,7 @@ func processRepoBuildStatus(results, ref []common.PackageBuildStatus) BuildStatu return BuildStatusSummarySuccess } -func generateObsPrjMeta(git *common.GitHandler, gitea *common.GiteaTransport, pr *models.PullRequest, obsClient *common.ObsClient) (*common.ProjectMeta, error) { +func generateObsPrjMeta(git *common.GitHandler, gitea common.Gitea, pr *models.PullRequest, obsClient *common.ObsClient) (*common.ProjectMeta, error) { log.Println("repo content fetching ...") err := fetchPrGit(git, pr) if err != nil { @@ -312,7 +312,7 @@ func generateObsPrjMeta(git *common.GitHandler, gitea *common.GiteaTransport, pr return meta, nil } -func startOrUpdateBuild(git *common.GitHandler, gitea *common.GiteaTransport, pr *models.PullRequest, obsClient *common.ObsClient) error { +func startOrUpdateBuild(git *common.GitHandler, gitea common.Gitea, pr *models.PullRequest, obsClient *common.ObsClient) error { log.Println("fetching OBS project Meta") obsPrProject := getObsProjectAssociatedWithPr(obsClient.HomeProject, pr) meta, err := obsClient.GetProjectMeta(obsPrProject) @@ -353,7 +353,7 @@ func startOrUpdateBuild(git *common.GitHandler, gitea *common.GiteaTransport, pr return nil } -func processPullNotification(gitea *common.GiteaTransport, thread *models.NotificationThread) { +func processPullNotification(gitea common.Gitea, thread *models.NotificationThread) { defer func() { err := recover() if err != nil { diff --git a/workflow-pr/go.mod b/workflow-pr/go.mod index 5c56700..27e4884 100644 --- a/workflow-pr/go.mod +++ b/workflow-pr/go.mod @@ -4,7 +4,10 @@ go 1.23.2 replace src.opensuse.org/autogits/common => ../bots-common -require src.opensuse.org/autogits/common v0.0.0-00010101000000-000000000000 +require ( + go.uber.org/mock v0.5.0 + src.opensuse.org/autogits/common v0.0.0-00010101000000-000000000000 +) require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect diff --git a/workflow-pr/go.sum b/workflow-pr/go.sum index 43e5142..4cfecde 100644 --- a/workflow-pr/go.sum +++ b/workflow-pr/go.sum @@ -68,6 +68,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= diff --git a/workflow-pr/main.go b/workflow-pr/main.go index 1f8d911..55eb1b6 100644 --- a/workflow-pr/main.go +++ b/workflow-pr/main.go @@ -31,6 +31,8 @@ import ( "src.opensuse.org/autogits/common" ) +//go:generate mockgen -source=main.go -destination=mock/main.go -typed + const ( AppName = "workflow-pr" GitAuthor = "AutoGits - pr-review" @@ -56,32 +58,6 @@ func fetchPrGit(h *common.RequestHandler, pr *models.PullRequest) error { return h.Error }*/ -func processPullRequestClosed(req *common.PullRequestWebhookEvent, git *common.GitHandler, config *common.AutogitConfig) error { - if req.Repository.Name != config.GitProjectName { - return nil - } - - log.Println("request was:", req.Pull_Request.State) - - return nil - /* - req := h.Data.(*common.PullRequestAction) - - if req.Repository.Name != common.DefaultGitPrj { - // we only handle project git PR updates here - return nil - } - - if err := fetchPrGit(h, req.Pull_Request); err != nil { - return err - } - - headSubmodules := h.GitSubmoduleList(dir, pr.Head.Sha) - baseSubmodules := h.GitSubmoduleList(dir, pr.Base.Sha) - return nil - */ -} - func processPrjGitPullRequestSync(req *common.PullRequestWebhookEvent) error { // req := h.Data.(*common.PullRequestAction) @@ -101,95 +77,15 @@ func updateOrCreatePRBranch(req *common.PullRequestWebhookEvent, git *common.Git return nil } -func processPullRequestSync(req *common.PullRequestWebhookEvent, git *common.GitHandler, config *common.AutogitConfig) error { - if req.Repository.Name == config.GitProjectName { - return processPrjGitPullRequestSync(req) - } - - // need to verify that submodule in the PR for prjgit - // is still pointing to the HEAD of the PR - prjPr, err := gitea.GetAssociatedPrjGitPR(req) - if err != nil { - return fmt.Errorf("Cannot get associated PrjGit PR in processPullRequestSync. Err: %w", err) - } - - log.Println("associated pr:", prjPr) - - common.PanicOnError(git.GitExec("", "clone", "--branch", prjPr.Head.Name, "--depth", "1", prjPr.Head.Repo.SSHURL, common.DefaultGitPrj)) - commitId, ok := git.GitSubmoduleCommitId(common.DefaultGitPrj, req.Repository.Name, prjPr.Head.Sha) - - if !ok { - return fmt.Errorf("Cannot fetch submodule commit id in prjgit for '%s'", req.Repository.Name) - } - - // nothing changed, still in sync - if commitId == req.Pull_Request.Head.Sha { - log.Println("commitID already match - nothing to do") - return nil - } - - log.Printf("different ids: '%s' vs. '%s'\n", req.Pull_Request.Head.Sha, commitId) - - commitMsg := fmt.Sprintf(`Sync PR - -Update to %s`, req.Pull_Request.Head.Sha) - - log.Println("will create new commit msg:", commitMsg) - - // we need to update prjgit PR with the new head hash - branchName := prGitBranchNameForPR(req) - return updateOrCreatePRBranch(req, git, commitMsg, branchName) +type PullRequestProcessor interface { + Process(req *common.PullRequestWebhookEvent, git *common.GitHandler, config *common.AutogitConfig) error } -func processPullRequestOpened(req *common.PullRequestWebhookEvent, git *common.GitHandler, config *common.AutogitConfig) error { - // requests against project are not handled here - if req.Repository.Name == config.GitProjectName { - return nil - } - - // create PrjGit branch for buidling the pull request - branchName := prGitBranchNameForPR(req) - commitMsg := fmt.Sprintf(`auto-created for %s - -This commit was autocreated by %s -referencing - -PullRequest: %s/%s#%d`, req.Repository.Owner.Username, - req.Repository.Name, GitAuthor, req.Repository.Name, req.Pull_Request.Number) - - prjGit, err := gitea.CreateRepositoryIfNotExist(git, *req.Repository.Owner, config.GitProjectName) - if err != nil { - return err - } - - common.PanicOnError(git.GitExec("", "clone", "--depth", "1", prjGit.SSHURL, common.DefaultGitPrj)) - common.PanicOnError(git.GitExec(common.DefaultGitPrj, "checkout", "-B", branchName, prjGit.DefaultBranch)) - common.PanicOnError(updateOrCreatePRBranch(req, git, commitMsg, branchName)) - - PR, err := gitea.CreatePullRequestIfNotExist(prjGit, branchName, prjGit.DefaultBranch, - fmt.Sprintf("Forwarded PR: %s", req.Repository.Name), - fmt.Sprintf(`This is a forwarded pull request by %s -referencing the following pull request: - -`+common.PrPattern, - GitAuthor, req.Repository.Owner.Username, req.Repository.Name, req.Pull_Request.Number), - ) - - if err != nil { - return err - } - - // request build review - for _, reviewer := range config.Reviewers { - _, err := gitea.RequestReviews(PR, reviewer) - if err != nil { - return fmt.Errorf("Failed to create reviewer '%s' for request: %s/%s/%d Err: %w", reviewer, PR.Base.Repo.Owner.UserName, PR.Base.Repo.Name, PR.Index, err) - } - } - return err +type RequestProcessor struct { + Opened, Synced, Closed PullRequestProcessor } - -func processPullRequest(request *common.Request) error { + +func (w *RequestProcessor) ProcessFunc(request *common.Request) error { req, ok := request.Data.(*common.PullRequestWebhookEvent) if !ok { return fmt.Errorf("*** Invalid data format for PR processing.") @@ -221,14 +117,14 @@ func processPullRequest(request *common.Request) error { switch req.Action { case "opened", "reopened": - return processPullRequestOpened(req, git, config) + return w.Opened.Process(req, git, config) case "synchronized": - return processPullRequestSync(req, git, config) + return w.Synced.Process(req, git, config) case "edited": // not need to be handled?? return nil case "closed": - return processPullRequestClosed(req, git, config) + return w.Closed.Process(req, git, config) } return fmt.Errorf("Unhandled pull request action: %s", req.Action) @@ -238,7 +134,7 @@ var DebugMode bool var checkOnStart bool var checkInterval time.Duration -func verifyProjectState(git *common.GitHandler, orgName string, config *common.AutogitConfig, configs []*common.AutogitConfig) error { +func verifyProjectState(processor *RequestProcessor, git *common.GitHandler, orgName string, config *common.AutogitConfig, configs []*common.AutogitConfig) error { org := common.Organization{ Username: orgName, } @@ -288,9 +184,9 @@ nextSubmodule: switch pr.State { case "open": - processPullRequestOpened(&event, git, config) + processor.Opened.Process(&event, git, config) case "closed": - processPullRequestClosed(&event, git, config) + processor.Closed.Process(&event, git, config) default: return fmt.Errorf("Unhandled pull request state: '%s'. %s/%s/%d", pr.State, config.Organization, submoduleName, pr.Index) } @@ -336,7 +232,7 @@ nextSubmodule: return nil } -func checkRepos() { +func checkRepos(processor *RequestProcessor) { for org, configs := range configuredRepos { for _, config := range configs { if checkInterval > 0 { @@ -354,7 +250,7 @@ func checkRepos() { if !DebugMode { defer git.Close() } - if err := verifyProjectState(git, org, config, configs); err != nil { + if err := verifyProjectState(processor, git, org, config, configs); err != nil { log.Printf(" *** verification failed, org: `%s`, err: %#v\n", org, err) } log.Printf(" ++ verification complete, org: `%s` config: `%s`\n", org, config.GitProjectName) @@ -362,18 +258,18 @@ func checkRepos() { } } -func consistencyCheckProcess() { +func consistencyCheckProcess(processor *RequestProcessor) { if checkOnStart { savedCheckInterval := checkInterval checkInterval = 0 log.Println("== Startup consistency check begin...") - checkRepos() + checkRepos(processor) log.Println("== Startup consistency check done...") checkInterval = savedCheckInterval } for { - checkRepos() + checkRepos(processor) } } @@ -423,7 +319,14 @@ func main() { } gitea = common.AllocateGiteaTransport(*giteaHost) - go consistencyCheckProcess() + + req := new(RequestProcessor) + + req.Synced = &PullRequestSynced{} + req.Opened = &PullRequestOpened{} + req.Closed = &PullRequestClosed{} + + go consistencyCheckProcess(req) var defs common.ListenDefinitions @@ -431,8 +334,8 @@ func main() { defs.RabbitURL = *rabbitUrl defs.Handlers = make(map[string]common.RequestProcessor) - defs.Handlers[common.RequestType_PR] = processPullRequest - defs.Handlers[common.RequestType_PRSync] = processPullRequest + defs.Handlers[common.RequestType_PR] = req + defs.Handlers[common.RequestType_PRSync] = req log.Fatal(common.ProcessRabbitMQEvents(defs, orgs)) } diff --git a/workflow-pr/main_test.go b/workflow-pr/main_test.go index b061d62..49ac722 100644 --- a/workflow-pr/main_test.go +++ b/workflow-pr/main_test.go @@ -9,7 +9,12 @@ import ( "strings" "testing" + // "go.uber.org/mock/gomock" + "go.uber.org/mock/gomock" "src.opensuse.org/autogits/common" + mock_common "src.opensuse.org/autogits/common/mock" + mock_main "src.opensuse.org/workflow-pr/mock" + // "src.opensuse.org/autogits/common/mock" ) func TestProjectBranchName(t *testing.T) { @@ -193,3 +198,52 @@ func TestCreatePrBranch(t *testing.T) { } } + +func TestPRProcessor(t *testing.T) { + ctl := gomock.NewController(t) + defer ctl.Finish() + + var logBuf bytes.Buffer + oldOut := log.Writer() + log.SetOutput(&logBuf) + defer log.SetOutput(oldOut) + + req := &RequestProcessor { + Opened: mock_main.NewMockPullRequestProcessor(ctl), + Closed: mock_main.NewMockPullRequestProcessor(ctl), + Synced: mock_main.NewMockPullRequestProcessor(ctl), + } + + gitea = mock_common.NewMockGitea(ctl) + pr_opened := mock_main.NewMockPullRequestProcessor(ctl) + + pr_opened.EXPECT().Process(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) + + event := &common.PullRequestWebhookEvent { + Action: "opened", + Number: 1, + Pull_Request: &common.PullRequest { + Id: 1, + Base: common.Head { + Ref: "HEAD", + Sha: "abc", + Repo: nil, + }, + Head: common.Head { + Ref: "HEAD", + Sha: "abc", + Repo: nil, + }, + }, + } + + err := req.ProcessFunc(&common.Request{ + Data: event, + }) + + if err != nil { + t.Error("Error processing open PR", err) + t.Error(logBuf.String()) + } +} + diff --git a/workflow-pr/pr_closed.go b/workflow-pr/pr_closed.go new file mode 100644 index 0000000..323dfd7 --- /dev/null +++ b/workflow-pr/pr_closed.go @@ -0,0 +1,36 @@ +package main + +import ( + "log" + + "src.opensuse.org/autogits/common" +) + +type PullRequestClosed struct {} + +func (*PullRequestClosed) Process(req *common.PullRequestWebhookEvent, git *common.GitHandler, config *common.AutogitConfig) error { + if req.Repository.Name != config.GitProjectName { + return nil + } + + log.Println("request was:", req.Pull_Request.State) + + return nil + /* + req := h.Data.(*common.PullRequestAction) + + if req.Repository.Name != common.DefaultGitPrj { + // we only handle project git PR updates here + return nil + } + + if err := fetchPrGit(h, req.Pull_Request); err != nil { + return err + } + + headSubmodules := h.GitSubmoduleList(dir, pr.Head.Sha) + baseSubmodules := h.GitSubmoduleList(dir, pr.Base.Sha) + return nil + */ +} + diff --git a/workflow-pr/pr_opened.go b/workflow-pr/pr_opened.go new file mode 100644 index 0000000..881963f --- /dev/null +++ b/workflow-pr/pr_opened.go @@ -0,0 +1,58 @@ +package main + +import ( + "fmt" + + "src.opensuse.org/autogits/common" +) + +type PullRequestOpened struct { +} + +func (*PullRequestOpened) Process(req *common.PullRequestWebhookEvent, git *common.GitHandler, config *common.AutogitConfig) error { + // requests against project are not handled here + if req.Repository.Name == config.GitProjectName { + return nil + } + + // create PrjGit branch for buidling the pull request + branchName := prGitBranchNameForPR(req) + commitMsg := fmt.Sprintf(`auto-created for %s + +This commit was autocreated by %s +referencing + +PullRequest: %s/%s#%d`, req.Repository.Owner.Username, + req.Repository.Name, GitAuthor, req.Repository.Name, req.Pull_Request.Number) + + prjGit, err := gitea.CreateRepositoryIfNotExist(git, *req.Repository.Owner, config.GitProjectName) + if err != nil { + return err + } + + common.PanicOnError(git.GitExec("", "clone", "--depth", "1", prjGit.SSHURL, common.DefaultGitPrj)) + common.PanicOnError(git.GitExec(common.DefaultGitPrj, "checkout", "-B", branchName, prjGit.DefaultBranch)) + common.PanicOnError(updateOrCreatePRBranch(req, git, commitMsg, branchName)) + + PR, err := gitea.CreatePullRequestIfNotExist(prjGit, branchName, prjGit.DefaultBranch, + fmt.Sprintf("Forwarded PR: %s", req.Repository.Name), + fmt.Sprintf(`This is a forwarded pull request by %s +referencing the following pull request: + +`+common.PrPattern, + GitAuthor, req.Repository.Owner.Username, req.Repository.Name, req.Pull_Request.Number), + ) + + if err != nil { + return err + } + + // request build review + for _, reviewer := range config.Reviewers { + _, err := gitea.RequestReviews(PR, reviewer) + if err != nil { + return fmt.Errorf("Failed to create reviewer '%s' for request: %s/%s/%d Err: %w", reviewer, PR.Base.Repo.Owner.UserName, PR.Base.Repo.Name, PR.Index, err) + } + } + return err +} diff --git a/workflow-pr/pr_sync.go b/workflow-pr/pr_sync.go new file mode 100644 index 0000000..6da0458 --- /dev/null +++ b/workflow-pr/pr_sync.go @@ -0,0 +1,59 @@ +package main + +import ( + "fmt" + "log" + + "src.opensuse.org/autogits/common" +) +/* +func processPrjGitPullRequestSync(req *common.PullRequestWebhookEvent) error { + // req := h.Data.(*common.PullRequestAction) + + return nil +} +*/ + +type PullRequestSynced struct { +} + +func (*PullRequestSynced) Process(req *common.PullRequestWebhookEvent, git *common.GitHandler, config *common.AutogitConfig) error { + if req.Repository.Name == config.GitProjectName { + return processPrjGitPullRequestSync(req) + } + + // need to verify that submodule in the PR for prjgit + // is still pointing to the HEAD of the PR + prjPr, err := gitea.GetAssociatedPrjGitPR(req) + if err != nil { + return fmt.Errorf("Cannot get associated PrjGit PR in processPullRequestSync. Err: %w", err) + } + + log.Println("associated pr:", prjPr) + + common.PanicOnError(git.GitExec("", "clone", "--branch", prjPr.Head.Name, "--depth", "1", prjPr.Head.Repo.SSHURL, common.DefaultGitPrj)) + commitId, ok := git.GitSubmoduleCommitId(common.DefaultGitPrj, req.Repository.Name, prjPr.Head.Sha) + + if !ok { + return fmt.Errorf("Cannot fetch submodule commit id in prjgit for '%s'", req.Repository.Name) + } + + // nothing changed, still in sync + if commitId == req.Pull_Request.Head.Sha { + log.Println("commitID already match - nothing to do") + return nil + } + + log.Printf("different ids: '%s' vs. '%s'\n", req.Pull_Request.Head.Sha, commitId) + + commitMsg := fmt.Sprintf(`Sync PR + +Update to %s`, req.Pull_Request.Head.Sha) + + log.Println("will create new commit msg:", commitMsg) + + // we need to update prjgit PR with the new head hash + branchName := prGitBranchNameForPR(req) + return updateOrCreatePRBranch(req, git, commitMsg, branchName) +} +