Skip to content

Commit 58b6686

Browse files
authored
Merge branch 'main' into graphql
2 parents ba40c95 + 3fa3cb9 commit 58b6686

31 files changed

+342
-348
lines changed

.github/workflows/e2e.yaml

Lines changed: 3 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ jobs:
4343
matrix:
4444
provider:
4545
[
46-
github_1,
47-
github_2,
48-
github_second_controller,
46+
github_public,
47+
github_ghe,
4948
gitlab_bitbucket,
5049
gitea_1,
5150
gitea_2,
@@ -87,7 +86,6 @@ jobs:
8786
TEST_GITHUB_SECOND_REPO_OWNER_GITHUBAPP: pipelines-as-code/e2e
8887
TEST_GITHUB_SECOND_TOKEN: ${{ secrets.TEST_GITHUB_SECOND_TOKEN }}
8988
TEST_GITHUB_TOKEN: ${{ secrets.GH_APPS_TOKEN }}
90-
TEST_GITLAB_API_URL: https://gitlab.com
9189
TEST_GITLAB_PROJECT_ID: ${{ vars.TEST_GITLAB_PROJECT_ID }}
9290
TEST_GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
9391
steps:
@@ -440,136 +438,10 @@ jobs:
440438
name: logs-e2e-tests-${{ matrix.provider }}
441439
path: /tmp/logs
442440

443-
e2e-flaky-tests:
444-
name: e2e flaky tests
445-
runs-on: ubuntu-latest
446-
needs: e2e-tests
447-
if: always() && !cancelled()
448-
concurrency:
449-
group: ${{ github.workflow }}-flaky-${{ github.event.pull_request.number || github.ref_name }}
450-
cancel-in-progress: true
451-
452-
env:
453-
CONTROLLER_DOMAIN_URL: controller.paac-127-0-0-1.nip.io
454-
KOCACHE: /tmp/ko-cache
455-
KO_DOCKER_REPO: localhost:5000
456-
KUBECONFIG: /home/runner/.kube/config.kind
457-
TEST_EL_URL: http://controller.paac-127-0-0-1.nip.io
458-
TEST_EL_WEBHOOK_SECRET: ${{ secrets.WEBHOOK_SECRET }}
459-
TEST_GITHUB_API_URL: api.github.com
460-
TEST_GITHUB_PRIVATE_TASK_NAME: task-remote
461-
TEST_GITHUB_PRIVATE_TASK_URL: https://github.com/openshift-pipelines/pipelines-as-code-e2e-tests-private/blob/main/remote_task.yaml
462-
TEST_GITHUB_REPO_INSTALLATION_ID: ${{ vars.INSTALLATION_ID }}
463-
TEST_GITHUB_REPO_OWNER_GITHUBAPP: openshift-pipelines/pipelines-as-code-e2e-tests
464-
TEST_GITHUB_SECOND_API_URL: ghe.pipelinesascode.com
465-
TEST_GITHUB_SECOND_EL_URL: http://ghe.paac-127-0-0-1.nip.io
466-
TEST_GITHUB_SECOND_REPO_INSTALLATION_ID: 1
467-
TEST_GITHUB_SECOND_REPO_OWNER_GITHUBAPP: pipelines-as-code/e2e
468-
TEST_GITHUB_SECOND_TOKEN: ${{ secrets.TEST_GITHUB_SECOND_TOKEN }}
469-
TEST_GITHUB_TOKEN: ${{ secrets.GH_APPS_TOKEN }}
470-
steps:
471-
- uses: actions/checkout@v6
472-
with:
473-
ref: ${{ inputs.target_ref || github.event.pull_request.head.sha || github.sha }}
474-
475-
- uses: actions/setup-go@v6
476-
with:
477-
go-version-file: "go.mod"
478-
479-
- name: Cache ko layer cache
480-
uses: actions/cache@v5
481-
with:
482-
path: /tmp/ko-cache
483-
key: ${{ runner.os }}-ko-${{ hashFiles('go.sum') }}
484-
restore-keys: |
485-
${{ runner.os }}-ko-
486-
487-
- uses: ko-build/setup-ko@v0.9
488-
489-
- name: Build binaries in parallel with cluster installation
490-
run: |
491-
nohup make allbinaries > /tmp/binary-build.log 2>&1 &
492-
echo $! > /tmp/binary-build.pid
493-
494-
- name: Install gosmee
495-
uses: jaxxstorm/action-install-gh-release@v2.1.0
496-
with:
497-
repo: chmouel/gosmee
498-
499-
- name: Install Snazy
500-
uses: jaxxstorm/action-install-gh-release@v2.1.0
501-
with:
502-
repo: chmouel/snazy
503-
504-
- name: Run gosmee for main controller
505-
run: |
506-
nohup gosmee client --saveDir /tmp/gosmee-replay ${{ secrets.PYSMEE_URL }} "http://${CONTROLLER_DOMAIN_URL}" > /tmp/gosmee-main.log 2>&1 &
507-
508-
- name: Start installing cluster
509-
run: |
510-
export PAC_DIR=${PWD}
511-
bash -x ./hack/dev/kind/install.sh
512-
513-
- name: Create PAC github-app-secret
514-
env:
515-
PAC_GITHUB_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }}
516-
PAC_GITHUB_APPLICATION_ID: ${{ vars.APPLICATION_ID }}
517-
PAC_WEBHOOK_SECRET: ${{ secrets.WEBHOOK_SECRET }}
518-
run: |
519-
./hack/gh-workflow-ci.sh create_pac_github_app_secret
520-
521-
- name: Create second Github APP Controller on GHE
522-
env:
523-
TEST_GITHUB_SECOND_SMEE_URL: ${{ secrets.TEST_GITHUB_SECOND_SMEE_URL }}
524-
TEST_GITHUB_SECOND_PRIVATE_KEY: ${{ secrets.TEST_GITHUB_SECOND_PRIVATE_KEY }}
525-
TEST_GITHUB_SECOND_WEBHOOK_SECRET: ${{ secrets.TEST_GITHUB_SECOND_WEBHOOK_SECRET }}
526-
TEST_GITHUB_SECOND_APPLICATION_ID: ${{ vars.TEST_GITHUB_SECOND_APPLICATION_ID }}
527-
run: |
528-
./hack/gh-workflow-ci.sh create_second_github_app_controller_on_ghe
529-
530-
- name: Enable debug logging for e2e
531-
run: |
532-
set -euo pipefail
533-
kubectl -n pipelines-as-code patch configmap pac-config-logging --type merge -p '{"data":{"loglevel.pipelinesascode":"debug","loglevel.pac-watcher":"debug","loglevel.pipelines-as-code-webhook":"debug"}}'
534-
kubectl -n pipelines-as-code rollout restart deployment/pipelines-as-code-controller deployment/pipelines-as-code-webhook deployment/pipelines-as-code-watcher
535-
for name in controller webhook watcher; do
536-
echo "=== Waiting for $name to be ready ==="
537-
kubectl -n pipelines-as-code rollout status deployment/pipelines-as-code-$name --timeout=120s
538-
done
539-
540-
- name: Run Flaky E2E Tests
541-
env:
542-
TEST_PROVIDER: flaky
543-
TEST_EL_WEBHOOK_SECRET: ${{ secrets.WEBHOOK_SECRET }}
544-
TEST_GITHUB_REPO_INSTALLATION_ID: ${{ vars.INSTALLATION_ID }}
545-
TEST_GITHUB_TOKEN: ${{ secrets.GH_APPS_TOKEN }}
546-
TEST_GITHUB_SECOND_TOKEN: ${{ secrets.TEST_GITHUB_SECOND_TOKEN }}
547-
run: |
548-
./hack/gh-workflow-ci.sh run_e2e_tests
549-
550-
- name: Collect logs
551-
if: ${{ always() }}
552-
env:
553-
TEST_GITHUB_SECOND_SMEE_URL: ${{ secrets.TEST_GITHUB_SECOND_SMEE_URL }}
554-
run: |
555-
./hack/gh-workflow-ci.sh collect_logs
556-
557-
- name: Show controllers/watcher errors with Snazy
558-
if: ${{ always() }}
559-
run: |
560-
./hack/gh-workflow-ci.sh output_logs
561-
562-
- name: Upload artifacts
563-
if: ${{ always() }}
564-
uses: actions/upload-artifact@v6
565-
with:
566-
name: logs-e2e-tests-flaky
567-
path: /tmp/logs
568-
569441
notify-slack:
570442
name: Notify Slack on Failures
571443
runs-on: ubuntu-latest
572-
needs: [e2e-tests, e2e-flaky-tests]
444+
needs: [e2e-tests]
573445
if: ${{ always() && github.ref_name == 'main' && github.event_name == 'schedule' }}
574446
steps:
575447
- uses: actions/checkout@v6

config/300-repositories.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,9 +476,11 @@ spec:
476476
CommentStrategy defines how GitLab comments are handled for pipeline results.
477477
Options:
478478
- 'disable_all': Disables all comments on merge requests
479+
- 'update': Updates a single comment per PipelineRun on every trigger.
479480
enum:
480481
- ""
481482
- disable_all
483+
- update
482484
type: string
483485
type: object
484486
pipelinerun_provenance:

docs/content/docs/guide/cli.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ The CEL evaluator is only useful for admins, since the payload and headers as se
421421
`tkn pac cel` — Evaluate CEL (Common Expression Language) expressions interactively with webhook payloads.
422422

423423
This command allows you to test and debug CEL expressions as they would be evaluated by Pipelines-as-Code, using real webhook payloads and headers. It supports interactive and non-interactive modes, provider auto-detection, and persistent history.
424+
Note that the CEL evaluator may not always produce the same output as when the expression is evaluated in an actual PipelineRun.
424425

425426
To be able to have the CEL evaluator working, you need to have the payload and the headers available in a file. The best way to do this is to go to the webhook configuration on your git provider and copy the payload and headers to different files.
426427

hack/gh-workflow-ci.sh

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
set -exufo pipefail
55

66
export PAC_API_INSTRUMENTATION_DIR=/tmp/api-instrumentation
7+
export TEST_GITLAB_API_URL=https://gitlab.pipelinesascode.com
78

89
create_pac_github_app_secret() {
910
# Read from environment variables instead of arguments
@@ -85,8 +86,8 @@ get_tests() {
8586
fi
8687

8788
local -a github_tests=()
88-
if [[ "${target}" == *"github"* ]] && [[ "${target}" != "github_second_controller" ]]; then
89-
mapfile -t github_tests < <(echo "${all_tests}" | grep -iP '^TestGithub' 2>/dev/null | grep -ivP 'Concurrency|GithubSecond|Flaky' 2>/dev/null | sort 2>/dev/null)
89+
if [[ "${target}" == *"github"* ]] && [[ "${target}" != "github_ghe" ]] && [[ "${target}" != "github_second_controller" ]]; then
90+
mapfile -t github_tests < <(echo "${all_tests}" | grep -iP '^TestGithub' 2>/dev/null | grep -ivP 'Concurrency|GithubGHE' 2>/dev/null | sort 2>/dev/null)
9091
fi
9192

9293
# Calculate chunk sizes for splitting gitea tests into 3 parts
@@ -96,32 +97,49 @@ get_tests() {
9697
remainder=$((${#gitea_tests[@]} % 3))
9798
fi
9899

99-
# Calculate chunk sizes for splitting github tests into 2 parts
100+
# TODO: revert once the new workflow matrix lands on main.
101+
# Backward compat: github_1/github_2 chunking for pull_request_target
102+
# which runs the workflow YAML from main (old target names).
100103
local github_chunk_size github_remainder
101104
if [[ ${#github_tests[@]} -gt 0 ]]; then
102-
github_chunk_size=$((${#github_tests[@]} / 2))
103-
github_remainder=$((${#github_tests[@]} % 2))
105+
github_chunk_size=$(( ${#github_tests[@]} / 2 ))
106+
github_remainder=$(( ${#github_tests[@]} % 2 ))
104107
fi
105108

106109
case "${target}" in
107110
flaky)
108-
printf '%s\n' "${all_tests}" | grep -iP 'Flaky'
111+
# no-op: flaky tests have been absorbed into their natural categories.
112+
# Kept for backward compat since pull_request_target uses main's YAML
113+
# which still references 'flaky'.
109114
;;
115+
110116
concurrency)
111117
printf '%s\n' "${all_tests}" | grep -iP 'Concurrency|Others'
112118
;;
119+
github_public)
120+
if [[ ${#github_tests[@]} -gt 0 ]]; then
121+
printf '%s\n' "${github_tests[@]}"
122+
fi
123+
;;
124+
# TODO: revert - remove github_1, github_2, github_second_controller aliases
125+
# once the new workflow matrix lands on main. These exist because
126+
# pull_request_target runs the workflow YAML from main which still sends old
127+
# target names.
113128
github_1)
114129
if [[ ${#github_tests[@]} -gt 0 ]]; then
115-
printf '%s\n' "${github_tests[@]:0:${github_chunk_size}}"
130+
printf '%s\n' "${github_tests[@]:0:$((github_chunk_size + github_remainder))}"
116131
fi
117132
;;
118133
github_2)
119134
if [[ ${#github_tests[@]} -gt 0 ]]; then
120-
printf '%s\n' "${github_tests[@]:${github_chunk_size}:$((github_chunk_size + github_remainder))}"
135+
printf '%s\n' "${github_tests[@]:$((github_chunk_size + github_remainder))}"
121136
fi
122137
;;
123138
github_second_controller)
124-
printf '%s\n' "${all_tests}" | grep -iP 'GithubSecond' | grep -ivP 'Concurrency|Flaky'
139+
printf '%s\n' "${all_tests}" | grep -iP 'GithubGHE' | grep -ivP 'Concurrency'
140+
;;
141+
github_ghe)
142+
printf '%s\n' "${all_tests}" | grep -iP 'GithubGHE' | grep -ivP 'Concurrency'
125143
;;
126144
gitlab_bitbucket)
127145
printf '%s\n' "${all_tests}" | grep -iP 'Gitlab|Bitbucket' | grep -ivP 'Concurrency'
@@ -144,7 +162,8 @@ get_tests() {
144162
;;
145163
*)
146164
echo "Invalid target: ${target}"
147-
echo "supported targets: github_1, github_2, github_second_controller, gitlab_bitbucket, gitea_1, gitea_2, gitea_3, concurrency, flaky"
165+
echo "supported targets: github_public, github_ghe, gitlab_bitbucket, gitea_1, gitea_2, gitea_3, concurrency, flaky"
166+
echo "backward compat aliases: github_1, github_2, github_second_controller"
148167
;;
149168
esac
150169
}
@@ -157,6 +176,11 @@ run_e2e_tests() {
157176
mapfile -t tests < <(get_tests "${target}")
158177
echo "About to run ${#tests[@]} tests: ${tests[*]}"
159178

179+
if [[ ${#tests[@]} -eq 0 || (-z "${tests[0]}" && ${#tests[@]} -eq 1) ]]; then
180+
echo "No tests to run for target '${target}', exiting successfully."
181+
return 0
182+
fi
183+
160184
mkdir -p /tmp/logs
161185

162186
# shellcheck disable=SC2001
@@ -284,7 +308,7 @@ output_logs)
284308
;;
285309
print_tests)
286310
set +x
287-
for target in github_1 github_2 github_second_controller gitlab_bitbucket gitea_1 gitea_2 gitea_3 concurrency flaky; do
311+
for target in github_public github_ghe gitlab_bitbucket gitea_1 gitea_2 gitea_3 concurrency flaky; do
288312
mapfile -t tests < <(get_tests "${target}")
289313
echo "Tests for target: ${target} Total: ${#tests[@]}"
290314
printf '%s\n' "${tests[@]}"

pkg/apis/pipelinesascode/v1alpha1/types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,9 @@ type GitlabSettings struct {
170170
// CommentStrategy defines how GitLab comments are handled for pipeline results.
171171
// Options:
172172
// - 'disable_all': Disables all comments on merge requests
173+
// - 'update': Updates a single comment per PipelineRun on every trigger.
173174
// +optional
174-
// +kubebuilder:validation:Enum="";disable_all
175+
// +kubebuilder:validation:Enum="";disable_all;update
175176
CommentStrategy string `json:"comment_strategy,omitempty"`
176177
}
177178

pkg/cmd/tknpac/cel/cel.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,10 @@ func printBanner(ioStreams *cli.IOStreams, provider, bodyFile, headersFile strin
8181

8282
fmt.Fprintf(ioStreams.Out, "%s %s\n", cs.Yellow("⚠"), cs.Bold("Important Notice"))
8383
fmt.Fprint(ioStreams.Out, "\n")
84-
fmt.Fprintf(ioStreams.Out, "This tool provides an interactive environment for testing CEL expressions.\n")
85-
fmt.Fprintf(ioStreams.Out, "However, please note the following important differences:\n")
84+
fmt.Fprintf(ioStreams.Out, "This is a %s feature for testing CEL expressions.\n", cs.Yellow("tech preview"))
85+
fmt.Fprintf(ioStreams.Out, "%s\n", cs.Bold("The evaluator may not always produce the same output as in actual PipelineRuns."))
86+
fmt.Fprint(ioStreams.Out, "\n")
87+
fmt.Fprintf(ioStreams.Out, "Please note the following important differences:\n")
8688
fmt.Fprint(ioStreams.Out, "\n")
8789

8890
differences := []string{

pkg/matcher/annotation_matcher.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -298,10 +298,26 @@ func MatchPipelinerunByAnnotation(ctx context.Context, logger *zap.SugaredLogger
298298
if err != nil {
299299
logger.Errorf("there was an error evaluating the CEL expression, skipping: %v", err)
300300
if checkIfCELEvaluateError(err) {
301-
celValidationErrors = append(celValidationErrors, &pacerrors.PacYamlValidations{
302-
Name: prName,
303-
Err: fmt.Errorf("CEL expression evaluation error: %s", sanitizeErrorAsMarkdown(err)),
304-
})
301+
if provider.IsCommentStrategyUpdate(repo) {
302+
// Using the same logic for getting OriginalPipelineRun as the one used for setting
303+
// the annotation which is used in the provider's "update" comment strategy.
304+
originPipelineRunName := prun.GetName()
305+
if originPipelineRunName == "" && prun.GenerateName != "" {
306+
originPipelineRunName = prun.GetGenerateName()
307+
}
308+
309+
if reportErrors {
310+
reportCELValidationErrors(ctx, repo, []*pacerrors.PacYamlValidations{{
311+
Name: originPipelineRunName,
312+
Err: fmt.Errorf("CEL expression evaluation error: %s", sanitizeErrorAsMarkdown(err)),
313+
}}, eventEmitter, vcx, event, fmt.Sprintf(provider.PlrStatusCommentPrefixTemplate, originPipelineRunName))
314+
}
315+
} else {
316+
celValidationErrors = append(celValidationErrors, &pacerrors.PacYamlValidations{
317+
Name: prName,
318+
Err: fmt.Errorf("CEL expression evaluation error: %s", sanitizeErrorAsMarkdown(err)),
319+
})
320+
}
305321
}
306322
continue
307323
}
@@ -395,7 +411,7 @@ func MatchPipelinerunByAnnotation(ctx context.Context, logger *zap.SugaredLogger
395411

396412
if len(celValidationErrors) > 0 && reportErrors {
397413
logger.Debugf("MatchPipelinerunByAnnotation: reporting %d CEL validation errors", len(celValidationErrors))
398-
reportCELValidationErrors(ctx, repo, celValidationErrors, eventEmitter, vcx, event)
414+
reportCELValidationErrors(ctx, repo, celValidationErrors, eventEmitter, vcx, event, "")
399415
}
400416

401417
if len(matchedPRs) > 0 {

pkg/matcher/errors.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,30 @@ func checkIfCELEvaluateError(err error) bool {
3838
return false
3939
}
4040

41-
func reportCELValidationErrors(ctx context.Context, repo *apipac.Repository, validationErrors []*pacerrors.PacYamlValidations, eventEmitter *events.EventEmitter, vcx provider.Interface, event *info.Event) {
41+
func reportCELValidationErrors(ctx context.Context, repo *apipac.Repository, validationErrors []*pacerrors.PacYamlValidations, eventEmitter *events.EventEmitter, vcx provider.Interface, event *info.Event, prefix string) {
4242
errorRows := make([]string, 0, len(validationErrors))
4343
for _, err := range validationErrors {
4444
errorRows = append(errorRows, fmt.Sprintf("| %s | `%s` |", err.Name, err.Err.Error()))
4545
}
4646
if len(errorRows) == 0 {
4747
return
4848
}
49-
markdownErrMessage := fmt.Sprintf(`%s
49+
50+
var err error
51+
52+
// The prefix is used for a single comment "update" strategy where the same comment is updated
53+
// with the celValidationError and the PipelineRun status for any subsequent or prior "runs".
54+
if prefix != "" {
55+
markdownErrMessage := fmt.Sprintf(`%s
56+
%s
57+
%s`, prefix, provider.ValidationErrorTemplate, strings.Join(errorRows, "\n"))
58+
err = vcx.CreateComment(ctx, event, markdownErrMessage, prefix)
59+
} else {
60+
markdownErrMessage := fmt.Sprintf(`%s
5061
%s`, provider.ValidationErrorTemplate, strings.Join(errorRows, "\n"))
51-
if err := vcx.CreateComment(ctx, event, markdownErrMessage, provider.ValidationErrorTemplate); err != nil {
62+
err = vcx.CreateComment(ctx, event, markdownErrMessage, provider.ValidationErrorTemplate)
63+
}
64+
if err != nil {
5265
eventEmitter.EmitMessage(repo, zap.ErrorLevel, "PipelineRunCommentCreationError",
5366
fmt.Sprintf("failed to create comment: %s", err.Error()))
5467
}

0 commit comments

Comments
 (0)