Repository navigation
chore: pin the Go toolchain via .go-version and GOTOOLCHAIN - #21
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0ffa770de5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| # go.mod の `go` ディレクティブは下限でしかないため、ローカルに新しい Go があると | ||
| # 黙ってそちらが使われ、正常な再ビルド出力と見分けのつかない差分が出る(stale ゲートが落ちる)。 | ||
| # 指定版が無ければ Go が自動ダウンロードするので、開発者側の事前準備は不要。 | ||
| GOTOOLCHAIN="go$(cat .go-version)" |
There was a problem hiding this comment.
Strip CR from the shell toolchain version
On Windows Git Bash with core.autocrlf=true, .go-version is checked out with CRLF because the repository has no .gitattributes rule for it. Command substitution removes the trailing LF but retains CR, so this exports GOTOOLCHAIN=go1.26.5\r; Go then exits with invalid GOTOOLCHAIN before any build. Since build.sh explicitly supports Git Bash, strip the CR/whitespace while reading the version or force .go-version to LF.
AGENTS.md reference: AGENTS.md:L82-L82
Useful? React with 👍 / 👎.
|
P2「Strip CR from the shell toolchain version」に対応しました( 2層で防いでいます。
検証: |
The deterministic rebuild gate requires a bit-identical build, which requires the exact Go patch version. That requirement was only stated in comments, and nothing enforced it: go.mod's `go 1.26.5` is a lower bound and GOTOOLCHAIN defaults to `auto`, so a newer local toolchain is used silently. Running ./build.sh with go1.27.1 produced 18 modified binaries that are indistinguishable from a legitimate rebuild. - Add .go-version as the single definition of the pinned patch version. - build.sh exports GOTOOLCHAIN from it, before the line that echoes `go version`, so the printed version is proof the pin took effect. Go downloads the toolchain on demand, so no developer setup is needed. - build.ps1 does the same, saving and restoring $env:GOTOOLCHAIN in the existing finally block so it does not leak into the caller's session. - CI reads the same file via setup-go's go-version-file, replacing the duplicated GO_VERSION env, and .go-version joins the paths triggers so the gate covers its own inputs. - Point the docs at .go-version instead of repeating the number. Binary-neutral: a full ./build.sh leaves all 21 committed binaries unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
build.sh supports Git Bash and WSL, but the repo had no .gitattributes, so with core.autocrlf=true `.go-version` is checked out as CRLF. Command substitution strips the LF and keeps the CR, so build.sh exported `GOTOOLCHAIN=go1.26.5\r` and Go exited with `invalid GOTOOLCHAIN "go1.26.5\r"` before building anything. Reproduced locally. Defend at both layers: - Add .gitattributes pinning .go-version and the shell scripts (build.sh, build.ps1, and the extensionless OS-dispatchers) to LF, and marking the committed native binaries as binary so nothing ever rewrites the bytes the bit-identical gate compares. - build.sh strips whitespace when reading the file, which also rescues clones that already have CRLF on disk. build.ps1 was already safe: it reads the file with .Trim(). Verified: ./build.sh still reports [go1.26.5] with the file written as CRLF and as LF, and adding .gitattributes renormalizes nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
087a0d9 to
eac1b18
Compare
なぜ
stale 検出ゲートは「再ビルド →
git diff --exit-code」なので bit-identical が必要で、そのために Go のパッチ版一致が要る(LESSONS #26 の実測)。ところがその要件はコメントに書いてあるだけで、何も強制していなかった。go.modのgo 1.26.5は下限であってダウングレードは強制できないGOTOOLCHAINの既定はauto= ローカルが 1.26.5 以上なら黙ってそちらが使われる結果、ローカル go1.27.1 で
./build.shを回すと 18 バイナリが差分として出る。しかもそれは正常な再ビルド出力と見分けがつかない。PR #20 で Codex が P1「バイナリが stale」を指摘した原因もこれ。何をしたか
.go-version(1.26.5)を追加。パッチ版の定義箇所をここ1つに集約。build.shがexport GOTOOLCHAIN=go$(cat .go-version)で強制。go versionを echo する行より前に置いたので、表示される版がそのまま「固定が効いた証拠」になる。未取得なら Go が自動ダウンロードするため開発者の事前準備は不要。build.ps1も同様。ただし$env:は呼び出し元セッションを汚染するため(LESSONS #43)、既存の退避/finally復元ブロックにGOTOOLCHAINを追加。go version表示より先に設定するので、表示と実ビルドの版がずれない。go-version-file: .go-version(7ジョブ)に変更し、重複していたGO_VERSIONenv を削除。pathsトリガにも.go-versionを追加(ゲートが自身の入力を守る。LESSONS #27)。.go-versionへの参照に置換。検証
./build.shを環境変数なしで実行し[go1.26.5]と表示されること、リポジトリ外の CWD から実行しても動くこと(cdを先頭へ移動した回帰)を確認。sh -n build.sh/ pwsh パーサでの構文チェック済み。補足
バージョンを 1.26.5 のまま据え置いています。現在 1.26.5 には到達可能な stdlib 脆弱性が3件(GO-2026-6218 / 6090 / 5972、いずれも 1.26.6 で修正済み、最新パッチは 1.26.8)あり、CI はこれを
::warning::で握り潰しています。版の引き上げは全21バイナリの再ビルドを伴い PR #20 と競合するため、#20 のマージ後に別 PR で行います。🤖 Generated with Claude Code