fix(ci): enable git long paths on Windows runners before checkout - #39
Merged
Conversation
The GitHub-hosted Windows images ship git 2.55.0.windows.5 with
core.longpaths unset, so actions/checkout aborts with "Filename too
long" on any repo containing a path that, once prefixed with the
runner's D:\a\<repo>\<repo>\ workspace root, crosses the 260-character
MAX_PATH limit. The failure lands in step 2, before any toolchain setup,
so a caller's Windows matrix shards can never start — and a caller has
no lever of its own, because build-and-test invokes actions/checkout
with no `with:` block.
csharp-ci.yaml and scala-ci.yaml now run `git config --system
core.longpaths true` on Windows immediately before that checkout. It has
to be --system: actions/checkout temporarily overrides HOME before
making its own global git config changes, so a --global value written by
an earlier step is not read during the checkout itself.
The step is pinned to `working-directory: ${{ github.workspace }}`
because the job-level `defaults.run.working-directory` points at the
caller's `working-directory` input, which does not exist yet before
checkout — the same pin the `pack` job's `Validate inputs` step already
uses for the same reason.
Only these two workflows expose an OS matrix that can place a shard on a
Windows runner. go-ci.yaml, terraform-ci.yaml and build-and-test.yaml
take a single `runs-on` that resolves to ubuntu-latest or the
self-hosted Linux pool, and every remaining checkout in the repo sits in
a job hard-pinned to ubuntu-latest, so none of them are reachable on
Windows.
Claude-Session: https://claude.ai/code/session_01GTo7LMjhYTY3u5NhakUZeb
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.
The problem
Both Windows shards (
windows-amd64,windows-arm64) of a consuming repository'sbuild-and-testmatrix die inactions/checkoutat step 2, beforeSetup .NETever runs:The offending paths were 202-212 characters; plus the runner's
D:\a\<repo>\<repo>\workspace prefix (~62 chars), they cross the 260-character WindowsMAX_PATHlimit.core.longpathsis not enabled on the GitHub-hosted Windows image — the failing log showsgit version 2.55.0.windows.5.The consuming repo has no lever of its own. In
csharp-ci.yamlthebuild-and-testjob callsactions/checkoutbare, with nowith:block, so a caller can reach neithersparse-checkoutnor any pre-config hook. The fix has to live here.Generated-code trees hit this easily: the path depth is derived from source namespaces, so it grows on its own and no single repo can shorten its way out permanently.
The change
A single step in the
build-and-testjob ofcsharp-ci.yamlandscala-ci.yaml, immediately before the consumer-repo checkout:Why
--systemand not--globalactions/checkouttemporarily reassignsHOMEbefore making its own global git config changes, so a--globalvalue written by an earlier step is simply not in the configHOMEthat the checkout reads. This is visible in the failing run's own log, immediately after the git version banner and before the fetch:--systemwrites outsideHOMEand therefore survives the override. On the GitHub-hosted Windows images the runner account is an administrator, so the write succeeds.Why
working-directory: ${{ github.workspace }}Both
build-and-testjobs set a job-leveldefaults.run.working-directory: ${{ inputs.working-directory }}. This new step runs before checkout, when that subdirectory does not exist yet — so for any caller passing a non-rootworking-directorythe step would fail outright. That combination is real: a caller invokingscala-ci.yamlwith a non-rootworking-directoryand a Windows shard would have seen the scala half of this fix dead on arrival.This mirrors the existing pin on the
packjob'sValidate inputsstep, which is pre-checkout for the same reason, and follows #28's precedent.Sweep: what changed and what did not
.github/workflows/csharp-ci.yamlbuild-and-testisruns-on: ${{ matrix.runner }};os-list/build-matrixboth documentwindows-latest.github/workflows/scala-ci.yaml.github/workflows/go-ci.yamlbuild-and-testandlinttake the singleruns-oninput, documented asubuntu-latestor the self-hosted Linux pool; no OS matrix.github/workflows/terraform-ci.yamlruns-onshape.github/workflows/build-and-test.yamlruns-onshape; this repo's own self-test (actionlint + bash + python).github/workflows/csharp-publish-public.yamlpublishis hard-pinnedruns-on: ubuntu-latest.github/workflows/update-badges.yamlubuntu-latestWithin the two changed files, the other checkouts (
normalize,coverage-output,matrix-output,matrix-comment,pack) are all in jobs hard-pinned toubuntu-latestand need nothing. TheCheckout CI helpersstep insidebuild-and-testruns on the same Windows runner but after the new step, so the--systemsetting already covers it.Verification
actionlint(the repo's ownLint workflow filesgate, v1.7.7 contract) — clean, exit 0.python3 -m unittest discover -s test -p '*_test.py'— 62 tests, OK.yaml.safe_loadon both edited files — parses.Not yet exercised on a real Windows runner; that happens when a consumer picks up the moved tag (see below).
Required follow-up for the maintainer
Merging this ships nothing.
v2is a floating tag and every consumer pins@v2. PerCONTRIBUTING.md's release process, the tag has to be moved after merge before any caller sees the fix:Until
v2moves, affected Windows shards keep failing identically.