gradle-wrapper-upgrade について
既存の Gradle Wrapper をアップグレードする手順を案内するスキルです。事前確認から検証、ロールバックまでを扱い、生成ファイルに対象 Gradle のテンプレートを使うため、wrapper タスクを2回実行する点を重視します。
主な機能
- 01既存 Wrapper のバージョンと種類の確認
- 02対象バージョンと対応するチェックサムの指定
- 03wrapper タスクの2回実行
- 04生成ファイルとビルド設定の検証
- 05スナップショットを使ったロールバック手順
活用シーン
- 01指定した Gradle バージョンへのプロジェクト更新
- 02バージョン未指定時の最新リリース選択
- 03途中で止まった Wrapper 更新の調査
- 04更新後にビルドが失敗した際の Wrapper ファイル復元
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ gradle/ gradle-skills --skill gradle-wrapper-upgradeインストール後、Claude Code で/gradle-wrapper-upgradeを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
metadata.jsonreferences/rollback.mdsnapshot.md詳細
Gradle Wrapper のアップグレード
2 つのモード — ユーザーの動詞に合わせる
まず、どちらに該当するかを判断してください。以下のすべては、その判断に応じて実行します。
- 「wrapper をアップグレードして」「Gradle を 8.14.4 に上げて」 → 実行します。手順を進め、検証し、結果を報告してください。
- 「wrapper はどうやってアップグレードしますか?」 → コマンドを提示し、2 回実行する必要があるという注意点を伝えたら、そこで止めてください。「どうやって」という質問には回答し、実行はしません。最初に「wrapper をアップグレードします」と伝えていた場合も同様です。コマンドを伝え、実行はしないでください。
本当に曖昧な場合は、コマンドを提示してください。
以下の手順は、どちらのモードでも同じ内容です。実行モードでは手順を実行し、回答モードでは提示します。ただし、スナップショットは例外です。回答時には、Step 3 のコピーと Step 5 の diff および削除は省いてください。これらはエージェントが自分の作業を取り消せるようにするためのものであり、ユーザーには独自のバージョン管理があります。また、cd "<build-root>" && のプレフィックスも削除してください。ユーザーはビルドルートからコマンドを実行します。
アップグレードするには、組み込みの wrapper タスクを実行します。ファイルを手動で編集してはいけません。gradlew、gradlew.bat、gradle-wrapper.jar は生成ファイルであり、次回 wrapper を実行すると、編集内容は警告なしに元に戻ります。対象範囲: すでに存在する wrapper に限ります。wrapper のないビルドに追加するのは別の作業です(システムにインストールされた Gradle から gradle :wrapper を実行します)。
このファイルと同じ場所に 2 つのリファレンスがあります。references/snapshot.md(Step 3 — 各アップグレード前に wrapper を保護する)と、references/rollback.md(Step 6 — ビルドで受け入れられないアップグレードを元に戻す。ほとんどのアップグレードでは該当しない分岐です)です。手順で指示された場合に限り、どちらかを開いてください。
Step 1 — 状況を確認する
ビルドルートを見つけてください。ビルドルートとは、gradle/wrapper/gradle-wrapper.properties があるディレクトリで、通常は gradlew と同じ場所にあります。そのファイルから distributionUrl を読み取ります。これには必要な 2 つの情報が含まれています。現在のバージョン(gradle-8.14-bin.zip → 8.14)と、ディストリビューションの種類(-bin または -all)です。
ビルドルートの絶対パスを控えてください(そのディレクトリで pwd を実行します)。以下のすべてのコマンドで "<build-root>" として使います。./gradlew の実行、各スナップショット、検証、復元、削除もすべて対象です。これにより、シェルがどのディレクトリにいても、このビルドに対して操作できます。1 つのリポジトリに複数のビルドがあり、それぞれに独自の wrapper がある場合もあります。
実行モードでは POSIX シェルが必要です。macOS、Linux、または Windows 上の WSL か Git Bash を使用してください。スナップショット、検証、ロールバックでは POSIX コマンドを使います。ネイティブの cmd または PowerShell ではアップグレードを実行せず、これらを Copy-Item や Remove-Item に置き換えないでください。回答モードと同じようにコマンドを提示し、WSL または Git Bash が必要であることを伝えてください。
以下のコマンドは ./gradlew を使います。Windows の cmd で手動実行する場合は gradlew.bat、PowerShell では .\gradlew を使います。オプションは同じです。
ステップ 2 — 対象バージョンとチェックサムを固定する
ユーザーが指定したバージョンを使用します。指定がない場合は、最新リリースを具体的なバージョンに解決してアップグレードします:
curl -s https://services.gradle.org/versions/current # → version + checksumUrl
対象バージョンが現在のバージョンと同じでも、手順は実行してください。 ボットや手作業でタスクとは無関係に distributionUrl が更新され、スクリプトや jar が古いままになっている可能性があります(このページの最後を参照してください)。2 回実行すれば再生成されます。固定する前にバージョンを解決してください。--gradle-version=latest のチェックサムは検索できません。チェックサムの固定は、追加作業ではなく、すべてのアップグレードで標準的に行うものです。ダウンロードを検証するために必要です。
チェックサムは、配布 URL の末尾に .sha256 を付けたものです。検索に必要なのはこの 1 行だけです:
curl -sL https://services.gradle.org/distributions/gradle-9.0.0-bin.zip.sha256
.sha256 を使用し、.sha256sum は使わないでください。後者はすべてのバージョンで 404 になり、まるでリリースが存在しないかのように見えます。-L は必須です。URL は 301 で downloads.gradle.org にリダイレクトされますが、-f は 4xx と 5xx でしか失敗しないため、リダイレクトに従わないと HTML が返されます。本文には 16 進数のチェックサムだけが含まれます。本当に 404 になった場合は、上の JSON にある checksumUrl、または https://gradle.org/release-checksums/ を確認してください。推測した別の URL は使わないでください。
チェックサムが distributionUrl に指定された zip と一致することを確認してください。 各リリースでは、-bin zip、-all zip、wrapper JAR それぞれに対して個別のチェックサムが公開されています。間違ったものを使うと Verification of Gradle distribution failed! が発生します。これは通常、コピー&ペーストの間違いなのに、ダウンロードが改ざんされたように見えてしまいます。
distributionSha256Sum を設定した後に、--gradle-version を変更する wrapper を実行する場合は、新しいバージョンに一致するチェックサムを渡す必要があります。渡さない場合、古いチェックサムが再利用されることはなく、ビルドが失敗します。バージョンが変わらなければ、チェックサムは自動的に保持されます。
ステップ 3 — ビルドの基準状態を確認し、wrapper を保護する
まず、変更を加える前にビルドが動作することを確認します:
cd "<build-root>" && ./gradlew --console=plain tasks
終了コードを記録してください。これがカナリアであり、ステップ 5 と 6 でも再実行します。アップグレード後にカナリアが失敗しても、アップグレード前から失敗していたなら何も意味しません。
build ではなく tasks を使います。 tasks はすべてのプラグインを適用し、すべてのタスクを登録します。これは新しいメジャーバージョンで問題が起きる可能性のある範囲そのものであり、コンパイルも実行も行わないため高速で、アップグレードが原因の問題だけで失敗します。build は不安定なテストや接続できないリポジトリでも失敗するため、それを理由にロールバックすると、問題のないアップグレードまで元に戻してしまいます。
ビルドで org.gradle.configuration-on-demand=true が設定されている場合は、代わりに tasks --all を使用してください。通常の tasks ではビルドのルートしか設定されず、それ以外はほとんど設定されないため、ビルドの別の部分に問題があっても成功してしまいます。どちらを選んでも、以降も毎回、同じコマンドを使用してください。アップグレード前に tasks、後に tasks --all を実行しても比較にはなりません。
ここでカナリアが失敗したら、作業を止めてアップグレードしないでください。 :wrapper もビルドを設定するため、ステップ 4 も同じ理由で失敗します。設定できないビルドをアップグレードするサポートされた方法はありません。何が問題だったかを報告してください。まず、現在のバージョンでビルドを成功させることが先決です。
その後、references/snapshot.md を読み、ビルドから wrapper ファイルをコピーして退避してください。Git 管理下にあるかどうかにかかわらず、アップグレードのたびに実施します。省略しないでください。スナップショットがなければロールバックできず、ステップ 6 ではスナップショットがあることを前提としています。
ステップ 4 — wrapper タスクを 2 回実行する
cd "<build-root>" && ./gradlew --console=plain :wrapper --gradle-version=8.14.4 --gradle-distribution-sha256-sum=<sha256>
cd "<build-root>" && ./gradlew --console=plain :wrapper --gradle-version=8.14.4 --gradle-distribution-sha256-sum=<sha256>
同じコマンドを 2 回実行します。1 回目は古い Gradle のテンプレートからスクリプトと jar を再生成し、2 回目は新しいバージョンのテンプレートから再生成します。どちらも必要です。詳しくは以下を参照してください。先頭の : は、タスクが存在する唯一の場所であるビルドルートでタスクを実行します。
アップグレードによってディストリビューションの種類が変わることはありません。 ステップ 1 の -all.zip に対しては、両方の実行に --distribution-type=all を追加してください。タスクのデフォルトは bin なので、そうしないとビルドが気付かないうちに切り替わってしまいます。種類を変更するかどうかはユーザーが決めることであり、アップグレードの副作用ではありません。
エージェントとして実行する場合:
- 終了コードを信頼してください。
BUILD SUCCESSFULを grep してはいけません。 チェックサムの検証失敗を、アップグレード成功と判定してはなりません。どちらかの実行がゼロ以外の終了コードを返した場合は、3 回目を試すのではなく、ステップ 6 に進んでください。 - ダウンロードに時間がかかることを想定してください。 2 回目の実行ではディストリビューション全体(100 MB 以上)を取得するため、数分かかる場合があります。タイムアウトを 10 分以上に設定するか、バックグラウンドで実行して終了を待ってください。長時間出力がないのは正常で、ハングではありません。途中で中断すると、以下で説明するエラーメッセージを引用できない中途半端な状態が残ります。
--console=plainを指定すると、プログレスバーや色が表示されず、出力を解析しやすくなります。
ステップ 5 — ファイルを検証してから、カナリアを実行する
リテラルのスナップショットパスとビルドルートパスを、二重引用符で囲んで指定してください。$SNAP は使わないでください。
diff -q "<snapshot>/gradle/wrapper/gradle-wrapper.properties" "<build-root>/gradle/wrapper/gradle-wrapper.properties"
differ と出力される必要があります。何も出力されないのは、対象がすでに現在のバージョンだった場合に限り、想定どおりです。 その場合、2 回の実行でスクリプトと jar が再生成されており、これは中途半端なアップグレードの修復に必要な処理です。続けてカナリアを実行してください。それ以外で何も出力されない場合、wrapper の実行によって別のビルドが変更されています。ビルドルート以外で実行されたためです。停止して、実行したディレクトリをユーザーに伝えてください。このビルドは変更されていないので、ロールバックしてはいけません。No such file はパスが間違っていることを意味し、ファイルが異なるという意味ではありません。その後、cd "<build-root>" && ./gradlew --version を実行すると、対象のバージョンが表示されるはずです。
変更が確実なのはプロパティだけです。スクリプトと jar が変わるのは、Gradle のテンプレートが変更された場合に限られます。jar は多くのリリースでバイト単位まで同一なので、変更されていなくても実行漏れではありません。上記のどちらのチェックでも、これらが最新であることは証明されませんし、証明する必要もありません。両方の wrapper 実行が終了コード 0 で終了したことが、その証明です。
これらのチェックで確認できるのは、アップグレードが適用されたことです。ビルドが引き続き動作するかどうかは分からないため、カナリアを再実行してください。ステップ 3 と同じコマンドです。
cd "<build-root>" && ./gradlew --console=plain tasks
終了コードがゼロ以外の場合 → ステップ 6。 ここで成功し、ステップ 3 の成功をベースラインとして比較できたら、アップグレードの検証は完了です。スナップショットを削除して、結果を報告してください。
rm -f "<snapshot>/gradlew" "<snapshot>/gradlew.bat" "<snapshot>/gradle/wrapper/gradle-wrapper.properties" "<snapshot>/gradle/wrapper/gradle-wrapper.jar" \
&& rmdir "<snapshot>/gradle/wrapper" "<snapshot>/gradle" "<snapshot>"
まず名前を指定してファイルを削除し、次に空のディレクトリを削除してください。rm -rf は使わないでください。空でないディレクトリを rmdir で削除できない場合、そのパスはスナップショットではありません。停止して、ユーザーに伝えてください。
ステップ 6 — ビルドを設定できなくなった場合は、ロールバックして停止します
ここに至るケースは 3 つあり、重要なのは 2 つ目です。
wrapperタスク自体が失敗した。 Run 2 が新しいバージョンそのものなので、そのバージョンで設定できないビルドは 2 回目の実行にも影響します。明らかなケースであり、ビルドを実行できないバージョンがプロパティに設定されたままになります。wrapperタスクは成功したが、カナリアが失敗した。 アップグレードは問題なく反映され、ラッパーファイルも正しい状態ですが、ビルドは使用できなくなっています。これが危険なケースです。ステップ 5 のファイル単位のチェックはすべて成功するため、そこで止まるエージェントは、ビルドが壊れているのにアップグレードが成功したと報告してしまいます。- Run 2 が完了しなかった — ダウンロードの途中で中断された。この場合、引用できるエラーはなく、ビルドで対象バージョンを実行できるかどうかも分かっていません。
最初の 2 つは原因が同じです。新しいメジャーバージョンでは API が削除され、最小 JVM バージョンが引き上げられ、新しい Groovy が提供されます。削除された機能に依存するビルドスクリプト、プラグイン、または buildSrc があると、ビルドを設定できなくなります。これは部分的なアップグレードではなく、ブロックされたアップグレードです。
今すぐ references/rollback.md を読み、その手順に従ってください — スナップショットからラッパーファイルを復元し、復元を確認して、最終報告に記載すべき 4 つの項目を確認します。このページをもとに独自に手順を考えないでください。
この分岐に入ったあとは、ここに記載されているほかの内容は適用されません。アップグレードを再試行したり、強制的に通すためにビルドスクリプトを編集したりしないでください。
タスクを 2 回実行する理由 — 実環境で最もよくある落とし穴
タスクは常に 4 つのファイルすべてを書き込みますが、スクリプトと jar は対象バージョンではなく、現在実行中の Gradle のテンプレートから生成されます。Run 1(まだ古い Gradle を使用)はプロパティを新しいバージョンに設定し、生成ファイルを古いテンプレートから書き換えます。通常は既存の内容がそのまま再現されますが、その際、手動で編集した gradlew がいつの間にか消えることもあります。プロパティが変更されたため、Run 2 では新しいバージョンが自動的にダウンロードされ、ファイルが新しいテンプレートから書き換えられます。
アップグレードが途中で止まったときによく見られる症状は、サポートに関する質問でも頻繁に目にする、消えないラッパーや非推奨の警告、不自然な gradlew の差分、またはタスクを一度も実行せずに distributionUrl だけを更新するボット(Dependabot など)です。解決方法は常に同じです。2 回実行してください。
バージョン形式
--gradle-version では、latest、release-candidate、release-nightly、nightly、release-milestone に加え、Gradle 9 以降では 9 や 9.1 のような単独のバージョンも指定できます。チェックサムを固定する場合は、具体的なバージョンを指定してください。Gradle 9.0 以降では、gradle-wrapper.properties に完全な X.Y.Z を指定する必要があります。メジャーのみ、またはメジャーとマイナーのみの指定はファイル内では拒否されますが、CLI では引き続き使用できます。使用するバージョンで指定可能なオプションは、./gradlew help --task=:wrapper で確認してください。
対象範囲外
ビルドの修正は、どちらの方向でも対象範囲外です — ブロックされたアップグレードを強制的に通すことも、新しいバージョンによって発生した問題を修正することも含みます。機械的には正しくアップグレードできていてもビルドが使用できないままなら、ジョブは失敗です。対応すべきなのはパッチではなく、ステップ 6 です。
境界となるのはコマンドではなく、ビルドのフェーズです。 設定できなくなった場合 — wrapper タスクまたはカナリアが失敗する場合 — アップグレードはブロックされています。ロールバックしてください。設定はできるものの、実行中に失敗する場合 — コンパイルエラーやテストの失敗など — アップグレードは反映されていますが、ビルドには別の問題があります。新しいラッパーはそのままにして、問題を報告してください。テストが失敗しただけでロールバックするのは、ビルドを設定できない状態のままにするのと同様に誤りです。この区別があるのは、設定の失敗は明確で確認も容易ですが、実行時の失敗はそうではないためです。tasks が成功しても、ビルドがコンパイルできるとは限りません。
公式ドキュメント:https://docs.gradle.org/current/userguide/gradle_wrapper.html。