Skip to content

ci: serialise the automation workflows on the state they write - #1310

Merged
mrbobbytables merged 1 commit into
mainfrom
ci/automation-concurrency-groups
Oct 11, 2026
Merged

mrbobbytables merged 1 commit into
mainfrom
ci/automation-concurrency-groups

Conversation

@mrbobbytables

Copy link
Copy Markdown
Member

Finding (#1222)

Four workflows open a pull request with peter-evans/create-pull-request on a branch they name themselves, and none declared a concurrency group. The action force-pushes refs/heads/<branch> with --force-with-lease and, with delete-branch: true, deletes that ref once it stops differing from the base. Two overlapping runs (a workflow_dispatch during the nightly cron, or Run workflow pressed twice) therefore either fail the loser's push on stale info or delete the ref the other run just opened a pull request from. Two further workflows mutate GitHub state non-atomically on a repeatable trigger.

Half 1: the workflows

workflow group why this key
architecture-submission.yml automation/architecture-issue-${{ github.event.issue.number }} per-issue, matching the per-issue branch, so different submissions still run in parallel
import-architectures.yml automation/import-architectures constant branch
refresh-community-people.yml automation/refresh-community-people constant branch
refresh-radar-reports.yml automation/refresh-radar-reports constant branch
create-milestones.yml create-milestones snapshots milestones once before its loop; two dispatches both take the create branch
pr-queue-hygiene.yml pr-queue-hygiene marker-comment state store is read then written non-atomically; overlapping runs double-post on contributor PRs

All six are cancel-in-progress: false: cancelling a run that has already pushed a branch, posted a marker or created a milestone is the failure mode, not the cure. Each block carries a comment explaining itself.

Half 2: the contract (tests/ci-concurrency.test.mjs)

  • racingBranchWorkflows / pullRequestBranches / expressionsIn: every workflow using the action must declare a group that varies with nothing the branch does not. A coarser group is accepted (it only queues more than it must); a finer one puts two runs that write one ref in different lanes and is reported.
  • unexplainedConstantGroups now uses isPerEvent (adds github.event.issue.number, inputs.) so the per-issue key is recognised as event-keyed rather than repository-wide.
  • The five constant groups are recorded in SERIALISED_WORKFLOWS with their reasons; the existing retire-itself test keeps them honest.
  • Six new tests cover every failure arm against fixtures. Header comment updated to describe both contracts.

Verification

  • node --test tests/ci-concurrency.test.mjs: 19 pass. With .github/workflows/ reverted, 2 fail and the branch-race contract names exactly the four branch-pushing files.
  • ci-supply-chain, workflow-scripts, automation-workflow-ordering: 42 pass.
  • npm run test:unit:coverage:check: green (src 100/100, harness 100/99.57, all files 99.66/96.16).
  • check:format, check:spelling: clean.

Closes #1222

Four workflows open a pull request with peter-evans/create-pull-request on a
branch they name themselves, and none declared a concurrency group. The
action force-pushes refs/heads/<branch> with --force-with-lease and, with
delete-branch: true, deletes that ref once it stops differing from the base,
so two overlapping runs (a dispatch during the nightly cron, or Run workflow
pressed twice) either fail the loser's push or delete the ref the other run
just opened a pull request from.

Add a concurrency group to each, keyed exactly as coarsely as the branch:
a constant group for import-architectures, refresh-community-people and
refresh-radar-reports, and a per-issue group for architecture-submission so
two different submissions still proceed in parallel. All are
cancel-in-progress: false, because cancelling a run that has already pushed
is the failure mode rather than the cure.

create-milestones and pr-queue-hygiene push no branch but mutate GitHub state
non-atomically (a read-once milestone snapshot; a marker comment read then
written), so they get constant, non-cancelling groups too.

tests/ci-concurrency.test.mjs gains the contract so the gap cannot reopen: a
workflow using the action must declare a group that varies with nothing the
branch does not (racingBranchWorkflows); unexplainedConstantGroups now accepts
any event-keyed group, not only per-PR ones; the five new constant groups are
recorded in SERIALISED_WORKFLOWS. With the workflow half reverted the contract
names all four branch-pushing files.

Closes #1222

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Bob Killen <bkillen@linuxfoundation.org>
@hivecommons-hive

Copy link
Copy Markdown
Contributor
62b8794

⚠️ Sentinel alert — maintainer review required

Hive flagged this PR (author @mrbobbytables, head 62b8794fd25b) because it matches behaviors that can override security controls, escalate privileges or damage the codebase. This is a heuristic, not an accusation — a maintainer should confirm the change is intended before it merges.

  • sensitive_path — changes 6 sensitive path(s) (Touches a sensitive path (OWNERS, workflows, policies, hive config, security docs, …))
    • .github/workflows/architecture-submission.yml
    • .github/workflows/create-milestones.yml
    • .github/workflows/import-architectures.yml
    • .github/workflows/pr-queue-hygiene.yml
    • .github/workflows/refresh-community-people.yml
    • .github/workflows/refresh-radar-reports.yml

Hive added the sentinel-alert label. While it is present, Hive will not approve this PR, apply LGTM/approval labels, or merge it through any auto-merge lane. Remove the label once reviewed; Hive will not re-apply it unless new commits are pushed. Tune paths and behaviors under sentinel in hive.yaml or the dashboard Security tab.

@mrbobbytables
mrbobbytables added this pull request to the merge queue Oct 11, 2026
Merged via the queue into main with commit bcebdf6 Oct 11, 2026
7 checks passed
@mrbobbytables
mrbobbytables deleted the ci/automation-concurrency-groups branch October 12, 2026 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[quality] automation workflows force-push a fixed PR branch with no concurrency group

1 participant