Skip to content

feat(status): report skipped status for unmatched PipelineRuns - #2918

Open
zakisk wants to merge 1 commit into
tektoncd:mainfrom
zakisk:SRVKP-13160-skipped-check-run-per-pipelinerun-mode-imple
Open

feat(status): report skipped status for unmatched PipelineRuns#2918
zakisk wants to merge 1 commit into
tektoncd:mainfrom
zakisk:SRVKP-13160-skipped-check-run-per-pipelinerun-mode-imple

Conversation

@zakisk

@zakisk zakisk commented Aug 11, 2026

Copy link
Copy Markdown
Member

📝 Description of the Change

When a repository has multiple PipelineRuns in .tekton/ targeting different events, only the ones matching the incoming event run. The rest are silently ignored, leaving gaps in the Git provider's status checks UI.

For example, a repository with two PipelineRuns:

.tekton/build.yaml — on-event: pull_request, on-target-branch: main
.tekton/deploy.yaml — on-event: push, on-target-branch: main

When a pull request is opened, build.yaml matches and runs. Without this feature, deploy.yaml produces no status at all — it is impossible to tell from the PR whether it was skipped intentionally or never picked up. With status_check enabled:

spec:
settings:
status_check:
enabled: true
mode: "per_unmatched_pipelinerun"

Pipelines-as-Code now reports a "skipped" status for deploy.yaml on the pull request, making the full picture visible in the provider UI.

The matcher now returns both matched and unmatched PipelineRuns. After the matched runs complete, the controller iterates the unmatched list and calls CreateStatus on each with the configured conclusion. The conclusion defaults to skipped but can be set to success or neutral via the no_match_conclusion field.

Every provider maps that conclusion to its native state:

  • GitHub App: check run conclusion "skipped"
  • GitHub Webhook: commit status "success" (API has no skipped)
  • GitLab: pipeline status "skipped"
  • Bitbucket Cloud: build status "STOPPED"
  • Bitbucket Data Center: build status "UNKNOWN"
  • Gitea/Forgejo: commit status "success" (no skipped state)

The setting is inheritable from the global Repository CR via the existing Settings.Merge path. A second mode (aggregate) is defined in the CRD but not yet implemented.

The whole feature is behind an opt-in flag (enabled: false by default) and marked as tech preview in the documentation.

🔗 Linked GitHub Issue

Fixes #

🧪 Testing Strategy

  • Unit tests
  • Integration tests
  • End-to-end tests
  • Manual testing
  • Not Applicable

🤖 AI Assistance

AI assistance can be used for various tasks, such as code generation,
documentation, or testing.

Please indicate whether you have used AI assistance
for this PR and provide details if applicable.

  • I have not used any AI assistance for this PR.
  • I have used AI assistance for this PR. (For testing)

Important

Slop will be simply rejected, if you are using AI assistance you need to make sure you
understand the code generated and that it meets the project's standards. you
need at least know how to run the code and deploy it (if needed). See
startpaac to make it easy
to deploy and test your code changes.

If the majority of the code in this PR was generated by an AI, please add a Co-authored-by trailer to your commit message.
For example:

Co-authored-by: Claude noreply@anthropic.com

✅ Submitter Checklist

  • 📝 My commit messages are clear, informative, and follow the project's How to write a git commit message guide. The Gitlint linter ensures in CI it's properly validated
  • ✨ I have ensured my commit message prefix (e.g., fix:, feat:) matches the "Type of Change" I selected above.
  • ♽ I have run make test and make lint locally to check for and fix any
    issues. For an efficient workflow, I have considered installing
    pre-commit and running pre-commit install to
    automate these checks.
  • 📖 I have added or updated documentation for any user-facing changes.
  • 🧪 I have added sufficient unit tests for my code changes.
  • 🎁 I have added end-to-end tests where feasible. See README for more details.
  • 🔎 I have addressed any CI test flakiness or provided a clear reason to bypass it.
  • If adding a provider feature, I have filled in the following and updated the provider documentation:
    • GitHub App
    • GitHub Webhook
    • Gitea/Forgejo
    • GitLab
    • Bitbucket Cloud
    • Bitbucket Data Center

@zakisk
zakisk requested a review from chmouel August 11, 2026 06:51
@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.58621% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.95%. Comparing base (6856ee8) to head (d2b2ce2).

Files with missing lines Patch % Lines
pkg/pipelineascode/match.go 61.11% 13 Missing and 1 partial ⚠️
pkg/matcher/annotation_matcher.go 77.77% 4 Missing ⚠️
pkg/provider/gitea/gitea.go 50.00% 4 Missing ⚠️
pkg/provider/github/status.go 81.81% 2 Missing ⚠️
pkg/provider/gitlab/gitlab.go 50.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2918      +/-   ##
==========================================
+ Coverage   80.66%   80.95%   +0.28%     
==========================================
  Files         164      164              
  Lines       13911    13970      +59     
==========================================
+ Hits        11222    11309      +87     
+ Misses       1967     1942      -25     
+ Partials      722      719       -3     
Flag Coverage Δ
unit-tests 80.95% <77.58%> (+0.28%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread docs/content/docs/guides/repository-crd/status-check.md Outdated
@pipelines-as-code

pipelines-as-code Bot commented Aug 11, 2026

Copy link
Copy Markdown

Paco Review ⚠️

Paco: the model returned output that could not be parsed as a review.

Reviewed commit: 875837e

@pipelines-as-code pipelines-as-code Bot added the paco/review-hard Paco review difficulty label Aug 11, 2026

@pipelines-as-code pipelines-as-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Paco inline comments -- see the Paco Review summary comment for the overview.

Comment thread pkg/pipelineascode/match.go Outdated
Comment thread pkg/matcher/annotation_matcher.go
@zakisk
zakisk force-pushed the SRVKP-13160-skipped-check-run-per-pipelinerun-mode-imple branch from 08fde7b to e2008a9 Compare August 12, 2026 09:59
@zakisk

zakisk commented Aug 12, 2026

Copy link
Copy Markdown
Member Author

/paco review

@zakisk

zakisk commented Aug 12, 2026

Copy link
Copy Markdown
Member Author

I can't request review from copilot. cc: @chmouel

@pipelines-as-code pipelines-as-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Paco inline comments -- see the Paco Review summary comment for the overview.

Comment thread pkg/pipelineascode/pipelineascode.go Outdated
Comment thread pkg/pipelineascode/pipelineascode.go Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in “status_check” feature to report provider statuses for PipelineRuns that do not match the incoming event, improving visibility in Git provider UIs when multiple .tekton/ PipelineRuns target different triggers.

Changes:

  • Extend PipelineRun matching to return both matched and unmatched PipelineRuns, and (when enabled) report a “skipped/success/neutral” status for each unmatched PipelineRun.
  • Update provider-specific status mapping/formatting to support a “skipped” conclusion (or best-effort equivalents where unsupported).
  • Add unit/E2E test coverage and documentation/CRD updates for the new Repository spec.settings.status_check API.

Reviewed changes

Copilot reviewed 35 out of 36 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/pkg/bitbucketdatacenter/crd.go Pass Settings into Bitbucket DC E2E Repository CR creation.
test/pkg/bitbucketcloud/crd.go Pass Settings into Bitbucket Cloud E2E Repository CR creation.
test/gitlab_merge_request_test.go Add E2E coverage for skipped status reporting on GitLab MR.
test/github_pullrequest_test.go Add E2E coverage for skipped status reporting (GitHub App + webhook).
test/gitea_pull_request_test.go Add E2E coverage for skipped status reporting on Gitea/Forgejo.
test/bitbucket_datacenter_push_test.go Update CreateCRD call signature to include opts/settings.
test/bitbucket_datacenter_pull_request_test.go Add Bitbucket DC PR E2E coverage for skipped statuses + CreateCRD signature update.
test/bitbucket_datacenter_dynamic_variables_test.go Update CreateCRD call signature to include opts/settings.
test/bitbucket_cloud_pullrequest_test.go Add Bitbucket Cloud PR E2E coverage for skipped statuses.
pkg/provider/github/status.go Map skipped conclusion appropriately for check runs and commit statuses; avoid empty DetailsURL in check run creation.
pkg/provider/github/status_test.go Add unit coverage for skipped conclusion behavior (apps + webhook).
pkg/provider/gitea/status_test.go Add unit coverage for skipped conclusion mapping (success + “Skipped” description).
pkg/provider/gitea/gitea.go Add skipped conclusion formatting + map skipped to success for commit statuses.
pkg/provider/bitbucketdatacenter/bitbucketdatacenter.go Map skipped conclusion to Bitbucket DC “UNKNOWN” state and update title text.
pkg/provider/bitbucketdatacenter/bitbucketdatacenter_test.go Add unit coverage for skipped conclusion.
pkg/provider/bitbucketcloud/bitbucket.go Update skipped title text for Bitbucket Cloud status reporting.
pkg/provider/bitbucketcloud/bitbucket_test.go Add unit coverage for skipped conclusion.
pkg/pipelineascode/testdata/no-match/.tekton/nomatch.yaml Add annotations to ensure deterministic “no-match” behavior for tests.
pkg/pipelineascode/pipelineascode.go Report per-unmatched statuses (when enabled) after starting matched PipelineRuns; add helper reporter.
pkg/pipelineascode/pipelineascode_test.go Add Run() test covering per-unmatched status reporting.
pkg/pipelineascode/pipelineascode_statuscheck_test.go New unit tests for status reporting helper behavior and error emission.
pkg/pipelineascode/match.go Plumb unmatched PipelineRuns through the matching flow.
pkg/pipelineascode/match_test.go Update tests to validate unmatched PipelineRuns counts.
pkg/matcher/annotation_matcher.go Return unmatched PipelineRuns alongside matches and populate unmatched list on non-match branches.
pkg/matcher/annotation_matcher_test.go Add tests verifying unmatched PipelineRun tracking and related logs.
pkg/apis/pipelinesascode/v1alpha1/zz_generated.deepcopy.go Regenerate deep-copies to include StatusCheck.
pkg/apis/pipelinesascode/v1alpha1/types.go Add StatusCheck API types/constants and inheritance via Settings.Merge.
pkg/apis/pipelinesascode/v1alpha1/types_test.go Add tests verifying StatusCheck inheritance/precedence.
docs/content/docs/operations/global-repository-settings.md Link global settings doc to the new Status Check guide.
docs/content/docs/guides/statuses.md Document the unmatched-PipelineRun status-check feature at a high level.
docs/content/docs/guides/repository-crd/status-check.md New tech preview guide documenting configuration and provider behavior.
docs/content/docs/guides/_index.md Update guide index card subtitle to mention status checks.
docs/content/docs/api/settings.md Add API reference documentation for settings.status_check.
docs/content/docs/api/repository.md Include status_check snippet in Repository API docs.
docs/content/docs/api/repository-spec.md Include status_check snippet in RepositorySpec API docs.
config/300-repositories.yaml CRD schema updates for the new spec.settings.status_check fields.
Files not reviewed (1)
  • pkg/apis/pipelinesascode/v1alpha1/zz_generated.deepcopy.go: Generated file

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pkg/pipelineascode/pipelineascode.go Outdated
Comment thread pkg/apis/pipelinesascode/v1alpha1/types.go Outdated
Comment thread pkg/pipelineascode/match.go Outdated
Comment thread pkg/pipelineascode/pipelineascode.go Outdated
Comment thread pkg/matcher/annotation_matcher.go Outdated
Comment thread pkg/pipelineascode/pipelineascode.go Outdated
Comment thread pkg/pipelineascode/pipelineascode.go
Comment thread pkg/apis/pipelinesascode/v1alpha1/types.go Outdated
@zakisk
zakisk force-pushed the SRVKP-13160-skipped-check-run-per-pipelinerun-mode-imple branch from e2008a9 to 1d55e09 Compare August 13, 2026 10:48
@zakisk
zakisk force-pushed the SRVKP-13160-skipped-check-run-per-pipelinerun-mode-imple branch from 1d55e09 to 79b4ba9 Compare August 13, 2026 17:09
@zakisk

zakisk commented Aug 14, 2026

Copy link
Copy Markdown
Member Author

/retest

@zakisk
zakisk force-pushed the SRVKP-13160-skipped-check-run-per-pipelinerun-mode-imple branch 3 times, most recently from bd2762c to d7a4b71 Compare August 19, 2026 12:43
@zakisk

zakisk commented Aug 20, 2026

Copy link
Copy Markdown
Member Author

/retest

@zakisk
zakisk force-pushed the SRVKP-13160-skipped-check-run-per-pipelinerun-mode-imple branch from d7a4b71 to 8805b0f Compare August 20, 2026 14:40
@zakisk

zakisk commented Aug 21, 2026

Copy link
Copy Markdown
Member Author

/retest

@zakisk
zakisk force-pushed the SRVKP-13160-skipped-check-run-per-pipelinerun-mode-imple branch 2 times, most recently from d01f965 to 043ba0e Compare August 25, 2026 06:16
@zakisk

zakisk commented Aug 25, 2026

Copy link
Copy Markdown
Member Author

/retest

@zakisk

zakisk commented Aug 26, 2026

Copy link
Copy Markdown
Member Author

/test go-testing

@zakisk
zakisk force-pushed the SRVKP-13160-skipped-check-run-per-pipelinerun-mode-imple branch from 043ba0e to 04f6150 Compare August 26, 2026 09:29
@zakisk

zakisk commented Aug 27, 2026

Copy link
Copy Markdown
Member Author

/test go-testing

Comment thread pkg/pipelineascode/pipelineascode.go
@zakisk
zakisk force-pushed the SRVKP-13160-skipped-check-run-per-pipelinerun-mode-imple branch 3 times, most recently from 0f09113 to 3756d41 Compare September 1, 2026 05:14
Comment thread pkg/matcher/annotation_matcher.go Outdated
Comment on lines +406 to +407
if event.EventType == triggertype.PullRequestLabeled.String() {
unmatchedPRs = append(unmatchedPRs, prun)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider a pipelinerun with annotation on-label: "ready-to-test". Would it not be shown as skipped on a push event?

@zakisk zakisk Sep 1, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, that's the reason eventType is checked

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This contradicts with the description ... produces no status at all — it is impossible to tell from the PR whether it was skipped intentionally or never picked up. The on-label pipelinerun shows no status on pull request and it seems similar to the scenario described in the description.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on-label pipelinerun shows
what do you mean by this?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider a on-label.yaml which only runs on on-label: "ready-to-test" annotation. Based on the changes, this prun would only be shown as skipped for pull_request_labeled event, not push or other events.
This feels contradictory to the example in the description where

.tekton/build.yaml — on-event: pull_request, on-target-branch: main
.tekton/deploy.yaml — on-event: push, on-target-branch: main

where deploy.yaml shows as skipped on pull_request open.
By this logic, shouldn't we also show "skipped" status on push for on-label.yaml

Comment thread pkg/pipelineascode/pipelineascode.go
@chmouel

chmouel commented Sep 2, 2026

Copy link
Copy Markdown
Member

If i understand okay every provider except the GitHub App path posts a PR comment for each unmatched PipelineRun (Status: completed + non-empty Text). N unmatched runs = N comments per push. This is going to annoy people quickly isnt it ?

And you forgot to update the schemas: (the linter probably need to be fixed)

image

it would be easier if we drop the aggregate stuff, ie: aggregate_name / StatusCheckModeAggregate / all aggregate docs. adnd only add it when we do the implementation.

I have some issue with the naming, but maybe it's just me and happy to take vote (cc @theakshaypant ) what does it look more saner and explicit

Before (this PR)

settings:
  status_check:
    enabled: true
    mode: per_unmatched_pipelinerun
    no_match_conclusion: skipped

Suggested change:

settings:
  status_checks:
    report_unmatched: true
    mode: per_pipelinerun
    unmatched_conclusion: skipped

this feels more english to me,

My reasoning for this:

  •  enabled  to report_unmatched :  enabled: true  today only turns on reporting for unmatched runs. Matched runs already get statuses regardless. The current name implies it toggles all status checks.
  •  per_unmatched_pipelinerun to per_pipelinerun : the mode describes how checks are reported (one per PipelineRun), not which ones. Shorter, and doesn't bake "unmatched" into a name that may later cover matched runs too.
    •  status_check  to  status_checks : plural, since it configures multiple check

@zakisk

zakisk commented Sep 3, 2026

Copy link
Copy Markdown
Member Author

enabled to report_unmatched : enabled: true today only turns on reporting for unmatched runs. Matched runs already get statuses regardless. The current name implies it toggles all status checks.

@chmouel actually enabled will be used for both mode (after aggregate is implemented soon) so report_unmatched seems only related to unmatch reporting. and also I chose per_unmatched_pipelinerun mode name to describe it because enabled was intended for both modes, wdyt should I still change it??

@theakshaypant

Copy link
Copy Markdown
Member

it would be easier if we drop the aggregate stuff, ie: aggregate_name / StatusCheckModeAggregate / all aggregate docs. adnd only add it when we do the implementation.

+1 on this

regarding the suggested names

  1. status_check -> status_checks: agreed, makes more sense
  2. per_unmatched_pipelinerun -> per_pipelinerun: I like this suggested name change as it makes it, one, concise and, second, it describes well how the status will be reported.
  3. enabled to report_unmatched: After reading Zaki's comment, it makes sense to keep the enabled name

@zakisk
zakisk force-pushed the SRVKP-13160-skipped-check-run-per-pipelinerun-mode-imple branch from 3756d41 to 875837e Compare September 4, 2026 14:25
@zakisk

zakisk commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

If i understand okay every provider except the GitHub App path posts a PR comment for each unmatched PipelineRun (Status: completed + non-empty Text). N unmatched runs = N comments per push. This is going to annoy people quickly isnt it ?

yeah, it was valid point for gitlab, gitea and github webhook. fixed it.

And you forgot to update the schemas: (the linter probably need to be fixed)

it's updated now

it would be easier if we drop the aggregate stuff, ie: aggregate_name / StatusCheckModeAggregate / all aggregate docs. adnd only add it when we do the implementation.

yes, removed

I have some issue with the naming

changed status_check -> status_checks and per_unmatched_pipelinerun -> per_pipelinerun and no_match_conclusion -> unmatched_conclusion but I kept enabled as it seems more perfect than report_unmatched as gate the whole feature.

@zakisk

zakisk commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

/paco review

@zakisk

zakisk commented Sep 7, 2026

Copy link
Copy Markdown
Member Author

/test linters

Comment thread docs/content/docs/api/repository-spec.md Outdated
Comment thread docs/content/docs/api/repository.md Outdated
Comment thread docs/content/docs/api/settings.md
Comment thread docs/content/docs/api/settings.md Outdated
Comment thread docs/content/docs/guides/repository-crd/status-checks.md
Comment thread docs/content/docs/guides/statuses.md
Comment thread pkg/matcher/annotation_matcher.go Outdated
Comment on lines +406 to +407
if event.EventType == triggertype.PullRequestLabeled.String() {
unmatchedPRs = append(unmatchedPRs, prun)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This contradicts with the description ... produces no status at all — it is impossible to tell from the PR whether it was skipped intentionally or never picked up. The on-label pipelinerun shows no status on pull request and it seems similar to the scenario described in the description.

@zakisk
zakisk force-pushed the SRVKP-13160-skipped-check-run-per-pipelinerun-mode-imple branch from 875837e to 6844f34 Compare September 7, 2026 07:37
When a repository has multiple PipelineRuns in .tekton/ targeting
different events, only the ones matching the incoming event run. The
rest are silently ignored, leaving gaps in the Git provider's status
checks UI.

For example, a repository with two PipelineRuns:

  .tekton/build.yaml   — on-event: pull_request, on-target-branch: main
  .tekton/deploy.yaml  — on-event: push, on-target-branch: main

When a pull request is opened, build.yaml matches and runs. Without
this feature, deploy.yaml produces no status at all — it is impossible
to tell from the PR whether it was skipped intentionally or never
picked up. With status_check enabled:

  spec:
    settings:
      status_check:
        enabled: true
        mode: "per_unmatched_pipelinerun"

Pipelines-as-Code now reports a "skipped" status for deploy.yaml on
the pull request, making the full picture visible in the provider UI.

The matcher now returns both matched and unmatched PipelineRuns. After
the matched runs complete, the controller iterates the unmatched list
and calls CreateStatus on each with the configured conclusion. The
conclusion defaults to `skipped` but can be set to `success` or
`neutral` via the `no_match_conclusion` field.

Every provider maps that conclusion to its native state:

  - GitHub App:           check run conclusion "skipped"
  - GitHub Webhook:       commit status "success" (API has no skipped)
  - GitLab:               pipeline status "skipped"
  - Bitbucket Cloud:      build status "STOPPED"
  - Bitbucket Data Center: build status "UNKNOWN"
  - Gitea/Forgejo:        commit status "success" (no skipped state)

The setting is inheritable from the global Repository CR via the
existing Settings.Merge path. A second mode (`aggregate`) is defined
in the CRD but not yet implemented.

The whole feature is behind an opt-in flag (enabled: false by default)
and marked as tech preview in the documentation.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Zaki Shaikh <zashaikh@redhat.com>
@zakisk
zakisk force-pushed the SRVKP-13160-skipped-check-run-per-pipelinerun-mode-imple branch from 6844f34 to d2b2ce2 Compare September 7, 2026 13:05
}

matchedPRs, err = matcher.MatchPipelinerunByAnnotation(ctx, p.logger, pipelineRuns, p.run, p.event, p.vcx, p.eventEmitter, repo, false)
// unmatchedPRs are filtered out above if RemoteTasks is enabled so we should also check if RemoteTasks is enabled then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[question] What happens when there is an error in resolving a pipelinerun? Is it reported as skipped or is there an error reported for the prun?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, there will be no status check reporting if any error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

paco/review-hard Paco review difficulty

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants