go.modのgo directiveとtoolchain directive

#golang

go.modのgo directiveは「このモジュールをビルドするのに必要なGoの最小バージョン」を宣言するもの。一方toolchain directiveは「開発時に実際に使うツールチェーンのバージョン」を指定するもので、両者は役割が違う。

go 1.24.0
toolchain go1.25.5

go directiveを最新にしてしまうと何が起きるか

前提として、Goは半年ごとにメジャーリリースされ(例: 2025年は1.24と1.25)、公式サポートは新しい2つのメジャーリリースのみ(詳細はGoのリリースサイクルとサポートポリシー)。

ライブラリやツールのgo.modでgo directiveを最新メジャーリリース(例: go 1.25.5)にしてしまうと:

  • 1つ前のメジャーリリース(まだ公式サポート内)を使っているユーザーがそのモジュールをビルドできなくなる。
  • go directiveの要求は依存元にも伝播する。あるライブラリがgo 1.25.5を宣言すると、それに依存するモジュールもGo 1.24をサポートできなくなる。
  • Go 1.24で入ったtool directive経由のツール依存でも同じことが起きる(arthur-1氏の記事ではGoReleaserが例に挙げられている)。

推奨される書き方(OSSのライブラリ・ツールの場合)

  • go directiveは1つ前のメジャーリリースにする。最新が1.25ならgo 1.24.0
  • パッチバージョンは.0にする。パッチを上げて宣言すると、ユーザー側がマイナーアップデートでバグ対応する余地を狭めるため。
  • 開発で最新の言語機能やツールチェーンを使いたい場合はtoolchain directiveで別途指定する。これでビルドの下限(go directive)と実際に使うツールチェーンを分離でき、GitHub Actionsのsetup-goなどでも正しいバージョンが使われる。
  • デメリットは「最新メジャーリリースで入った言語機能をライブラリ本体のコードですぐ使えない」ことだが、半年後の次リリースで使えるようになる。

Go 1.26からはgo mod initが生成するgo directiveのデフォルトが1つ前のメジャーリリースになる予定で、Goチーム自身もこの方針を推奨しているとのこと。

Goの開発ツーリングの中での位置づけ

モジュール管理系。リリースポリシーを前提に、ライブラリのgo.modをどう書くべきかという方針の話。

出典

作成日時: 2026-08-15 06:48 / 更新日時: 2026-08-15 07:06