Skip to content

Resolve the formatter in a temp project, not the runner's shared depot - #29

Merged
sotashimozono merged 1 commit into
mainfrom
pin-formatter
Sep 13, 2026
Merged

sotashimozono merged 1 commit into
mainfrom
pin-formatter

Conversation

@sotashimozono

@sotashimozono sotashimozono commented Sep 13, 2026

Copy link
Copy Markdown
Member

Pkg.add(name="JuliaFormatter", version="2") ran with no active project, so it
resolved into whatever environment the runner happened to have. The compat
bounds already sitting in that depot cap the resolve, which makes the installed
version a property of the machine rather than of this file: the same commit
resolved 2.3.2 on a self-hosted runner and 2.10.1 on a GitHub-hosted one.
Formatting differs across 2.x minors, so format-check returned a verdict on the
runner, not on the diff. A leftover ITensorFormatter in a shared depot also
pinned JuliaSyntax to 0.4 and turned the install into a hard resolve failure,
which presents as a flake because it depends on which runner you land on.

Pkg.activate(; temp=true) before the add is the fix, and the install and the
check are now one process so the environment cannot expire between them.

The version still floats, deliberately. A pin converts each new release into
permanent debt in every calling repo and rots while the ecosystem moves; the
answer to a release that reflows files is to adopt it and reformat. Isolation
is what this check needed to be reproducible, and it is orthogonal to the
version spec.

Added an assertion that the loaded version is the one the temp project holds.
using silently falls back to the depot's default environment when the active
project does not declare the package, which has bitten this fleet twice through
an env that looked right by its name.

The failure message now names the version CI resolved and gives the same
floating spec in a temp env, with overwrite=true and a retry loop, since
overwrite=false is a check rather than a fix and one pass does not always
converge.

Runs the script through shell: julia --color=yes {0} rather than julia -e,
which is how lab-sotashimozono/.github has run this check for months. The
failure message has to contain a Julia command with its own quotes, and that
does not survive nesting inside -e '...'. The two orgs' scripts are now
byte-identical, so a fix to one is a copy-paste to the other.

Verified locally on both arms rather than by CI round trip: a formatted tree
exits 0 with the success line, a misformatted one exits 1 with the message.
The YAML and the embedded script both parse.

Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com

QAtlasHub/QAtlas.jl#795 tracks the remaining caller: its inline FormatCheck.yml pins 2.12.3 and should migrate here. Seven repos call this workflow today (AbstractQAtlas.jl, ExperimentalAPI.jl, SweepRunner.jl, TestShards.jl, DataVault.jl, ParamIO.jl, templateHPC.jl) and all resolve 2.14.0, so this changes where the formatter is installed, not which one runs.

@sotashimozono sotashimozono changed the title Pin the formatter, since seven repos were floating on it together Resolve the formatter in a temp project, not the runner's shared depot Sep 13, 2026
`Pkg.add(name="JuliaFormatter", version="2")` ran with no active project, so it
resolved into whatever environment the runner happened to have. The compat
bounds already sitting in that depot cap the resolve, which makes the installed
version a property of the machine rather than of this file: the same commit
resolved 2.3.2 on a self-hosted runner and 2.10.1 on a GitHub-hosted one.
Formatting differs across 2.x minors, so format-check returned a verdict on the
runner, not on the diff. A leftover ITensorFormatter in a shared depot also
pinned JuliaSyntax to 0.4 and turned the install into a hard resolve failure,
which presents as a flake because it depends on which runner you land on.

`Pkg.activate(; temp=true)` before the add is the fix, and the install and the
check are now one process so the environment cannot expire between them.

The version still floats, deliberately. A pin converts each new release into
permanent debt in every calling repo and rots while the ecosystem moves; the
answer to a release that reflows files is to adopt it and reformat. Isolation
is what this check needed to be reproducible, and it is orthogonal to the
version spec.

Added an assertion that the loaded version is the one the temp project holds.
`using` silently falls back to the depot's default environment when the active
project does not declare the package, which has bitten this fleet twice through
an env that looked right by its name.

The failure message now names the version CI resolved and gives the same
floating spec in a temp env, with `overwrite=true` and a retry loop, since
`overwrite=false` is a check rather than a fix and one pass does not always
converge.

Runs the script through `shell: julia --color=yes {0}` rather than `julia -e`,
which is how lab-sotashimozono/.github has run this check for months. The
failure message has to contain a Julia command with its own quotes, and that
does not survive nesting inside `-e '...'`. The two orgs' scripts are now
byte-identical, so a fix to one is a copy-paste to the other.

Verified locally on both arms rather than by CI round trip: a formatted tree
exits 0 with the success line, a misformatted one exits 1 with the message.
The YAML and the embedded script both parse.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sotashimozono
sotashimozono merged commit 05552d8 into main Sep 13, 2026
1 check passed
@sotashimozono
sotashimozono deleted the pin-formatter branch September 13, 2026 13:54
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