ci: Bulk Migration — replay bulk migrations onto an open PR - #8662
Open
keithharvey wants to merge 1 commit into
Open
ci: Bulk Migration — replay bulk migrations onto an open PR#8662keithharvey wants to merge 1 commit into
keithharvey wants to merge 1 commit into
Conversation
keithharvey
force-pushed
the
gh-migrate-action-env
branch
3 times, most recently
from
August 6, 2026 21:08
390a156 to
d735bb8
Compare
keithharvey
force-pushed
the
gh-migrate-action-env
branch
from
August 6, 2026 21:13
d735bb8 to
cbc1de6
Compare
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
keithharvey
force-pushed
the
gh-migrate-action-env
branch
from
August 6, 2026 21:41
cbc1de6 to
2ae6108
Compare
10 tasks
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.
Part of #7408.
A repo-wide mechanical change rewrites lines that in-flight branches also touch, so every open PR conflicts with
masteruntil it is replayed through the same transforms. The transforms are deterministic and idempotent — run them on both sides and the mechanical conflicts cancel out, leaving only genuine ones.Contributors can already do that themselves in three lines. This adds the other half: a maintainer runs this workflow on a PR and the same three lines run in CI, on the same BAR-Devtools code path, and the result is pushed back.
Nobody has to install anything to stay current, and nobody gets marooned on a branch that can no longer be merged.
Usage
From the Actions tab, or:
By default it replays every migration BAR-Devtools still lists, oldest first, so a branch that predates several catches up on all of them in one pass — migrations the branch already has produce nothing and are skipped. The optional
migrationinput narrows it to one:Dispatch is the whole trigger surface, and that is the intended shape for now. A
/migratePR-comment trigger is the obvious next step, and deliberately not in this PR: it would fire on all ~155 comments/week this repo gets, and it is easy to add once someone actually wants it.Trying it before the dependencies land
Three further inputs —
devtools_repo,devtools_ref,image— default to the canonical values and exist so the whole path can be exercised against a fork first. Normal use leaves them alone. Pointed at the fork this was verified on — both images are public and the workflow is on that fork'smaster, so this runs as-is:Two things to know if you do.
workflow_dispatchonly registers a workflow that is on the repository's default branch, so this file has to be on your fork'smasterbefore it can be dispatched at all — being manual-trigger only, it is inert sitting there. Anddevtools_refcan be the working branch: the images live in GHCR independently of any branch, so publishing them does not commit you to keeping the recipes onmaster.Once this is on
masterbut BAR-Devtools#57 is not, dispatch moves here — real PR numbers, no--ref— and only the BAR-Devtools half stays overridden:The migration list is not maintained here
It is read from BAR-Devtools at run time:
just/bar-migrate.justalready declares migrations in adoption order and retires them by marking them[private], which drops them from--list. So that command is "every migration still worth replaying, oldest first" — there is no second copy of the list in this repo to drift out of step.This also settles the security question. A name from a PR comment is only ever compared against that list, never passed through, so a
[private]recipe such asstylua-cleanup-generate(which would regenerate the whole branch stack) cannot be reached from a comment.When the merge conflicts
It bails without pushing. Both sides have been through the same deterministic transforms at that point, so whatever still conflicts is a real disagreement with
master— not something a replay can settle. The job fails, and the PR comment lists the conflicted paths.Pushing to forks
GITHUB_TOKENis scoped to this repository and cannot push to a fork, even when the PR has Allow edits by maintainers enabled. So:migrate/pr-<N>here; the comment gives the author a one-linegit pull.No secrets, nothing to provision. A PAT could make the fork case push directly too, but that needs both the token and the PR's Allow edits by maintainers box, and silently falls back to the second row when either is missing — not worth the branch until the fork friction actually proves painful.
The toolchain is not restated here either
The job runs in
ghcr.io/beyond-all-reason/bar-migration:latest— BAR-Devtools' own dev image, built from thedocker/dev.Containerfilethat is already the canonical dependency list for local development, plus a prebuilt copy of the codemod binary.This matters more than it looks. StyLua's output is version-specific: a workflow that assembled its own toolchain would eventually format lines
master's own run did not, and that is precisely when the mechanical conflicts stop cancelling out and the whole premise fails. Sharing the image makes that impossible rather than merely unlikely — there is no version number in this file to drift.Recipes are not baked into the image; they are checked out at
devtools_refon every run. So a change tobar::migrate::*takes effect on the next dispatch with no image rebuild, while the codemod binary — which is baked — is rebuilt and republished automatically when its source changes.Both images are published by a new
dev-imageworkflow on the BAR-Devtools side. They must be public for this job to pull them without credentials.Verified
Replayed end to end onto a throwaway PR, in that image, with no install steps: 8,648 bracket-to-dot conversions, StyLua across the tree, one commit pushed to the PR head, and the summary comment posted. Run against fork-published copies of both images, via the override inputs above.
The image's prebuilt codemod is picked up rather than rebuilt.
CODEMOD_BINshort-circuitsrequire-codemod, so the ~2.5 min cargo build an earlier revision of this workflow paid on every run does not happen — confirmed by the absence of any cargo output in the run log, with the three transforms starting about a second apart.Also checked: every tool the job needs is present in the image (
gh,jq,just,cargo,stylua2.0.2,lx0.28.3,lua,git), and the recipes do not try to re-exec themselves into a distrobox when_DEVTOOLS_IN_DISTROBOXis set.Merge ordering
Independent of the type-cleanup stack and safe to merge first — which is the point, since it is the answer to "what happens to in-flight branches when the reformat lands".
It needs BAR-Devtools#57 on BAR-Devtools master for both the
bar::migraterecipes and the published images, and it needs a migration on this repo'smasterto have something to replay. It is manual-trigger only, so merging it before either of those is inert rather than wrong.LLM Disclosure
Opus 5 on this one. It did a far better job on the description than I ever would've done after I slogged through the action myself, so I largely left it after some tweaks.