diff --git a/docs/content/docs/install/settings.md b/docs/content/docs/install/settings.md index 7ca358dcd2..2aefa204c6 100644 --- a/docs/content/docs/install/settings.md +++ b/docs/content/docs/install/settings.md @@ -164,6 +164,9 @@ There are a few things you can configure through the ConfigMap Default: `true` + **Note:** This setting does not apply to git tag push events. Tag push events will always trigger + pipeline runs regardless of whether the tagged commit is part of an open pull request. + {{< support_matrix github_app="true" github_webhook="true" gitea="false" gitlab="false" bitbucket_cloud="false" bitbucket_datacenter="false" >}} ### Global Cancel In Progress Settings diff --git a/pkg/provider/github/parse_payload.go b/pkg/provider/github/parse_payload.go index 32a19670db..c542d7b130 100644 --- a/pkg/provider/github/parse_payload.go +++ b/pkg/provider/github/parse_payload.go @@ -346,8 +346,14 @@ func (v *Provider) processEvent(ctx context.Context, event *info.Event, eventInt v.Logger.Warnf("Error getting pull requests associated with the commit in this push event: %v", err) } - // Only check if the flag is enabled and there are pull requests associated with this commit. - if v.pacInfo.SkipPushEventForPRCommits && len(prs) > 0 { + isGitTagEvent := strings.HasPrefix(gitEvent.GetRef(), "refs/tags/") + + if v.pacInfo.SkipPushEventForPRCommits && isGitTagEvent { + v.Logger.Infof("Processing tag push event for commit %s despite skip-push-events-for-pr-commits being enabled (tag events are excluded from this setting)", sha) + } + + // Only check if the flag is enabled, and there are pull requests associated with this commit, and it's not a tag push event. + if v.pacInfo.SkipPushEventForPRCommits && len(prs) > 0 && !isGitTagEvent { isPartOfPR, prNumber := v.isCommitPartOfPullRequest(sha, org, repoName, prs) // If the commit is part of a PR, skip processing the push event diff --git a/pkg/provider/github/parse_payload_test.go b/pkg/provider/github/parse_payload_test.go index b77c009d2d..55b77b38e1 100644 --- a/pkg/provider/github/parse_payload_test.go +++ b/pkg/provider/github/parse_payload_test.go @@ -356,6 +356,18 @@ func TestParsePayLoad(t *testing.T) { samplePRNoRepo.Repo = nil samplePrEventClosed := samplePRevent samplePrEventClosed.Action = github.Ptr("closed") + + sampleGhPRs := []*github.PullRequest{ + { + Number: github.Ptr(41), + State: github.Ptr("closed"), + }, + { + Number: github.Ptr(42), + State: github.Ptr("open"), + }, + } + tests := []struct { name string wantErrString string @@ -371,6 +383,7 @@ func TestParsePayLoad(t *testing.T) { wantedBranchName string wantedTagName string isCancelPipelineRunEnabled bool + skipPushEventForPRCommits bool }{ { name: "bad/unknown event", @@ -897,6 +910,41 @@ func TestParsePayLoad(t *testing.T) { wantedBranchName: "main", wantErrString: "provided SHA samplePRshanew is not the HEAD commit of the branch main", }, + { + name: "good/skip push event for skip-pr-commits setting", + eventType: "push", + triggerTarget: "push", + githubClient: true, + payloadEventStruct: github.PushEvent{ + Ref: github.Ptr("refs/heads/main"), + Repo: &github.PushEventRepository{ + Owner: &github.User{Login: github.Ptr("owner")}, + Name: github.Ptr("pushRepo"), + }, + HeadCommit: &github.HeadCommit{ID: github.Ptr("SHAPush")}, + }, + shaRet: "SHAPush", + skipPushEventForPRCommits: true, + muxReplies: map[string]any{"/repos/owner/pushRepo/commits/SHAPush/pulls": sampleGhPRs}, + wantErrString: "commit SHAPush is part of pull request #42, skipping push event", + }, + { + name: "good/skip tag push event for skip-pr-commits setting", + eventType: "push", + triggerTarget: "push", + githubClient: true, + payloadEventStruct: github.PushEvent{ + Ref: github.Ptr("refs/tags/v1.0.0"), + Repo: &github.PushEventRepository{ + Owner: &github.User{Login: github.Ptr("owner")}, + Name: github.Ptr("pushRepo"), + }, + HeadCommit: &github.HeadCommit{ID: github.Ptr("SHAPush")}, + }, + shaRet: "SHAPush", + skipPushEventForPRCommits: true, + muxReplies: map[string]any{"/repos/owner/pushRepo/commits/SHAPush/pulls": sampleGhPRs}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -969,7 +1017,7 @@ func TestParsePayLoad(t *testing.T) { ghClient: ghClient, Logger: logger, pacInfo: &info.PacOpts{ - Settings: settings.Settings{}, + Settings: settings.Settings{SkipPushEventForPRCommits: tt.skipPushEventForPRCommits}, }, } request := &http.Request{Header: map[string][]string{}} diff --git a/test/gitea_params_test.go b/test/gitea_params_test.go index e434e4b7e8..ead963de31 100644 --- a/test/gitea_params_test.go +++ b/test/gitea_params_test.go @@ -1,3 +1,5 @@ +//go:build e2e + package test import ( diff --git a/test/github_pullrequest_test.go b/test/github_pullrequest_test.go index 923a2786dc..cb74e93c2c 100644 --- a/test/github_pullrequest_test.go +++ b/test/github_pullrequest_test.go @@ -1,3 +1,5 @@ +//go:build e2e + package test import ( @@ -23,6 +25,7 @@ import ( "github.com/google/go-github/v74/github" tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/names" "gotest.tools/v3/assert" "gotest.tools/v3/assert/cmp" "gotest.tools/v3/golden" @@ -651,6 +654,37 @@ func TestGithubDisableCommentsOnPR(t *testing.T) { assert.Equal(t, 0, successCommentsPost) } +func TestGithubIgnoreTagPushCommitsFromSkipPushEventsSetting(t *testing.T) { + ctx := context.Background() + g := &tgithub.PRTest{ + Label: "Github PullRequest", + YamlFiles: []string{"testdata/pipelinerun.yaml"}, + NoStatusCheck: true, + } + g.RunPullRequest(ctx, t) + defer g.TearDown(ctx, t) + + tag := names.SimpleNameGenerator.RestrictLengthWithRandomSuffix("v1.0") + + _, err := tgithub.CreateTag(ctx, t, g.Cnx, g.Provider, g.Options, g.SHA, tag) + assert.NilError(t, err) + defer tgithub.DeleteTag(ctx, g.Provider, g.Options, tag) //nolint:errcheck + + globalNs, _, err := params.GetInstallLocation(ctx, g.Cnx) + assert.NilError(t, err) + ctx = info.StoreNS(ctx, globalNs) + + reg := regexp.MustCompile(fmt.Sprintf("Processing tag push event for commit %s despite skip-push-events-for-pr-commits being enabled.*", g.SHA)) + maxLines := int64(100) + err = twait.RegexpMatchingInControllerLog(ctx, g.Cnx, *reg, 20, "controller", &maxLines) + assert.NilError(t, err) + + g.Cnx.Clients.Log.Infof("Deleting tag %s", tag) + err = tgithub.DeleteTag(ctx, g.Provider, g.Options, tag) + assert.NilError(t, err) + g.Cnx.Clients.Log.Infof("Tag %s has been deleted", tag) +} + // Local Variables: // compile-command: "go test -tags=e2e -v -info TestGithubPullRequest$ ." // End: diff --git a/test/github_tag_gitops_test.go b/test/github_tag_gitops_test.go index e7ddb8f76f..4ab98c401d 100644 --- a/test/github_tag_gitops_test.go +++ b/test/github_tag_gitops_test.go @@ -1,3 +1,5 @@ +//go:build e2e + package test import ( diff --git a/test/pkg/github/tag.go b/test/pkg/github/tag.go index 91a1d4b320..f6fc954f2a 100644 --- a/test/pkg/github/tag.go +++ b/test/pkg/github/tag.go @@ -29,8 +29,6 @@ func CreateTag(ctx context.Context, t *testing.T, runcnx *params.Run, ghcnx *pac tag, _, err := ghcnx.Client().Git.CreateTag(ctx, opts.Organization, opts.Repo, tag) assert.NilError(t, err) - runcnx.Clients.Log.Infof("Tag %s has been created successfully", *tag.SHA) - refToCreate := &github.Reference{ Ref: github.Ptr("refs/tags/" + tagName), Object: &github.GitObject{SHA: tag.SHA}, @@ -41,3 +39,8 @@ func CreateTag(ctx context.Context, t *testing.T, runcnx *params.Run, ghcnx *pac return tag, nil } + +func DeleteTag(ctx context.Context, ghcnx *pacgithub.Provider, opts options.E2E, tagName string) error { + _, err := ghcnx.Client().Git.DeleteRef(ctx, opts.Organization, opts.Repo, "refs/tags/"+tagName) + return err +}