ci(status): skip Status job when upstream scan was cancelled#22
Merged
Conversation
The Semgrep Status and Security Status aggregator jobs evaluate the
upstream scan's `result` and emit a FAILURE check_run when that
result is `cancelled`. In practice the only way the upstream gets
cancelled is concurrency superseding the run (two events arrive for
the same SHA — common after force-push + rapid follow-up push,
which leaves a delayed webhook in GitHub's queue).
That FAILURE check_run then blocks branch protection on the
surviving SUCCESS run, even though the actual scan was clean.
Fix: change `if: always()` → `if: ${{ !cancelled() }}` on both
Status jobs. After this:
- scan succeeds → Status runs, evaluates findings, passes/fails
- scan fails → Status runs, sees `result=failure`, fails
- scan cancelled → Status SKIPPED, no FAILURE check_run produced
A skipped Status produces a NEUTRAL check_run that branch protection
treats as not-failing. The surviving non-cancelled run's Status
emits SUCCESS and gates the merge correctly.
Security trade-off (acknowledged inline in the YAML):
The previous behaviour was justified by the comment "a fork PR
that's cancelled mid-flight could merge without ever being scanned."
That concern is mitigated separately:
- Fork PRs do not receive repo secrets (GitHub policy)
- These scans are read-only, no exfiltration vector
- A maintainer reviewing the PR can see the cancellation /
skip in the check-rollup before clicking Merge
Observed in the wild on simple-container-com/api PR #273
(c38148e) — every required-status check went CANCELLED + SUCCESS
from the dual-fire, with the cancelled twin's Status job emitting
the FAILURE that blocked the merge.
Refs simple-container-com/api#273.
Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
Security Scan ResultsRepository:
Scanned at 2026-05-19 09:46 UTC |
Semgrep Scan ResultsRepository:
Scanned at 2026-05-19 09:46 UTC |
Cre-eD
added a commit
to simple-container-com/api
that referenced
this pull request
May 19, 2026
Picks up the permanent fix for the cancellation-cascade we hit on the previous head of this PR (c38148e, where dual-fired pull_request events left FAILURE check_runs from the cancelled twin's Status aggregator job and blocked merge): simple-container-com/actions#22 ci(status): skip Status job when upstream scan was cancelled After this bump, future dual-fire events on any PR in this repo will produce NEUTRAL (skipped) Status check_runs from the cancelled twin instead of FAILURE — branch protection then treats the cancelled run as not-failing and the surviving run's SUCCESS gates the merge. Also pulls in actions#17 (drop sc-image-release reusable workflow + bump-self-release tooling) which landed between the previous pin and this one; no consumer-facing change in this repo because we don't reference those workflows. Pin applied uniformly across all four consumer workflows that reference the actions repo's reusable workflows: - .github/workflows/semgrep.yml - .github/workflows/semgrep-comment.yml - .github/workflows/security-scan.yml - .github/workflows/security-scan-comment.yml Signed-off-by: Dmitrii Creed <creeed22@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Semgrep Status and Security Status aggregator jobs currently emit a
FAILUREcheck_run when their upstream scan was cancelled. In practice the only realistic cause of cancellation is concurrency superseding the run — two webhook events arriving for the same SHA at the same instant, which happens commonly after a force-push followed by a rapid follow-up push (a delayed webhook from the earlier push fires alongside the new one).This FAILURE check_run then blocks branch protection on the surviving non-cancelled run, even though the actual scan was clean.
Hit live on
simple-container-com/apiPR #273 — every required-status check came back asCANCELLED + SUCCESSfrom the dual-fire, with the cancelled twin's Status emitting theFAILUREthat left the PRmergeStateStatus=BLOCKED.Fix
Change
if: always()→if: ${{ !cancelled() }}on both Status jobs.successfailurecancelledFAILURENEUTRALA skipped Status produces a
NEUTRALcheck_run that branch protection treats as not-failing. The surviving non-cancelled run's Status still emitsSUCCESSand gates the merge correctly.Security trade-off (acknowledged inline)
The previous behaviour was documented as guarding against "a fork PR that's cancelled mid-flight merging without ever being scanned." That concern is mitigated separately:
The original inline comments are preserved + extended to spell out this reasoning.
Test plan
simple-container-com/apiPR #273 should be unblocked once the new ref is consumed (it already pins to@main, so this merge propagates automatically).Files
.github/workflows/semgrep.yml— Status jobif:updated..github/workflows/security-scan.yml— Status jobif:updated.No behaviour change for the common case (scans completing normally). Only changes the cancellation-cascade path.