diff --git a/docs/content/docs/guide/running.md b/docs/content/docs/guide/running.md index 185a5bb8c..50296e819 100644 --- a/docs/content/docs/guide/running.md +++ b/docs/content/docs/guide/running.md @@ -114,12 +114,12 @@ entire suite of checks once again. ![github apps rerun check](/images/github-apps-rerun-checks.png) -### Gitops command on pull or merge request +### Gitops command on push, pull or merge request -If you are targeting a pull or merge request you can use `GitOps` comment +If you are targeting a push, pull or merge request you can use `GitOps` comment inside your pull request, to restart all or specific Pipelines. -For example you want to restart all your pipeline you can add a comment starting +For example, you want to restart all your pipeline you can add a comment starting with `/retest` and all PipelineRun attached to that pull or merge request will be restarted : @@ -146,7 +146,7 @@ roses are red, violets are blue. pipeline are bound to flake by design. You can cancel a running PipelineRun by commenting on the PullRequest. For example if you want to cancel all your PipelinerRuns you can add a comment starting -with `/cancel` and all PipelineRun attached to that pull or merge request will be cancelled. +with `/cancel` and all PipelineRun attached to that push, pull or merge request will be cancelled. Example : diff --git a/docs/content/docs/install/github_apps.md b/docs/content/docs/install/github_apps.md index 39462a746..3a852736f 100644 --- a/docs/content/docs/install/github_apps.md +++ b/docs/content/docs/install/github_apps.md @@ -48,6 +48,7 @@ Alternatively, you could set up manually by following the steps [here](#setup-ma * Check run * Check suite * Issue comment + * Commit comment * Pull request * Push diff --git a/pkg/cmd/tknpac/bootstrap/github.go b/pkg/cmd/tknpac/bootstrap/github.go index cef2555a9..c5d943036 100644 --- a/pkg/cmd/tknpac/bootstrap/github.go +++ b/pkg/cmd/tknpac/bootstrap/github.go @@ -21,6 +21,7 @@ func generateManifest(opts *bootstrapOpts) ([]byte, error) { "check_run", "check_suite", "issue_comment", + "commit_comment", "pull_request", "push", }, diff --git a/pkg/pipelineascode/cancel_pipelinerun_test.go b/pkg/pipelineascode/cancel_pipelinerun_test.go index 75d649305..01408088a 100644 --- a/pkg/pipelineascode/cancel_pipelinerun_test.go +++ b/pkg/pipelineascode/cancel_pipelinerun_test.go @@ -32,6 +32,10 @@ var ( URL: "https://github.com/fooorg/foo", }, } + fooRepoLabelsForPush = map[string]string{ + keys.URLRepository: formatting.CleanValueKubernetes("foo"), + keys.SHA: formatting.CleanValueKubernetes("foosha"), + } fooRepoLabels = map[string]string{ keys.URLRepository: formatting.CleanValueKubernetes("foo"), keys.SHA: formatting.CleanValueKubernetes("foosha"), @@ -66,12 +70,6 @@ func TestCancelPipelinerun(t *testing.T) { pipelineRuns []*pipelinev1.PipelineRun cancelledPipelineRuns map[string]bool }{ - { - name: "not a pull request event", - event: &info.Event{ - TriggerTarget: "push", - }, - }, { name: "cancel running", event: &info.Event{ @@ -203,6 +201,76 @@ func TestCancelPipelinerun(t *testing.T) { repo: fooRepo, cancelledPipelineRuns: map[string]bool{}, }, + { + name: "cancel running for push event", + event: &info.Event{ + Repository: "foo", + SHA: "foosha", + TriggerTarget: "push", + State: info.State{ + CancelPipelineRuns: true, + }, + }, + pipelineRuns: []*pipelinev1.PipelineRun{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pr-foo", + Namespace: "foo", + Labels: fooRepoLabelsForPush, + }, + Spec: pipelinev1.PipelineRunSpec{}, + }, + }, + repo: fooRepo, + cancelledPipelineRuns: map[string]bool{ + "pr-foo": true, + }, + }, + { + name: "cancel a specific run for push event", + event: &info.Event{ + Repository: "foo", + SHA: "foosha", + TriggerTarget: "push", + State: info.State{ + CancelPipelineRuns: true, + TargetCancelPipelineRun: "pr-foo-abc", + }, + }, + pipelineRuns: []*pipelinev1.PipelineRun{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pr-foo", + Namespace: "foo", + Labels: fooRepoLabelsForPush, + Annotations: fooRepoAnnotations, + }, + Spec: pipelinev1.PipelineRunSpec{}, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pr-foo-abc-123", + Namespace: "foo", + Labels: fooRepoLabelsPrFooAbc, + Annotations: fooRepoAnnotationsPrFooAbc, + }, + Spec: pipelinev1.PipelineRunSpec{}, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pr-foo-pqr", + Namespace: "foo", + Labels: fooRepoLabelsForPush, + Annotations: fooRepoAnnotations, + }, + Spec: pipelinev1.PipelineRunSpec{}, + }, + }, + repo: fooRepo, + cancelledPipelineRuns: map[string]bool{ + "pr-foo-abc-123": true, + }, + }, } for _, tt := range tests { diff --git a/pkg/pipelineascode/cancel_pipelineruns.go b/pkg/pipelineascode/cancel_pipelineruns.go index 1f420c3ac..c3f1dcdfc 100644 --- a/pkg/pipelineascode/cancel_pipelineruns.go +++ b/pkg/pipelineascode/cancel_pipelineruns.go @@ -24,18 +24,21 @@ var cancelMergePatch = map[string]interface{}{ } func (p *PacRun) cancelPipelineRuns(ctx context.Context, repo *v1alpha1.Repository) error { - if p.event.TriggerTarget != "pull_request" { - msg := fmt.Sprintf("not a pullRequest event, event: %v", p.event.TriggerTarget) - p.eventEmitter.EmitMessage(repo, zap.WarnLevel, "RepositoryEvent", msg) - return nil - } + labelSelector := getLabelSelector(map[string]string{ + keys.URLRepository: formatting.CleanValueKubernetes(p.event.Repository), + keys.SHA: formatting.CleanValueKubernetes(p.event.SHA), + keys.PullRequest: strconv.Itoa(p.event.PullRequestNumber), + }) - prs, err := p.run.Clients.Tekton.TektonV1().PipelineRuns(repo.Namespace).List(ctx, metav1.ListOptions{ - LabelSelector: getLabelSelector(map[string]string{ + if p.event.TriggerTarget == "push" { + labelSelector = getLabelSelector(map[string]string{ keys.URLRepository: formatting.CleanValueKubernetes(p.event.Repository), keys.SHA: formatting.CleanValueKubernetes(p.event.SHA), - keys.PullRequest: strconv.Itoa(p.event.PullRequestNumber), - }), + }) + } + + prs, err := p.run.Clients.Tekton.TektonV1().PipelineRuns(repo.Namespace).List(ctx, metav1.ListOptions{ + LabelSelector: labelSelector, }) if err != nil { return fmt.Errorf("failed to list pipelineRuns : %w", err) diff --git a/pkg/provider/github/detect.go b/pkg/provider/github/detect.go index ffd431241..926840241 100644 --- a/pkg/provider/github/detect.go +++ b/pkg/provider/github/detect.go @@ -88,6 +88,19 @@ func detectTriggerTypeFromPayload(ghEventType string, eventInt any) (info.Trigge return info.TriggerTypeCheckRunRerequested, "" } return "", fmt.Sprintf("check_run: unsupported action \"%s\"", event.GetAction()) + case *github.CommitCommentEvent: + if event.GetAction() == "created" { + if provider.IsTestRetestComment(event.GetComment().GetBody()) { + return info.TriggerTypeRetest, "" + } + if provider.IsOkToTestComment(event.GetComment().GetBody()) { + return info.TriggerTypeOkToTest, "" + } + if provider.IsCancelComment(event.GetComment().GetBody()) { + return info.TriggerTypeCancel, "" + } + } + return "", fmt.Sprintf("commit_comment: unsupported action \"%s\"", event.GetAction()) } return "", fmt.Sprintf("github: event \"%v\" is not supported", ghEventType) } diff --git a/pkg/provider/github/detect_test.go b/pkg/provider/github/detect_test.go index de78d266c..30bbb0660 100644 --- a/pkg/provider/github/detect_test.go +++ b/pkg/provider/github/detect_test.go @@ -59,12 +59,11 @@ func TestProvider_Detect(t *testing.T) { processReq: true, }, { - name: "unsupported Event", + name: "invalid commit_comment Event", event: github.CommitCommentEvent{ Action: github.String("something"), }, eventType: "commit_comment", - wantReason: "event \"commit_comment\" is not supported", isGH: true, processReq: false, }, @@ -228,7 +227,7 @@ func TestProvider_Detect(t *testing.T) { processReq: true, }, { - name: "issue comment Event with retest", + name: "issue comment Event with cancel comment ", event: github.IssueCommentEvent{ Action: github.String("created"), Issue: &github.Issue{ @@ -246,6 +245,45 @@ func TestProvider_Detect(t *testing.T) { isGH: true, processReq: true, }, + { + name: "commit comment event with cancel comment", + event: github.CommitCommentEvent{ + Action: github.String("created"), + Installation: &github.Installation{ + ID: github.Int64(123), + }, + Comment: &github.RepositoryComment{Body: github.String("/cancel")}, + }, + eventType: "commit_comment", + isGH: true, + processReq: true, + }, + { + name: "commit comment Event with retest", + event: github.CommitCommentEvent{ + Action: github.String("created"), + Installation: &github.Installation{ + ID: github.Int64(123), + }, + Comment: &github.RepositoryComment{Body: github.String("/retest")}, + }, + eventType: "commit_comment", + isGH: true, + processReq: true, + }, + { + name: "commit comment Event with test", + event: github.CommitCommentEvent{ + Action: github.String("created"), + Installation: &github.Installation{ + ID: github.Int64(123), + }, + Comment: &github.RepositoryComment{Body: github.String("/test")}, + }, + eventType: "commit_comment", + isGH: true, + processReq: true, + }, } for _, tt := range tests { diff --git a/pkg/provider/github/github.go b/pkg/provider/github/github.go index b02885006..a4c30ebe5 100644 --- a/pkg/provider/github/github.go +++ b/pkg/provider/github/github.go @@ -540,3 +540,33 @@ func uniqueRepositoryID(repoIDs []int64, id int64) []int64 { } return r } + +// listBranches list all branches in the repo and set the default branch for a matching branch commit SHA. +func (v *Provider) listBranches(ctx context.Context, runevent *info.Event) error { + if v.Client == nil { + return fmt.Errorf("no github client has been initialized, " + + "exiting... (hint: did you forget setting a secret on your repo?)") + } + + opt := github.ListOptions{PerPage: v.paginedNumber} + for { + branchInfo, resp, err := v.Client.Repositories.ListBranches(ctx, runevent.Organization, runevent.Repository, + &github.BranchListOptions{ + ListOptions: opt, + }) + if err != nil { + return err + } + for _, b := range branchInfo { + if b.Commit.GetSHA() == runevent.SHA { + runevent.DefaultBranch = b.GetName() + break + } + } + if resp.NextPage == 0 { + break + } + opt.Page = resp.NextPage + } + return nil +} diff --git a/pkg/provider/github/github_test.go b/pkg/provider/github/github_test.go index 6ec20a921..2d25c5ea7 100644 --- a/pkg/provider/github/github_test.go +++ b/pkg/provider/github/github_test.go @@ -998,3 +998,36 @@ func TestCreateToken(t *testing.T) { assert.Equal(t, strings.Contains(err.Error(), "could not refresh installation id 1234567's token"), true) } } + +func TestListBranches(t *testing.T) { + runEvent := &info.Event{ + Organization: "pushrequestowner", + Repository: "pushrequestrepository", + SHA: "sha1", + InstallationID: int64(1234567), + } + fakeclient, mux, _, teardown := ghtesthelper.SetupGH() + defer teardown() + + mux.HandleFunc(fmt.Sprintf("/repos/%s/%s/branches", + runEvent.Organization, runEvent.Repository), func(rw http.ResponseWriter, r *http.Request) { + _, err := fmt.Fprintf(rw, `[{ + "name": "test1", + "commit": { + "sha": "sha1" + } + }, { + "name": "test2", + "commit": { + "sha": "sha2" + } + }]`) + assert.NilError(t, err) + }) + + ctx, _ := rtesting.SetupFakeContext(t) + provider := &Provider{Client: fakeclient} + err := provider.listBranches(ctx, runEvent) + assert.NilError(t, err) + assert.Equal(t, runEvent.DefaultBranch, "test1") +} diff --git a/pkg/provider/github/parse_payload.go b/pkg/provider/github/parse_payload.go index 8bd2b8ab1..b59647ae6 100644 --- a/pkg/provider/github/parse_payload.go +++ b/pkg/provider/github/parse_payload.go @@ -229,6 +229,11 @@ func (v *Provider) processEvent(ctx context.Context, event *info.Event, eventInt if err != nil { return nil, err } + case *github.CommitCommentEvent: + if v.Client == nil { + return nil, fmt.Errorf("gitops style comments operation is only supported with github apps integration") + } + return v.handleCommitCommentEvent(ctx, gitEvent) case *github.PushEvent: processedEvent.Organization = gitEvent.GetRepo().GetOwner().GetLogin() processedEvent.Repository = gitEvent.GetRepo().GetName() @@ -370,3 +375,37 @@ func (v *Provider) handleIssueCommentEvent(ctx context.Context, event *github.Is v.Logger.Infof("issue_comment: pipelinerun %s on %s/%s#%d has been requested", action, runevent.Organization, runevent.Repository, runevent.PullRequestNumber) return v.getPullRequest(ctx, runevent) } + +func (v *Provider) handleCommitCommentEvent(ctx context.Context, event *github.CommitCommentEvent) (*info.Event, error) { + action := "recheck" + runevent := info.NewEvent() + runevent.Organization = event.GetRepo().GetOwner().GetLogin() + runevent.Repository = event.GetRepo().GetName() + runevent.Sender = event.GetSender().GetLogin() + runevent.URL = event.GetRepo().GetHTMLURL() + runevent.SHA = event.GetComment().GetCommitID() + runevent.HeadURL = runevent.URL + runevent.BaseURL = runevent.HeadURL + runevent.EventType = "push" + runevent.TriggerTarget = "push" + + if err := v.listBranches(ctx, runevent); err != nil { + return runevent, err + } + + // value for runevent.DefaultBranch set by listBranches function + runevent.HeadBranch = runevent.DefaultBranch + runevent.BaseBranch = runevent.DefaultBranch + + // if it is a /test or /retest comment with pipelinerun name figure out the pipelinerun name + if provider.IsTestRetestComment(event.GetComment().GetBody()) { + runevent.TargetTestPipelineRun = provider.GetPipelineRunFromTestComment(event.GetComment().GetBody()) + } + if provider.IsCancelComment(event.GetComment().GetBody()) { + action = "cancellation" + runevent.CancelPipelineRuns = true + runevent.TargetCancelPipelineRun = provider.GetPipelineRunFromCancelComment(event.GetComment().GetBody()) + } + v.Logger.Infof("commit_comment: pipelinerun %s on %s/%s#%s has been requested", action, runevent.Organization, runevent.Repository, runevent.SHA) + return runevent, nil +} diff --git a/pkg/provider/github/parse_payload_test.go b/pkg/provider/github/parse_payload_test.go index f69cd8131..40c25777e 100644 --- a/pkg/provider/github/parse_payload_test.go +++ b/pkg/provider/github/parse_payload_test.go @@ -317,6 +317,63 @@ func TestParsePayLoad(t *testing.T) { shaRet: "samplePRsha", targetCancelPipelinerun: "dummy", }, + { + name: "bad/commit comment retest only with github apps", + wantErrString: "only supported with github apps", + eventType: "commit_comment", + triggerTarget: "push", + payloadEventStruct: github.CommitCommentEvent{Action: github.String("created")}, + }, + { + name: "good/commit comment for retest", + eventType: "commit_comment", + triggerTarget: "push", + githubClient: true, + payloadEventStruct: github.CommitCommentEvent{ + Repo: sampleRepo, + Comment: &github.RepositoryComment{ + CommitID: github.String("samplePRsha"), + HTMLURL: github.String("/777"), + Body: github.String("/retest dummy"), + }, + }, + muxReplies: map[string]interface{}{"/repos/owner/reponame/pulls/777": samplePR}, + shaRet: "samplePRsha", + targetPipelinerun: "dummy", + }, + { + name: "good/commit comment for cancel all", + eventType: "commit_comment", + triggerTarget: "push", + githubClient: true, + payloadEventStruct: github.CommitCommentEvent{ + Repo: sampleRepo, + Comment: &github.RepositoryComment{ + CommitID: github.String("samplePRsha"), + HTMLURL: github.String("/999"), + Body: github.String("/cancel"), + }, + }, + muxReplies: map[string]interface{}{"/repos/owner/reponame/pulls/999": samplePR}, + shaRet: "samplePRsha", + }, + { + name: "good/commit comment for cancel a pr", + eventType: "commit_comment", + triggerTarget: "push", + githubClient: true, + payloadEventStruct: github.CommitCommentEvent{ + Repo: sampleRepo, + Comment: &github.RepositoryComment{ + CommitID: github.String("samplePRsha"), + HTMLURL: github.String("/888"), + Body: github.String("/cancel dummy"), + }, + }, + muxReplies: map[string]interface{}{"/repos/owner/reponame/pulls/888": samplePR}, + shaRet: "samplePRsha", + targetCancelPipelinerun: "dummy", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -333,6 +390,23 @@ func TestParsePayLoad(t *testing.T) { fmt.Fprint(rw, string(bjeez)) }) } + if tt.eventType == "commit_comment" { + mux.HandleFunc(fmt.Sprintf("/repos/%s/%s/branches", + "owner", "reponame"), func(rw http.ResponseWriter, r *http.Request) { + _, err := fmt.Fprintf(rw, `[{ + "name": "test1", + "commit": { + "sha": "samplePRsha" + } + }, { + "name": "test2", + "commit": { + "sha": "samplePRsha2" + } + }]`) + assert.NilError(t, err) + }) + } logger, _ := logger.GetLogger() gprovider := Provider{ Client: ghClient, @@ -361,6 +435,9 @@ func TestParsePayLoad(t *testing.T) { assert.NilError(t, err) assert.Assert(t, ret != nil) assert.Equal(t, tt.shaRet, ret.SHA) + if tt.eventType == "commit_comment" { + assert.Equal(t, "test1", ret.DefaultBranch) + } if tt.targetPipelinerun != "" { assert.Equal(t, tt.targetPipelinerun, ret.TargetTestPipelineRun) } diff --git a/test/github_push_retest_test.go b/test/github_push_retest_test.go new file mode 100644 index 000000000..9c0efade7 --- /dev/null +++ b/test/github_push_retest_test.go @@ -0,0 +1,95 @@ +//go:build e2e +// +build e2e + +package test + +import ( + "context" + "testing" + + "github.com/google/go-github/v53/github" + tgithub "github.com/openshift-pipelines/pipelines-as-code/test/pkg/github" + twait "github.com/openshift-pipelines/pipelines-as-code/test/pkg/wait" + tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "gotest.tools/v3/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestGithubPushRequestGitOpsComments(t *testing.T) { + ctx := context.TODO() + runcnx, ghcnx, opts, targetNS, targetRefName, prNumber, sha := tgithub.RunPushRequest(ctx, t, + "Github Push Request", []string{"testdata/pipelinerun-on-push.yaml", "testdata/pipelinerun.yaml"}, false) + defer tgithub.TearDown(ctx, t, runcnx, ghcnx, prNumber, targetRefName, targetNS, opts) + + pruns, err := runcnx.Clients.Tekton.TektonV1().PipelineRuns(targetNS).List(ctx, metav1.ListOptions{}) + assert.NilError(t, err) + assert.Assert(t, len(pruns.Items) == 2) + + tests := []struct { + name, comment string + prNum int + }{ + { + name: "Retest", + comment: "/retest", + prNum: 4, + }, + { + name: "Test PipelineRun", + comment: "/test pipelinerun-on-push", + prNum: 5, + }, + { + name: "Test and Cancel PipelineRun", + comment: "/cancel pipelinerun-on-push", + prNum: 6, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.comment == "/cancel pipelinerun-on-push" { + runcnx.Clients.Log.Info("/test pipelinerun-on-push on Push Request before canceling") + _, _, err = ghcnx.Client.Repositories.CreateComment(ctx, + opts.Organization, + opts.Repo, sha, + &github.RepositoryComment{Body: github.String("/test pipelinerun-on-push")}) + assert.NilError(t, err) + } + runcnx.Clients.Log.Infof("%s on Push Request", tt.comment) + _, _, err = ghcnx.Client.Repositories.CreateComment(ctx, + opts.Organization, + opts.Repo, sha, + &github.RepositoryComment{Body: github.String(tt.comment)}) + assert.NilError(t, err) + + runcnx.Clients.Log.Info("Waiting for Repository to be updated") + waitOpts := twait.Opts{ + RepoName: targetNS, + Namespace: targetNS, + MinNumberStatus: 0, + PollTimeout: twait.DefaultTimeout, + TargetSHA: sha, + } + err = twait.UntilRepositoryUpdated(ctx, runcnx.Clients, waitOpts) + assert.NilError(t, err) + + runcnx.Clients.Log.Infof("Check if we have the repository set as succeeded") + repo, err := runcnx.Clients.PipelineAsCode.PipelinesascodeV1alpha1().Repositories(targetNS).Get(ctx, targetNS, metav1.GetOptions{}) + assert.NilError(t, err) + if tt.comment == "/cancel pipelinerun-on-push" { + for i := range repo.Status { + if repo.Status[i].Conditions[0].Reason == tektonv1.PipelineRunReasonCancelled.String() { + assert.Assert(t, repo.Status[i].Conditions[0].Status == corev1.ConditionFalse) + } + } + } else { + assert.Assert(t, repo.Status[len(repo.Status)-1].Conditions[0].Status == corev1.ConditionTrue) + } + + pruns, err = runcnx.Clients.Tekton.TektonV1().PipelineRuns(targetNS).List(ctx, metav1.ListOptions{}) + assert.NilError(t, err) + assert.Assert(t, len(pruns.Items) == tt.prNum) + }) + } +} diff --git a/test/github_push_test.go b/test/github_push_test.go index e4d17aedf..003127002 100644 --- a/test/github_push_test.go +++ b/test/github_push_test.go @@ -5,81 +5,24 @@ package test import ( "context" - "fmt" - "net/http" "os" "testing" tgithub "github.com/openshift-pipelines/pipelines-as-code/test/pkg/github" - "github.com/openshift-pipelines/pipelines-as-code/test/pkg/payload" - twait "github.com/openshift-pipelines/pipelines-as-code/test/pkg/wait" - "github.com/tektoncd/pipeline/pkg/names" - "gotest.tools/v3/assert" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func TestGithubPush(t *testing.T) { if os.Getenv("NIGHTLY_E2E_TEST") != "true" { t.Skip("Skipping test since only enabled for nightly") } + ctx := context.TODO() for _, onWebhook := range []bool{false, true} { - targetNS := names.SimpleNameGenerator.RestrictLengthWithRandomSuffix("pac-e2e-push") - targetBranch := targetNS - targetEvent := "push" if onWebhook && os.Getenv("TEST_GITHUB_REPO_OWNER_WEBHOOK") == "" { t.Skip("TEST_GITHUB_REPO_OWNER_WEBHOOK is not set") continue } - - ctx := context.Background() - runcnx, opts, gprovider, err := tgithub.Setup(ctx, onWebhook) - assert.NilError(t, err) - - if onWebhook { - runcnx.Clients.Log.Info("Testing with Direct Webhook integration") - } else { - runcnx.Clients.Log.Info("Testing with Github APPS integration") - } - repoinfo, resp, err := gprovider.Client.Repositories.Get(ctx, opts.Organization, opts.Repo) - assert.NilError(t, err) - if resp != nil && resp.StatusCode == http.StatusNotFound { - t.Errorf("Repository %s not found in %s", opts.Organization, opts.Repo) - } - err = tgithub.CreateCRD(ctx, t, repoinfo, runcnx, opts, targetNS) - assert.NilError(t, err) - - entries, err := payload.GetEntries( - map[string]string{".tekton/pipelinerun-on-push.yaml": "testdata/pipelinerun-on-push.yaml"}, - targetNS, targetBranch, targetEvent, map[string]string{}) - assert.NilError(t, err) - - title := "TestPush " - if onWebhook { - title += "OnWebhook" - } - title += "- " + targetBranch - - targetRefName := fmt.Sprintf("refs/heads/%s", targetBranch) - sha, err := tgithub.PushFilesToRef(ctx, gprovider.Client, title, repoinfo.GetDefaultBranch(), targetRefName, opts.Organization, opts.Repo, entries) - runcnx.Clients.Log.Infof("Commit %s has been created and pushed to %s", sha, targetRefName) - assert.NilError(t, err) - defer tgithub.TearDown(ctx, t, runcnx, gprovider, -1, targetRefName, targetNS, opts) - - runcnx.Clients.Log.Infof("Waiting for Repository to be updated") - waitOpts := twait.Opts{ - RepoName: targetNS, - Namespace: targetNS, - MinNumberStatus: 1, - PollTimeout: twait.DefaultTimeout, - TargetSHA: sha, - } - err = twait.UntilRepositoryUpdated(ctx, runcnx.Clients, waitOpts) - assert.NilError(t, err) - - runcnx.Clients.Log.Infof("Check if we have the repository set as succeeded") - repo, err := runcnx.Clients.PipelineAsCode.PipelinesascodeV1alpha1().Repositories(targetNS).Get(ctx, targetNS, metav1.GetOptions{}) - assert.NilError(t, err) - assert.Assert(t, repo.Status[len(repo.Status)-1].Conditions[0].Status == corev1.ConditionTrue) + runcnx, ghcnx, opts, targetNS, targetRefName, prNumber, _ := tgithub.RunPushRequest(ctx, t, + "Github Push Request", []string{"testdata/pipelinerun-on-push.yaml"}, onWebhook) + defer tgithub.TearDown(ctx, t, runcnx, ghcnx, prNumber, targetRefName, targetNS, opts) } } diff --git a/test/pkg/github/pr.go b/test/pkg/github/pr.go index 4c8bb55b5..b0cd5ee7d 100644 --- a/test/pkg/github/pr.go +++ b/test/pkg/github/pr.go @@ -147,3 +147,51 @@ func RunPullRequest(ctx context.Context, t *testing.T, label string, yamlFiles [ wait.Succeeded(ctx, t, runcnx, opts, sopt) return runcnx, ghcnx, opts, targetNS, targetRefName, number, sha } + +func RunPushRequest(ctx context.Context, t *testing.T, label string, yamlFiles []string, onWebhook bool) (*params.Run, *ghprovider.Provider, options.E2E, string, string, int, string) { + targetNS := names.SimpleNameGenerator.RestrictLengthWithRandomSuffix("pac-e2e-push") + targetBranch := targetNS + targetEvent := "push" + runcnx, opts, ghcnx, err := Setup(ctx, onWebhook) + assert.NilError(t, err) + + var logmsg string + if onWebhook { + logmsg = fmt.Sprintf("Testing %s with Direct Webhook integration on %s", label, targetNS) + runcnx.Clients.Log.Info(logmsg) + } else { + logmsg = fmt.Sprintf("Testing %s with Github APPS integration on %s", label, targetNS) + runcnx.Clients.Log.Info(logmsg) + } + repoinfo, resp, err := ghcnx.Client.Repositories.Get(ctx, opts.Organization, opts.Repo) + assert.NilError(t, err) + if resp != nil && resp.StatusCode == http.StatusNotFound { + t.Errorf("Repository %s not found in %s", opts.Organization, opts.Repo) + } + err = CreateCRD(ctx, t, repoinfo, runcnx, opts, targetNS) + assert.NilError(t, err) + + yamlEntries := map[string]string{} + for _, v := range yamlFiles { + yamlEntries[filepath.Join(".tekton", filepath.Base(v))] = v + } + + entries, err := payload.GetEntries(yamlEntries, + targetNS, targetBranch, targetEvent, map[string]string{}) + assert.NilError(t, err) + + targetRefName := fmt.Sprintf("refs/heads/%s", targetBranch) + sha, err := PushFilesToRef(ctx, ghcnx.Client, logmsg, repoinfo.GetDefaultBranch(), targetRefName, opts.Organization, opts.Repo, entries) + runcnx.Clients.Log.Infof("Commit %s has been created and pushed to %s", sha, targetRefName) + assert.NilError(t, err) + + sopt := wait.SuccessOpt{ + Title: logmsg, + OnEvent: options.PushEvent, + TargetNS: targetNS, + NumberofPRMatch: len(yamlFiles), + SHA: sha, + } + wait.Succeeded(ctx, t, runcnx, opts, sopt) + return runcnx, ghcnx, opts, targetNS, targetRefName, -1, sha +} diff --git a/test/testdata/pipelinerun-on-push.yaml b/test/testdata/pipelinerun-on-push.yaml index 1e1d11778..a2d8bd977 100644 --- a/test/testdata/pipelinerun-on-push.yaml +++ b/test/testdata/pipelinerun-on-push.yaml @@ -2,7 +2,7 @@ apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: - name: "\\ .PipelineName //" + name: "pipelinerun-on-push" annotations: pipelinesascode.tekton.dev/target-namespace: "\\ .TargetNamespace //" pipelinesascode.tekton.dev/on-target-branch: "[\\ .TargetBranch //]"