feat: adopt merge queue versioning - #29
Open
dblane-digicatapult wants to merge 11 commits into
Open
dblane-digicatapult wants to merge 11 commits into
dblane-digicatapult wants to merge 11 commits into
Conversation
Canary for digicatapult/shared-workflows#122. Switches this repo from bumping the version on the pull request branch to applying it on main after merge, which is what makes a GitHub merge queue usable here. - Remove the synchronise-pr-version / synchronise-trunk-version callers. They commit a version onto the PR branch, which dismisses approval and evicts the PR from the queue. Both reusable workflows remain available in shared-workflows for repos not adopting a queue. - Remove the check-version job from test.yml. It asserts package.json is ahead of the last release, which two approved PRs cannot both satisfy. - Add version-label.yml, which gates a PR on carrying exactly one v: label. Own file because it needs labeled/unlabeled triggers, which would otherwise re-run the whole suite on every label change. - Add apply-version.yml, which computes and commits the version on main after merge. - Add the merge_group trigger to test.yml. A required check that never reports on the queue branch leaves the queue waiting indefinitely. - Guard every release.yml job so the release runs on the version commit rather than the merge commit, since build-docker, generate-sbom and release-github all read the version from the checked out tree. Changed shared workflows are pinned to @merge-queue-versioning and must be flipped to @main once that PR merges. release.yml's migration-checks were pinned to the stale @ENG-313-migration-checks and are repointed here too.
This was referenced Aug 1, 2026
Merged
Merged
6 tasks
Without this every Renovate PR would fail the new require-version-label gate, since the shared renovate config applies no v: labels, and Renovate's bumpVersion would keep writing a version onto the PR branch, reintroducing the exact collision the merge queue model removes. The overlay is pinned to the merge-queue-preset branch of renovate-config and must be flipped to the default branch once digicatapult/renovate-config#1191 merges.
Replaces the dependency on an unmerged renovate-config preset branch. Proving the overrides here first avoids landing an untested preset org-wide; once the model is demonstrated end to end they can be promoted to a shared preset. Same four overrides, now self-contained: bumpVersion unset, v:patch added, platformAutomerge on, rebaseWhen conflicted. Validated with renovate-config-validator.
Picks up the fix that skips the GHAS SARIF upload on merge_group. Without it static-checks fails in the queue because the ephemeral queue ref is deleted before code scanning can attach the analysis, which would block every merge once lint and test are required checks.
tests-poetry still carried the branch in its job name, so its check name was 'Run tests - tests/unit - gh-readonly-queue/mq-demo/pr-32-<sha>'. That is unique per pull request and per merge attempt and can never be a required status check. Visible side by side with the fixed tests-npm in the queue run: https://github.com/digicatapult/hello-world/actions/runs/30699160605
Checked against the Renovate docs rather than assumption. conflicted was taken from a GitHub discussion, not the documentation. Renovate documents rebaseWhen=auto as rebasing when the repository requires up to date branches OR when automerge is enabled, so disabling rebasing entirely risks an automerging pull request sitting behind its base and never merging. That is a worse failure than the wasted CI it saves. automerging is purpose built for this: behind-base-branch behaviour for pull requests that are actually automerging, never for the rest. It cannot deadlock, and still removes the base preset's blanket rebasing from :rebaseStalePrs, which under a queue rebases every open PR whenever trunk moves and evicts anything already enqueued. Also documents why platformAutomerge is load bearing: merge queues are only supported when it is true, and automergeType=branch can never work behind one.
The comments had grown to explain the whole design in every file, and the renovate.json description was five paragraphs. Trimmed each to the non-obvious fact plus a pointer, and moved the rationale into a Merge queue section of the README where it can be read in one place.
build-docker's check-version defaults to failing when the version matches the latest release. Under merge queue versioning the branch carries no bump, so in steady state that would fail every PR. require-version-label is the gate now. release.yml keeps the default, since it runs on the bumped version commit. This repo would not have surfaced it either way: package.json is 2.0.0 against a latest release tag of v1.1.3, so the check was passing by accident.
9 tasks
| jobs: | ||
| apply-version: | ||
| if: ${{ !startsWith(github.event.head_commit.message, 'chore(release):') }} | ||
| uses: digicatapult/shared-workflows/.github/workflows/apply-version-npm.yml@merge-queue-versioning |
| static-checks-npm: | ||
| uses: digicatapult/shared-workflows/.github/workflows/static-checks-npm.yml@main | ||
| if: ${{ startsWith(github.event.head_commit.message, 'chore(release):') }} | ||
| uses: digicatapult/shared-workflows/.github/workflows/static-checks-npm.yml@merge-queue-versioning |
| tests-npm: | ||
| uses: digicatapult/shared-workflows/.github/workflows/tests-npm.yml@main | ||
| if: ${{ startsWith(github.event.head_commit.message, 'chore(release):') }} | ||
| uses: digicatapult/shared-workflows/.github/workflows/tests-npm.yml@merge-queue-versioning |
| uses: digicatapult/shared-workflows/.github/workflows/migration-checks-npm.yml@ENG-313-migration-checks | ||
| if: ${{ startsWith(github.event.head_commit.message, 'chore(release):') }} | ||
| uses: digicatapult/shared-workflows/.github/workflows/migration-checks-npm.yml@merge-queue-versioning | ||
| permissions: |
| uses: digicatapult/shared-workflows/.github/workflows/migration-checks-poetry.yml@ENG-313-migration-checks | ||
| if: ${{ startsWith(github.event.head_commit.message, 'chore(release):') }} | ||
| uses: digicatapult/shared-workflows/.github/workflows/migration-checks-poetry.yml@merge-queue-versioning | ||
| permissions: |
|
|
||
| migration-checks-npm: | ||
| uses: digicatapult/shared-workflows/.github/workflows/migration-checks-npm.yml@main | ||
| uses: digicatapult/shared-workflows/.github/workflows/migration-checks-npm.yml@merge-queue-versioning |
|
|
||
| migration-checks-poetry: | ||
| uses: digicatapult/shared-workflows/.github/workflows/migration-checks-poetry.yml@main | ||
| uses: digicatapult/shared-workflows/.github/workflows/migration-checks-poetry.yml@merge-queue-versioning |
|
|
||
| build-docker-npm: | ||
| uses: digicatapult/shared-workflows/.github/workflows/build-docker.yml@main | ||
| uses: digicatapult/shared-workflows/.github/workflows/build-docker.yml@merge-queue-versioning |
|
|
||
| build-docker-poetry: | ||
| uses: digicatapult/shared-workflows/.github/workflows/build-docker.yml@main | ||
| uses: digicatapult/shared-workflows/.github/workflows/build-docker.yml@merge-queue-versioning |
|
|
||
| jobs: | ||
| require-version-label: | ||
| uses: digicatapult/shared-workflows/.github/workflows/require-version-label.yml@merge-queue-versioning |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
Checklist
PR Type
Linked tickets
High level description
Canary adoption of the merge queue versioning model from digicatapult/shared-workflows#122. Moves this repository from bumping the version on the pull request branch to applying it on
mainafter merge.Detailed description
Removed
synchronise-pr-version-npm.ymlandsynchronise-trunk-version-npm.ymlcallers. These commit a version onto the branch, which dismisses approval and evicts the PR from a queue. Both reusable workflows remain inshared-workflowsfor repositories not adopting a queue.check-versionjob intest.yml. It assertspackage.jsonis ahead of the last release, which two approved PRs cannot both satisfy.The two models compete over the same
v:labels, so a repository uses one or the other.Added
version-label.yml, gating a PR on exactly onev:label. Its own file because it must trigger onlabeledandunlabeled, which intest.ymlwould re-run the whole suite on every label change.apply-version.yml, computing and committing the version onmainafter merge.renovate.json, holding the merge queue Renovate overrides inline.README.mdcarrying the rationale, so the workflow files stay terse.Changed
test.yml: addsmerge_group, and setsfail_on_same_version: falseon bothbuild-dockerjobs. Without that second change every PR would fail, because the branch deliberately carries no version bump andbuild-docker'scheck-versiondefaults to failing when the version matches the latest release.release.yml: every job guarded so the release runs on the version commit rather than the merge commit, sincebuild-docker,generate-sbomandrelease-githuball read the version from the checked-out tree.What a merge now looks like
apply-versioncomputes the bump from its label and pushes achore(release):commit.release.ymlis skipped.apply-versionis skipped by its guard.release.ymlruns and releases.Renovate
Four overrides, inline rather than in a shared preset so an untested preset does not land across every repository at once:
bumpVersion: nulladdLabels: ["v:patch"]v:labels, so every Renovate PR would fail the gate and never merge.platformAutomerge: truerebaseWhen: "automerging"behind-base-branchrebases every open PR whenevermainmoves, wasted CI under a queue and evicts anything enqueued.automerginglimits that to PRs actually automerging.Renovate's branch automerge (
automergeType: branch) can never work behind a merge queue. This repo usespr, so it is unaffected.Describe alternatives you've considered
Keeping both the per-PR bump callers and the new ones, selected by a variable. Rejected: both react to the same
v:labels, so the repo would bump twice. Coexistence belongs inshared-workflows, where both reusables remain, not in a single caller.Putting the Renovate overrides straight into a shared preset. Rejected for now: proving them here first avoids landing an untested preset org-wide.
rebaseWhen: "conflicted". An earlier revision of this PR used it, taken from a GitHub discussion rather than the documentation. Renovate documentsautoas rebasing when automerge is enabled, soconflictedrisks an automerging PR sitting behind its base and never merging.automergingcannot deadlock.Operational impact
Prerequisites that need repository admin, and this PR should not merge without them:
BOT_ID/BOT_KEYmust be added to the bypass list of the organisation ruleset protectingmain. It now pushes there rather than to feature branches. A repo-level ruleset cannot grant this, because rulesets are cumulative.Before merging: the six shared workflows pinned to
@merge-queue-versioning(migration-checks-npm/poetry,static-checks-npm/poetry,tests-npm/poetry, plusbuild-docker) must be flipped to@mainonce #122 lands.To revert: restore the two
synchronise-*callers and thecheck-versionjob, and drop the workflow changes. Nothing inshared-workflowsneeds reverting.Additional context
Verified in a real merge queue on a throwaway branch, so
mainwas never touched:v:patchmerged together,package.jsonunchanged at2.0.0throughout. PR 31's queue branch was built on PR 30's commit, confirming stacking.migration-checkswas refused entry to the queue.Known gaps:
renovate-config. That promotion must also covercargoandnuget, which carry the samebumpVersion: patchand are omitted here only because this repo has neither.generate-sbomon PRs now tags Dependency-Track with the current released version rather than the upcoming one, since the branch is not bumped. It usesfail_on_same_version: falseso nothing fails, but the tag is less useful.package.jsonis2.0.0against a latest release tag ofv1.1.3, so it is already ahead. That masked thebuild-dockersame-version failure, which was found by inspection rather than by CI here.