Skip to content

PR hygiene cancels most of its own runs #526

Closed

Description

@CaffeinatedCoder

How does it fail?

pr-hygiene.yml runs on opened, edited, reopened, synchronize, labeled, unlabeled, with concurrency: { group: pr-hygiene-<number>, cancel-in-progress: true }. A pull request that is pushed and then given its labels and body within seconds starts several runs, up to fifteen, and every run still going when the next one starts is cancelled.

Here "Labels and issue link" isn't a required check (only the four CI checks are, on main and release/**), so a cancelled run never blocks a merge. That's the difference from CaffeinatedCoder/CodoMetis.TypeKit#144, where it does. The cost here is still visible, though. GitHub counts every run in the commit's status, and a cancelled run counts as failing. 61 of the last 100 merged PRs show a red status for nothing but cancelled hygiene runs, with every other check green; #520, for example, has three cancelled runs and one green one. gh pr checks shows only the latest run per name, so it hides this. The check would also start blocking merges the day it becomes required.

What you ran

On 2026-10-29: gh run list --workflow pr-hygiene.yml --limit 400, which covers 2026-10-25 and 2026-10-26, grouped by commit.

What you got

295 of 400 runs cancelled and 105 succeeded, over 100 commits. Every commit has at least one successful run, and check-runs for the commit shows the successful one as the latest. For example, #421 at bd7683b had 15 runs, 14 of them cancelled, and #520 at 5bf8aaa had 7 runs, 6 of them cancelled.

What you expected

Each event's run completes, and the commit's status is green when the latest payload passes. The check takes seconds and reads only the event payload and two files, so there's nothing to save by cancelling it. The latest run decides the check.

Proposal

Set cancel-in-progress: false, or drop the concurrency group. With a group, a newer waiting run still cancels an older waiting one even when cancel-in-progress is false, so measure which choice leaves no cancelled run. Without a group, the runs may finish out of order: check which result GitHub keeps for the commit when an earlier payload (no labels yet) finishes after a later one. Write down what was measured in the workflow's header comment.

Lands on main and is cherry-picked into release/10.x, since the workflow runs from the pull request's base.

Done when

On a test pull request whose labels and body are set within a few seconds of the push, every hygiene run completes, none is cancelled, and the commit's status (statusCheckRollup.state) is SUCCESS. Leaving the PR without a type label still fails.

Measured (2026-10-29)

Dropping the group alone isn't enough. On the throwaway PR #527, five events ran to the end with none cancelled, but the two stale payloads that failed (no labels yet; two type labels at once) left the status FAILURE beside a green latest run. #528 also lets a run whose payload is out of date pass as superseded. A change to the head, base, labels or description is itself a trigger, so a newer run always exists to decide. #528 has the table.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/releaseVersioning, changelogs, release wiringbugSomething isn't workingseverity/lowCosmetic, message or documentation-level difference

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions