Skip to content

Commit 536208a

Browse files
committed
test(e2e): add incoming webhook test with default_branch provenance
Add an e2e test that verifies incoming webhooks work correctly when pipelinerun_provenance is set to 'default_branch' on the Repository CR. The test creates a Repository CR with default_branch provenance, pushes .tekton/ files only to the default branch, and triggers an incoming webhook targeting a different branch. This validates that PAC correctly resolves the DefaultBranch for incoming events and fetches PipelineRun definitions from the default branch. Related: #2646
1 parent 333fb64 commit 536208a

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed

test/github_incoming_test.go

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/openshift-pipelines/pipelines-as-code/pkg/params/triggertype"
2121
tgithub "github.com/openshift-pipelines/pipelines-as-code/test/pkg/github"
2222
"github.com/openshift-pipelines/pipelines-as-code/test/pkg/payload"
23+
repository "github.com/openshift-pipelines/pipelines-as-code/test/pkg/repository"
2324
"github.com/openshift-pipelines/pipelines-as-code/test/pkg/secret"
2425
"github.com/openshift-pipelines/pipelines-as-code/test/pkg/wait"
2526
"github.com/tektoncd/pipeline/pkg/names"
@@ -341,6 +342,153 @@ func verifyIncomingWebhook(t *testing.T, randomedString, pipelinerunName string,
341342
}
342343
}
343344

345+
// TestGithubGHEAppIncomingDefaultBranchProvenance tests that incoming webhooks
346+
// work correctly with pipelinerun_provenance set to "default_branch".
347+
// This verifies the fix for https://github.com/tektoncd/pipelines-as-code/issues/2646
348+
// where DefaultBranch was not populated for incoming events.
349+
func TestGithubGHEAppIncomingDefaultBranchProvenance(t *testing.T) {
350+
ctx := context.Background()
351+
onGHE := true
352+
ctx, runcnx, opts, ghprovider, err := tgithub.Setup(ctx, onGHE, false)
353+
assert.NilError(t, err)
354+
355+
randomedString := names.SimpleNameGenerator.RestrictLengthWithRandomSuffix("pac-e2e-ns")
356+
targetBranch := names.SimpleNameGenerator.RestrictLengthWithRandomSuffix("incoming-branch")
357+
358+
runcnx.Clients.Log.Infof("Testing incoming webhook with default_branch provenance on %s", randomedString)
359+
360+
repoinfo, resp, err := ghprovider.Client().Repositories.Get(ctx, opts.Organization, opts.Repo)
361+
assert.NilError(t, err)
362+
if resp != nil && resp.StatusCode == http.StatusNotFound {
363+
t.Errorf("Repository %s not found in %s", opts.Organization, opts.Repo)
364+
}
365+
366+
incoming := &[]v1alpha1.Incoming{
367+
{
368+
Type: "webhook-url",
369+
Secret: v1alpha1.Secret{
370+
Name: incomingSecretName,
371+
Key: "incoming",
372+
},
373+
Targets: []string{targetBranch},
374+
Params: []string{
375+
"the_best_superhero_is",
376+
},
377+
},
378+
}
379+
380+
// Create Repository CR with pipelinerun_provenance: default_branch
381+
repo := &v1alpha1.Repository{
382+
ObjectMeta: metav1.ObjectMeta{
383+
Name: randomedString,
384+
},
385+
Spec: v1alpha1.RepositorySpec{
386+
URL: repoinfo.GetHTMLURL(),
387+
Incomings: incoming,
388+
Settings: &v1alpha1.Settings{
389+
PipelineRunProvenance: "default_branch",
390+
},
391+
},
392+
}
393+
394+
err = repository.CreateNS(ctx, randomedString, runcnx)
395+
assert.NilError(t, err)
396+
err = repository.CreateRepo(ctx, randomedString, runcnx, repo)
397+
assert.NilError(t, err)
398+
399+
err = secret.Create(ctx, runcnx, map[string]string{"incoming": incomingSecreteValue}, randomedString, incomingSecretName)
400+
assert.NilError(t, err)
401+
402+
// Push .tekton/ files to the DEFAULT branch (not the incoming target branch)
403+
entries, err := payload.GetEntries(map[string]string{
404+
".tekton/pipelinerun-incoming.yaml": "testdata/pipelinerun-incoming.yaml",
405+
}, randomedString, targetBranch, triggertype.Incoming.String(), map[string]string{})
406+
assert.NilError(t, err)
407+
408+
defaultBranch := repoinfo.GetDefaultBranch()
409+
title := "TestGithubAppIncomingDefaultBranchProvenance - " + randomedString
410+
sha, vref, err := tgithub.PushFilesToRef(ctx, ghprovider.Client(), title,
411+
defaultBranch,
412+
fmt.Sprintf("refs/heads/%s", defaultBranch),
413+
opts.Organization,
414+
opts.Repo,
415+
entries)
416+
assert.NilError(t, err)
417+
runcnx.Clients.Log.Infof("Commit %s has been created and pushed to default branch %s", sha, vref.GetURL())
418+
419+
// Also create the target branch (the incoming webhook targets this branch)
420+
_, _, err = tgithub.PushFilesToRef(ctx, ghprovider.Client(),
421+
"create target branch",
422+
defaultBranch,
423+
fmt.Sprintf("refs/heads/%s", targetBranch),
424+
opts.Organization,
425+
opts.Repo,
426+
map[string]string{"README.md": "# target branch"})
427+
assert.NilError(t, err)
428+
429+
// Trigger incoming webhook targeting the non-default branch
430+
incomingURL := fmt.Sprintf("%s/incoming", opts.ControllerURL)
431+
jsonBody := map[string]interface{}{
432+
"repository": randomedString,
433+
"branch": targetBranch,
434+
"pipelinerun": "pipelinerun-incoming",
435+
"secret": incomingSecreteValue,
436+
"params": map[string]string{
437+
"the_best_superhero_is": "Superman",
438+
},
439+
}
440+
jsonData, err := json.Marshal(jsonBody)
441+
assert.NilError(t, err)
442+
req, err := http.NewRequestWithContext(ctx, http.MethodPost, incomingURL, strings.NewReader(string(jsonData)))
443+
assert.NilError(t, err)
444+
req.Header.Add("Content-Type", "application/json")
445+
if onGHE {
446+
urlParse, _ := url.Parse(*ghprovider.APIURL)
447+
req.Header.Add("X-GitHub-Enterprise-Host", urlParse.Host)
448+
}
449+
450+
client := &http.Client{}
451+
httpResp, err := client.Do(req)
452+
assert.NilError(t, err)
453+
defer httpResp.Body.Close()
454+
assert.Assert(t, httpResp.StatusCode >= 200 && httpResp.StatusCode < 300,
455+
"HTTP status code mismatch: expected=2xx, actual=%d", httpResp.StatusCode)
456+
457+
runcnx.Clients.Log.Infof("Incoming webhook triggered on URL: %s for branch: %s", incomingURL, targetBranch)
458+
459+
g := tgithub.PRTest{
460+
Cnx: runcnx,
461+
Options: opts,
462+
Provider: ghprovider,
463+
TargetNamespace: randomedString,
464+
TargetRefName: fmt.Sprintf("refs/heads/%s", targetBranch),
465+
PRNumber: -1,
466+
SHA: sha,
467+
Logger: runcnx.Clients.Log,
468+
GHE: onGHE,
469+
}
470+
defer g.TearDown(ctx, t)
471+
472+
sopt := wait.SuccessOpt{
473+
Title: title,
474+
OnEvent: triggertype.Incoming.String(),
475+
TargetNS: randomedString,
476+
NumberofPRMatch: 1,
477+
SHA: "",
478+
}
479+
wait.Succeeded(ctx, t, runcnx, opts, sopt)
480+
481+
// Verify the PipelineRun was created
482+
prs, err := runcnx.Clients.Tekton.TektonV1().PipelineRuns(randomedString).List(ctx, metav1.ListOptions{})
483+
assert.NilError(t, err)
484+
assert.Assert(t, len(prs.Items) == 1, "Expected 1 PipelineRun, got %d", len(prs.Items))
485+
486+
err = wait.RegexpMatchingInPodLog(context.Background(), runcnx, randomedString,
487+
"pipelinesascode.tekton.dev/event-type=incoming", "step-task",
488+
*regexp.MustCompile(".*It's a Bird... It's a Plane... It's Superman"), "", 2, nil)
489+
assert.NilError(t, err, "Error while checking the logs of the pods")
490+
}
491+
344492
// Local Variables:
345493
// compile-command: "go test -tags=e2e -v -run TestGithubAppIncoming ."
346494
// End:

0 commit comments

Comments
 (0)