#77020active
cmd/go: add -buildversion build flag
新規提案
要約
AIによる要約であり、誤りを含む場合があります。
概要
go build でバイナリをビルドする際に、バージョン情報を debug.BuildInfo.Main.Version に埋め込むための -buildversion フラグを cmd/go に追加するプロポーザルです。パッケージマネージャーなど、バージョンを知っているビルドプロセスが、VCS情報なしでバイナリにバージョンを注入できるようにします。
ステータス変更
(新規) → active
2026年4月16日、@aclements(Goコアチーム)がこのプロポーザルをアクティブカラムに追加し、週次プロポーザルレビューミーティングの審議対象となりました。@mvdan が Go 1.27 のフリーズまで約7週間というタイミングでレビューを強く促したことが直接的な契機となっています。
技術的背景
現状の問題点
Go バイナリには debug.BuildInfo を通じてバージョン情報が埋め込まれますが、そのソースは限られています。
go install example.com/cli@v1.2.3— モジュールバージョンが埋め込まれる(動作する)git cloneしてからgo build— Go 1.24 で解決済み(#50603)、VCS タグからバージョンを埋め込めるようになった- パッケージマネージャーによるビルド — 未解決。Nix や Debian などのパッケージマネージャーはソースアーカイブ(
.tar.gz)からビルドするため.gitディレクトリが存在せず、バージョン情報が埋め込めない - ソースアーカイブからの
go build— 未解決
ケース3において、パッケージマネージャーはビルドするバージョンを知っているにもかかわらず、それをcmd/goに伝える手段がありません。現在の回避策は-ldflags='-X main.version=v1.2.3'のような方法ですが、これはアプリケーション固有の変数を対象とするものであり、標準のdebug.BuildInfo.Main.Versionには反映されません。
提案された解決策
-buildversion フラグの追加:
-buildversion version
The version of the main module being built. This overrides the version
derived from -buildvcs information. It is an error to use this flag with
"go install" with a version suffix. version must be a valid semver string
with a "v" prefix.
このフラグを使用することで debug.BuildInfo.Main.Version が指定したバージョンに設定されます。
これによって何ができるようになるか
標準的な方法でバイナリ自身がバージョンを取得できるようになります。ビルドプロセスがバージョンを知っている場面(パッケージマネージャー、CI/CD パイプライン、Docker ビルドなど)で -buildvcs=false になる環境でもバージョンが埋め込まれます。
コード例
// Before: -ldflags を使った従来のワークアラウンド(ビルド側)
// go build -ldflags="-X main.version=v1.2.3" ./cmd/myapp
// アプリ固有の変数にしか反映されず、debug.BuildInfo.Main.Version は "(devel)" のまま
var version = "(devel)" // アプリ側でも変数を用意する必要がある
func printVersion() {
fmt.Println(version) // ldflags で注入された値
}
// After: -buildversion を使った新しい方法(ビルド側)
// go build -buildversion=v1.2.3 ./cmd/myapp
// debug.BuildInfo.Main.Version に v1.2.3 が反映される
func printVersion() {
info, ok := debug.ReadBuildInfo()
if !ok {
panic("build info unavailable")
}
fmt.Println(info.Main.Version) // v1.2.3
}
議論のハイライト
- @ianlancetaylor はドキュメントに
Buildinfo.Main.Versionを設定するという効果を明記すべきと指摘。また、main パッケージ以外でのビルド時にエラーにすべきか質問した。提案者 @FiloSottile はメインモジュールのバージョンは main パッケージに限らない概念なので不要と返答。 - @seankhliao は単一のバージョン文字列だけでなく、モジュールプロキシが使う
.infoファイル(JSON形式でコミットハッシュやタイムスタンプを含む)をパスとして渡せるよう-buildvcsを拡張することを提案。Dockerビルドで.gitを.dockerignoreに入れるケースで有用と指摘。 - @mvdan は
.infoファイルアプローチに同意しつつ、govcs.infoのような決まったファイル名が存在すれば自動的に読み込まれる仕組みが望ましいと主張。フラグを指定しなくても動作するため、ソースアーカイブに含めるだけでバージョン情報が保持できると説明。この考えに基づく実装CL(go.dev/cl/762920:cmd/go: read vcs info from a .info file)も投稿されている。 - @stapelberg は Nix パッケージマネージャーにおいて VCS スタンピングのために git の挙動を模倣する複雑な回避策(
.git/HEADの合成と偽のgitコマンドのインジェクション)を実装していることを紹介し、標準的な解決策の必要性を訴えた。 - 議論は単純な
-buildversionフラグから.infoファイルを使うより豊富なメタデータの受け渡しへと発展しており、最終的な API 設計はまだ確定していない。