What's happening
verify-release-intent.yml correctly implements its label-extraction logic — this is not a bug in the jq filtering. But there's a race condition in how consuming repos trigger it that produces a confusing, spurious failing check run whenever a pull request is opened and then labeled a few seconds later (a very common flow: gh pr create --label patch, or a human opening a PR and immediately clicking a label).
Concrete example (Cratis/Templates PR #36)
Every repo's thin caller (verify-semver-label.yml) triggers on:
on:
pull_request:
types: [opened, reopened, synchronize, labeled, unlabeled]
For PR #36 (fix/26-atomic-publication):
2026-09-06T09:08:12Z — PR opened (no labels yet) → run 34023786118 starts, evaluates LABELS: [], fails with "This pull request states no release intent."
2026-09-06T09:08:16Z — patch label added → run 34023791826 starts (correctly sees patch), succeeds.
The concurrency: cancel-in-progress: true group (${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}) is supposed to cancel the stale "opened" run once the "labeled" run starts for the same PR, but the job body is a few lines of jq/bash that finishes in well under a second — faster than GitHub can cancel it. So instead of the older run being cleanly superseded (which does happen sometimes — see run 33147269338 on PR carrying docs/discoverability, which shows cancelled), it completes first and posts a failure.
The result: the commit ends up with both a failure and a success entry for the same check name (verify / verify) in its status-check rollup. It doesn't block merging (the latest run for the SHA is what GitHub's merge gate honors), but it's confusing — a red X shows up in the PR's check history for a run that already reflects stale, pre-label state, and it can trigger unnecessary "why did this fail?" investigation (as it did here).
This isn't unique to Cratis/Templates — every repo that adopted the reusable workflow copies the same types: [...] trigger list (checked Chronicle, Arc, Fundamentals, Components — all identical), so all of them see this whenever a PR is opened before it's labeled.
Possible directions (not prescribing a fix — this is a judgment call for the team that owns the gate's UX)
- Drop
opened from the trigger types, since it almost always precedes a deliberate label choice; labeled/unlabeled/synchronize would still guarantee the check reruns whenever the label state or code actually changes. Trade-off: a PR that's opened and genuinely never labeled would show as "expected"/pending rather than an explicit failing message telling the author what to do.
- Or accept this as a known, non-blocking cosmetic rough edge, since it never actually blocks a merge.
Evidence
Filed after investigating Cratis/Templates#37 (a workflow-run failure report) — no code fix was made in Cratis/Templates, since its thin caller has no logic to fix and correctly delegates to this reusable workflow.
What's happening
verify-release-intent.ymlcorrectly implements its label-extraction logic — this is not a bug in thejqfiltering. But there's a race condition in how consuming repos trigger it that produces a confusing, spurious failing check run whenever a pull request is opened and then labeled a few seconds later (a very common flow:gh pr create --label patch, or a human opening a PR and immediately clicking a label).Concrete example (Cratis/Templates PR #36)
Every repo's thin caller (
verify-semver-label.yml) triggers on:For PR #36 (
fix/26-atomic-publication):2026-09-06T09:08:12Z— PR opened (no labels yet) → run 34023786118 starts, evaluatesLABELS: [], fails with "This pull request states no release intent."2026-09-06T09:08:16Z—patchlabel added → run 34023791826 starts (correctly seespatch), succeeds.The
concurrency: cancel-in-progress: truegroup (${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}) is supposed to cancel the stale "opened" run once the "labeled" run starts for the same PR, but the job body is a few lines ofjq/bash that finishes in well under a second — faster than GitHub can cancel it. So instead of the older run being cleanly superseded (which does happen sometimes — see run 33147269338 on PR carryingdocs/discoverability, which showscancelled), it completes first and posts afailure.The result: the commit ends up with both a
failureand asuccessentry for the same check name (verify / verify) in its status-check rollup. It doesn't block merging (the latest run for the SHA is what GitHub's merge gate honors), but it's confusing — a red X shows up in the PR's check history for a run that already reflects stale, pre-label state, and it can trigger unnecessary "why did this fail?" investigation (as it did here).This isn't unique to Cratis/Templates — every repo that adopted the reusable workflow copies the same
types: [...]trigger list (checked Chronicle, Arc, Fundamentals, Components — all identical), so all of them see this whenever a PR is opened before it's labeled.Possible directions (not prescribing a fix — this is a judgment call for the team that owns the gate's UX)
openedfrom the trigger types, since it almost always precedes a deliberate label choice;labeled/unlabeled/synchronizewould still guarantee the check reruns whenever the label state or code actually changes. Trade-off: a PR that's opened and genuinely never labeled would show as "expected"/pending rather than an explicit failing message telling the author what to do.Evidence
LABELS: []at trigger time — the PR genuinely had no labels yet)Filed after investigating Cratis/Templates#37 (a workflow-run failure report) — no code fix was made in Cratis/Templates, since its thin caller has no logic to fix and correctly delegates to this reusable workflow.