Skip to content

Run one sync at a time - #23

Merged
mervin008 merged 1 commit into
mainfrom
ci/serialise-sync
Oct 4, 2026
Merged

mervin008 merged 1 commit into
mainfrom
ci/serialise-sync

Conversation

@mervin008

Copy link
Copy Markdown
Collaborator

Problem: two dispatches that arrive close together race to push to main.

On 2026-09-27, certpilot#118 and certpilot-agent#6 merged 3 seconds apart. Both syncs checked out the same main, and the second push was rejected as not a fast-forward (run 36320902564). Rerunning doesn't help, because a rerun checks out the original commit and is rejected again.

Nothing was lost this time: both runs would have published the same two pages. It will recur on any burst of merges, including the five phase-2 PRs queued on certpilot (#119–#123).

Fix: a workflow-level concurrency: {group: sync, cancel-in-progress: false}.

  • Runs queue instead of racing.
  • A run in progress is never cancelled mid-publish.
  • GitHub keeps one pending run per group, so a burst ends with a run for the newest dispatch, which includes the earlier merges.

How it was verified

  • The workflow YAML parses.
  • The failure mode was confirmed from the failed run's log (! [remote rejected] main -> main (cannot lock ref …)) and from the rerun's (! [rejected] main -> main (fetch first)).
  • Not verified: the queueing itself. It can only be observed on the next burst of dispatches.

🤖 Generated with Claude Code

certpilot#118 and certpilot-agent#6 merged three seconds apart on
2026-09-27. Each dispatched a sync, and both runs checked out the same
main. The first pushed. The second was rejected as not a fast-forward
and failed.

Nothing was lost that time: both runs would have published the same
two pages. A rerun could not recover it anyway, because a rerun checks
out the original commit again and is rejected the same way. The failure
reads as a broken pipeline all the same, and it recurs on any burst of
merges, such as the five phase-2 pull requests queued on certpilot.

A workflow-level concurrency group queues runs rather than cancelling
them, because a run in progress may be halfway through publishing.
GitHub keeps one pending run per group, so a burst ends with a run for
the newest dispatch, which reads what the earlier ones would have.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@mervin008
mervin008 merged commit 39ced4c into main Oct 4, 2026
1 check passed
@mervin008
mervin008 deleted the ci/serialise-sync branch October 4, 2026 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant