Skip to content

fix(release-please): queue overlapping runs to prevent branch races - #46

Merged
kojiromike merged 1 commit into
mainfrom
kojiromike/release-please-queue
Oct 24, 2026
Merged

kojiromike merged 1 commit into
mainfrom
kojiromike/release-please-queue

Conversation

@kojiromike

@kojiromike kojiromike commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

This change queues overlapping release-please runs in each caller repository. It prevents runs from racing to update the release PR branch.

Callers must not declare a concurrency group named release-please-reusable. Doing so causes a deadlock. None do today.

Rollout needs a release, and the open release PR #45 for 1.2.0 will pick it up. Dependabot then bumps callers that have github-actions updates configured. Callers without that configuration need a manual bump.

Background

Tonight six Dependabot merges landed in oce-fe-harness within 25 seconds. Run https://github.com/openCoreEMR/oce-fe-harness/actions/runs/40051491975 failed with "Error updating ref heads/release-please--branches--main" because a newer run had already moved the branch. No release work was lost, but main went red.

This revives #39. That PR was closed because without queue: max GitHub cancels the waiting run when a third overlaps. That also causes a red check. Pull request #41 made the shared actionlint accept queue, so that blocker is gone.

Behavior changes

The job uses a repo-wide group with queue: max and no cancel-in-progress. It sets a 30-minute timeout so a hung run cannot hold the queue. Runs are serialized. A burst of N merges takes about N times a ~1-minute run, and each run reads the current HEAD.

The README now covers the new concurrency group behavior and the group naming restriction for callers.

Verification

The YAML parses successfully. A local upstream actionlint 1.7.12 rejects queue as expected. This PR's actionlint check runs the v1.7.12-oce.3 fork build and is the real test. The workflow is not yet exercised in a caller.

Closes #40. Refs #39.

Summary by CodeRabbit

  • Chores
    • Release runs are now processed sequentially for each repository. Pending runs are queued, and runs already in progress are not canceled.
    • Release runs now have a 30-minute time limit.
    • Updated the release workflow documentation to describe the queueing behavior and time limit.

This serializes the reusable release-please job per caller repo with a concurrency group that queues every run, plus a 30-minute timeout. Overlapping runs race to update the release PR branch and the loser fails with "Error updating ref heads/release-please--branches--main." On 2026-10-24 six Dependabot merges landed in oce-fe-harness within 25 seconds and one run failed this way (oce-fe-harness run 40051491975).

The group is repo-wide, not per-ref, because release-please always targets the default branch. Queued runs read the branch's current HEAD, so a run whose commit was overtaken finds nothing to do. The timeout matters because a hung run holds the group. The slowest caller's job takes under five minutes. A caller that declares a concurrency group named release-please-reusable would deadlock with this job, so the README warns against it.

PR #39 tried the same group but was closed because GitHub's default keeps one pending run and cancels it when a newer one queues. This shows as a failed check. The `queue: max` setting avoids this but was blocked on actionlint. PR #41 fixed that by moving the shared check to the actionlint fork build v1.7.12-oce.3. Upstream actionlint 1.7.12 still rejects `queue`, so repos linting with it need the fork build. Closes #40. Refs #39.

Assisted-by: Claude Code
@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 01388d6e-5188-41e1-9916-0ca06448669b
📥 Commits

Reviewing files that changed from the base of the PR and between 4d2f1e0 and 8b37870.

📒 Files selected for processing: 2
  • .github/workflows/release-please-reusable.yml
  • README.md

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

📝 Walkthrough

The reusable Release Please job queues runs in a repository-wide concurrency group without canceling in-progress runs. It also has a 30-minute timeout. The README documents the queue behavior and the branch HEAD used when a run starts.

Changes: Release Please run serialization

Layer / File(s) Summary
Job concurrency and documentation
.github/workflows/release-please-reusable.yml, README.md
The job uses the release-please-reusable concurrency group with queue: max and cancel-in-progress: false, and has a 30-minute timeout. The README documents the queue behavior, branch HEAD behavior, timeout, and group-name restriction.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related PRs

Suggested reviewers: bjeffrey92

Merge Risk: 🟡 Moderate · up to 8b378

The changed queue behavior remains unvalidated in a real caller workflow before release.

Security architecture risk: 🔵 Low · up to 8b378

The change aims to prevent competing release updates without expanding permissions or adding new callers. The direct caller avoids the documented concurrency-group collision. Residual uncertainty concerns actual queue behavior and recovery when the new timeout interrupts a release update; these have not been demonstrated in a caller.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The affected control surface is release automation in repositories adopting this workflow version. The intended repository-wide group couples release-job scheduling within each caller repository. No additional repository access, IAM capability or secret source is introduced by the diff.

Trust Boundaries and Controls

  • observed — The direct caller remains limited to main pushes and manual dispatch, and the concurrency-group value is static rather than derived from event text. The PR adds no pull-request trigger or attacker-controlled credential-selection path.

Resilience and Maintainability Implications

  • inferred — Mutual exclusion is intended to prevent competing release-branch writers, while the timeout limits queue blockage. Neither establishes safe recovery from a partially completed release. The documented claim that queued runs reconcile current HEAD remains dependent on external behavior rather than an explicit checkout ref or local recovery implementation.
Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Linked Issues check Warning Issue #40 requires queue: max, actionlint support, removal of the one-pending-run caveat, and three overlapping runs that finish green. The workflow has queue: max, cancel-in-progress: false, an… Remove the one-pending-run caveat from the release-please job comment. Exercise three overlapping Release Please runs in one caller repository and provide evidence that all three finish green.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title "fix(release-please): queue overlapping runs to prevent branch races" matches the main change. The PR makes the release-please job serialize runs per caller repository with queue: max, which…
Out of Scope Changes check Passed The changes are limited to the reusable release-please workflow and its README documentation. The concurrency group, queueing, timeout, caller naming restriction, and related comments support Issue #4…
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Full details: Title check

Explanation

The title "fix(release-please): queue overlapping runs to prevent branch races" matches the main change. The PR makes the release-please job serialize runs per caller repository with queue: max, which queues overlapping runs instead of canceling them. The title names the component, the fix type, and the purpose. It stays specific and does not list files. The title is accurate and clear.

Full details: Out of Scope Changes check

Explanation

The changes are limited to the reusable release-please workflow and its README documentation. The concurrency group, queueing, timeout, caller naming restriction, and related comments support Issue #40 and the stated release-please behavior.

Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (2 skipped: 2 unsupported.)

Full details: Linked Issues check

Explanation

Issue #40 requires queue: max, actionlint support, removal of the one-pending-run caveat, and three overlapping runs that finish green. The workflow has queue: max, cancel-in-progress: false, and a 30-minute timeout. The actionlint workflow already pins v1.7.12-oce.3. The README documents the new behavior. However, the new workflow comment still describes the one-pending-run cancellation behavior, and the PR description states that the workflow was not exercised in a caller. The three-run completion criterion is therefore not met or verified.

Resolution

Remove the one-pending-run caveat from the release-please job comment. Exercise three overlapping Release Please runs in one caller repository and provide evidence that all three finish green.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@kojiromike
kojiromike merged commit 46e2e1e into main Oct 24, 2026
4 checks passed
@kojiromike
kojiromike deleted the kojiromike/release-please-queue branch October 24, 2026 02:08
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.

release-please: use queue: max on the concurrency group once actionlint accepts it

1 participant