gh-release
バンプ、CHANGELOG、タグ、プッシュ、監視。
以下のコマンドは ~/.claude/skills/gh-release/scripts/ をフルパスで記述しています。記述されたとおりに実行してください - 先頭の ~ を保持し、展開しないでください。 パーミッションルールはリテラルのコマンド文字列と一致するため、/home/<you>/.claude/...(チルダ展開済み)、python3 ~/...、相対パス、または先に cd することは、それぞれ異なる文字列であり、再確認を求められます。チルダパスは「非形式的に書かれた絶対パス」ではありません。パーミッションルールにとって、それはパスそのものです。
リリースを失敗させる原因は2つあり、どちらもタグが作成される前に発生します。
- リポジトリが自動化済みのバンプを再発明すること。 手動編集は、リポジトリ独自のタスクが処理したであろうファイルに触れ、それが知っているファイルを見逃し、そのゲートをスキップします。
- 何もトリガーしないタグ。 これは遅いCIキューとまったく同じに見え、20分後に気づきます。
ステップ1と3はこれらをキャッチするために存在します。
0. バージョンを決定する
タグを読み取って(git tag --sort=-v:refname | head -5)、リポジトリの形式(v1.2.3 か 1.2.3 か)と現在のバージョンを確認します。ユーザーがバージョンを指定した場合はそれを使用します。そうでない場合は、最新タグ以降のコミットから提案します - 破壊的変更はメジャー、feat: はマイナー、それ以外はパッチ - そして、その理由を説明します。
ダーティツリー、切り離されたHEAD、またはリモートに追いついていないブランチでは処理を拒否します。コミットされていない作業をリリースすると、誰も再現できないタグが生成されます。
1. リポジトリ独自のリリース機構を使用する
何かを手動で行う前に、常に確認してください:
~/.claude/skills/gh-release/scripts/versiontool.py discover
これはプロジェクトスキル、miseタスク、npmスクリプト、Makeターゲット、justレシピ、scripts/-bin/ エントリ、およびツール設定(cargo-release、bumpversion、release-please、git-cliff)を報告します。優先順位:
kind=project-skill - このスキルの読み取りを停止し、そのスキルに従ってください。それはリポジトリ独自の手順であり、この汎用スキルが知り得ないことを知っています。
タスクまたはスクリプト(kind=mise-task|npm-script|make-target|just-recipe|script)
- 実行する前にそれを読み、実行してください。何をカバーしているかを把握し、作業を重複または省略しないようにする必要があります。一般的なタスクは、バンプ、CHANGELOG昇格、ゲート、コミット、タグ、プッシュの一部(すべてではない)を行います。どれかをメモし、残りだけを行ってください。
多くの場合、裸のバージョンを受け取り、自分でプレフィックスを追加します(mise run release 0.13.0 は v0.13.0 というタグを付けます)。そのため、バージョンが求められている場所にタグを渡さないでください。--dry-run があれば、最初にそれを使用し、計画をユーザーに示してください。
ツール設定(タスクなし) - そのツール独自のコマンド(cargo release <version>、bump-my-version bump ...)を使用し、手動編集はしないでください。
result=none - その場合のみ、ステップ2にフォールバックします。
2. フォールバック: バージョンが存在するすべての場所を見つける
ステップ1で何も見つからなかった場合のみ。
~/.claude/skills/gh-release/scripts/versiontool.py locations <current-version>
これはリテラルのバージョン文字列を検索し、「version」という単語は検索しません。実際のリポジトリで測定した結果: version キー検索では5ファイルが見つかり、リテラル文字列検索では8ファイルが見つかりました。見逃したものは、キーを "version-name"(GNOMEメタデータ)や "Version"(Plasma)と綴っていました。見逃したものは、誤ったバージョンを報告するバイナリをリリースしてしまいます。
出力は分類されます: edit(変更する)、regenerate(ロックファイル - ヒントのコマンドを実行し、決して手動編集しない。そうしないとCIの --locked が失敗する)、changelog(ステップ4)。
次に前のバージョンも確認してください - そこにヒットがあれば、前回のリリースで見逃され、それ以降古くなっているファイルです。今回のリリースで修正してください。
3. タグの事前確認
~/.claude/skills/gh-release/scripts/relwatch.py preflight <tag>
これは .github/workflows/*.yml を読み取り、すべての on.push.tags パターンを抽出し、あなたのタグがそれらのいずれかに一致するか、そのワークフローがリリースを作成するように見えるかを教えてくれます。result=NO_MATCH は、タグをプッシュしても何も起きないことを意味します。
これをコミットする前に、タグを変更するのが無料のうちに実行してください。
また、ワークフローのリリースステップがプッシュしようとしているタグを使用していることを目視で確認してください。多くのワークフローは、タグがコード内のバージョンと一致することを確認しないため、不一致が発生すると、誤ったバージョンを報告するバイナリが、静かに、グリーンCIでリリースされます。
4. CHANGELOG
ステップ1のタスクがCHANGELOG自体を昇格させる場合は、それに任せ、ステップ5にスキップしてください。
Keep a Changelog(## [Unreleased] 見出しがある場合): それを昇格させます。
## [Unreleased]を## [X.Y.Z] - YYYY-MM-DDに変更- その上に新しい空の
## [Unreleased]を追加 - 下部のリンク定義を更新し、
[Unreleased]比較リンクの新しいベースを含める
CHANGELOGがない、またはUnreleasedセクションがない場合: 最新タグ以降のコミットからエントリを書き、ファイルが既にグループ化している方法でグループ化します。既存の文体に正確に一致させてください - エントリが1行であれば1行で書き、リードが太字の散文であればそのように書いてください。
いずれの場合も: リポジトリに対して何をしたかではなく、プロジェクトのユーザーにとって何が変わったかを説明してください。
すべてのエントリに unslop スキルを適用してください。 CHANGELOGは何年も読み継がれ、アップグレードするかどうかを判断する人々によって読まれます。「各種改善とバグ修正」はエントリがないより悪いです。同様に、コミット件名をより長い言葉で言い直すだけのエントリも悪いです。ドキュメント固有の注意点は docs-update/SKILL.md のステップ5にリストされており、ここでもそのまま適用されます: 前置きなし、空の強調なし、答えが明確な場合の曖昧な表現は避ける。
5. タグ付け前の検証
~/.claude/skills/gh-release/scripts/versiontool.py verify <old-version> # 結果は result=clean を出力しなければならない
リポジトリタスクがバンプを行った場合でもこれを実行してください。 6か月前に書かれたバンパーは、先週誰かが追加したファイルを知りません。そしてそれがまさに、バージョンがツリーの一部で古くなる方法です。CHANGELOG履歴は無視されます。編集可能なファイルのみがカウントされます。
次にプロジェクトゲート(ビルド、テスト、リンター)を実行してください。赤いコミットを指すタグは削除して再カットする必要があり、プッシュされたタグを削除することは、既にフェッチした人にとって面倒です。
6. コミット、タグ、プッシュ
ステップ1のタスクが既に行ったことはスキップしてください。コミット、タグ付け、プッシュを既に行っている場合は、ステップ7に直接進みます。
そうでない場合: リリース用に1つのコミットを作成し、件名は ~/.claude/CLAUDE.md に従ってブランチ名をプレフィックスとして付けます。バンプとCHANGELOGは同じコミットに属します。これらは1つの変更です。
git commit -m "[<branch>] chore(release): <version>"
git tag -a <tag> -m "<tag>"
git push && git push origin <tag>
コミットをタグの前にプッシュしてください。先に到着したタグは、リモートがまだ持っていないコミットに対するビルドを開始する可能性があります。
プッシュ時刻をメモしてください。監視の上限となります。
7. リリースが存在するまで監視する
~/.claude/skills/gh-release/scripts/relwatch.py watch <tag> --timeout 1800
| 結果 | 意味 |
|---|---|
released url=... | 完了 |
ci_failed run=... conclusion=... | ステップ8 |
no_run | 何もトリガーされませんでした。タグがいずれのパターンにも一致しませんでした - preflight を実行 |
still_running | 失敗ではありません。再度監視 |
グリーンCIはリリースではありません。公開ステップはビルドより遅れる可能性があるため、ウォッチャーはReleaseオブジェクトが実際に存在するまで待機し続けます。
babysit-pr と同じサブエージェントルール: 単一の watch を1回のBash呼び出し内で行う場合(--timeout 540)はインラインでより安価です。待機が複数の呼び出しにまたがる場合のみ委任してください。リリースが存在する前、またはブロッカーがある前に停止しないでください。
8. タグ後にCIが失敗した場合
タグが間違っているため、回避策ではなくそれを撤回してください:
git push --delete origin <tag>
git tag -d <tag>
修正し、ステップ5から同じバージョン番号で再カットしてください。失敗をスキップするためにバンプしないでください: 誰もリリースしたことのないバージョンを捨てる価値はなく、そのギャップは誰かが欠落したリリースを探しに行くきっかけになります。
タグがしばらく公開されていた場合、または部分的なリリースが存在する場合、その旨を伝え、ユーザーに削除するか、その上にパッチをリリースするかの選択を委ねてください。
9. 報告
PR/比較リンク、タグ、リリースURL、変更点、およびバンプされたすべてのファイルを報告してください。ユーザーに残されたものがあれば、それを明記してください。