ship について
shipは、機能ブランチの変更をレビュー、テスト、コミットへ進め、リリース情報を更新してプルリクエストを作成する自動ワークフローです。変更を二分探索しやすいコミットにまとめ、失敗や人の判断が必要な場合は停止します。
主な機能
- 01テスト前にベースブランチをマージ
- 02プロジェクトのテストとマージ前レビュー
- 03対象となるレビュー指摘の自動修正
- 04二分探索しやすいコミットへの整理
- 05必要に応じたバージョンと変更履歴の更新
- 06プルリクエストの準備
活用シーン
- 01機能ブランチの変更をプルリクエストとして出荷
- 02マージ前のチェックとコードレビュー
- 03大きな変更を論理的なコミットに分割
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ borkweb/ skills --skill shipインストール後、Claude Code で/shipを入力して読み込まれたか確認します。
詳細
Step 0: ベースブランチを特定する
この PR の対象ブランチを特定します。以降のすべての手順で、結果を「ベースブランチ」として使用します。
共通ヘルパーを実行します。
BASE=$(bash "$CLAUDE_PLUGIN_ROOT/scripts/detect-base-branch.sh")
このヘルパーは、現在の PR の baseRefName、リポジトリのデフォルトブランチ、最後に main の順で確認します。必ず使用可能な名前を出力します。
Ship:完全自動化された Ship ワークフロー
/ship ワークフローを実行しています。これは非対話型の完全自動化ワークフローです。どの手順でも確認を求めてはいけません。ユーザーが /ship と指定したということは、実行するということです。最後までそのまま進め、最後に PR の URL を出力してください。
次の場合に限り停止します:
- ベースブランチ上にいる場合(中止)
- 自動解決できないマージコンフリクトがある場合(停止して、コンフリクトを表示)
- テストが失敗した場合(停止して、失敗内容を表示)
- リリース前レビューで、ユーザーの判断が必要な ASK 項目が見つかった場合
- MINOR または MAJOR のバージョン更新が必要な場合(確認する。「Step 5」を参照)
次の場合は決して停止しません:
- 未コミットの変更(必ず含める)
- バージョン更新の選択(自動的に MICRO または PATCH を選択。「Step 5」を参照)
- CHANGELOG の内容(コミットから自動生成)
- コミットメッセージの承認(自動コミット)
- 複数ファイルにまたがる変更セット(バイセクト可能なコミットに自動分割)
- TODOS.md の完了項目の検出(自動でマーク)
- 自動修正可能なレビュー結果(デッドコード、N+1、古いコメントは自動で修正)
Step 1: 事前確認
-
現在のブランチを確認します。ベースブランチ上にいる場合は、中止します:「ベースブランチ上にいます。フィーチャーブランチから Ship を実行してください。」
-
git statusを実行します(-uallは決して使用しないでください)。未コミットの変更は必ず含めます。確認は不要です。 -
git diff <base>...HEAD --statとgit log <base>..HEAD --onelineを実行して、Ship する内容を把握します。 -
関連付けられた Issue を検出します。 次の場所にある Issue への参照を確認します。
- ブランチ名(例:
fix/123-broken-login、feature/GH-45) - コミットメッセージ(
Fixes #123、Closes #45、Relates to #78) - Issue を参照している TODOS.md の項目 すべての Issue 番号を収集します。これらは Step 9 の PR 本文に含めます。
- ブランチ名(例:
復旧方法: git status または git log が失敗した場合(インデックスの破損など)、git fsck を実行して報告します。先に進んではいけません。
Step 2: ベースブランチをマージする(テストの前に実行)
テストをマージ後の状態で実行できるよう、ベースブランチをフィーチャーブランチにフェッチしてマージします。
git fetch origin <base> && git merge origin/<base> --no-edit
マージコンフリクトが発生した場合: 単純なものであれば(VERSION、スキーマ、CHANGELOG の順序など)、自動解決を試みます。複雑または曖昧なコンフリクトがある場合は、停止して内容を表示します。
すでに最新の場合: 何も表示せずに続行します。
復旧方法: git fetch が失敗した場合(ネットワーク、認証など)は、エラーを報告して停止します。コンフリクト以外の理由(無関係な履歴など)で git merge が失敗した場合は、報告して停止します。
Step 3: テストを実行する(マージ済みコードで)
コードベースからプロジェクトのテストコマンドを特定し(package.json の scripts、Makefile、Gemfile など)、実行します。
テストが1つでも失敗した場合: 失敗内容を表示して停止します。先に進んではいけません。
すべて成功した場合: 何も表示せずに続行し、件数だけ簡潔に記録します。
復旧方法: テストランナー自体の実行に失敗した場合(依存関係の不足、設定エラーなど)は、エラーを明確に報告します。「ランナーがクラッシュした」ことを「テストに合格した」と見なしてはいけません。
ステップ 3.5:マージ前レビュー(レビュー用スキルに委任)
ロジックを重複させず、/review スキルのチェックリストにレビューを委任します。
-
レビュー用スキルのディレクトリから
checklist.mdを読み込みます(skills/gstack/review/checklist.md)。見つからない場合は、停止して報告してください。 -
レビュー用スキルのディレクトリから
design-checklist.mdを読み込みます。ステップ 3.5.4 で使えるようにしておきます。 -
git diff origin/<base>を実行して、差分全体を取得します。 -
チェックリストに従って、2 回に分けてレビューを実施します。
- パス 1(重大): SQL とデータの安全性、マイグレーションとスキーマの安全性、競合状態と並行処理、認証と権限の不備、LLM 出力の信頼境界、列挙型と値の完全性、API コントラクトを破壊する変更
- パス 2(参考情報): エラーハンドリングのアンチパターン、条件付き副作用、マジックナンバーと文字列の結合、デッドコードと一貫性、LLM プロンプトの問題、テストの不足、暗号とエントロピー、時間ウィンドウの安全性、境界での型変換、ビュー/フロントエンド、パフォーマンスとバンドルへの影響
-
フロントエンドの変更を確認します。
bash "$CLAUDE_PLUGIN_ROOT/scripts/detect-frontend-files.sh" "$BASE"ファイルが出力された場合は、デザインチェックリスト(ステップ 2 で読み込み済み)を適用します。まずリポジトリのルートに
DESIGN.mdがあるか確認してください。そこに記載されている承認済みのパターンは指摘対象にしません。 -
チェックリストの Fix-First ヒューリスティックに従って、各指摘を AUTO-FIX または ASK に分類します。重大な指摘は ASK、参考情報は AUTO-FIX に分類する傾向があります。
-
AUTO-FIX 項目をすべて自動修正します。修正ごとに 1 行で出力します。
[AUTO-FIXED] [file:line] 問題 → 実施した対応 -
ASK 項目が残っている場合は、1 つの AskUserQuestion にまとめて提示します。
- 各項目に番号、重大度、問題、推奨される修正を記載します
- 各項目の選択肢:A) 修正する B) スキップする
- 全体の推奨事項
-
すべての修正(自動修正とユーザー承認済みの修正)の後:
- 修正を適用した場合:修正したファイルをコミットし、続行する前にテストを再実行します。
- 修正を適用していない場合:ステップ 4 に進みます。
-
次の形式で概要を出力します。
マージ前レビュー:N 件の問題 — M 件を自動修正、K 件を確認依頼(J 件を修正、L 件をスキップ)
レビュー結果を保存します。ステップ 9 で PR の本文に含めます。
ステップ 3.7:敵対的レビュー
差分が次の条件のいずれかに該当する場合、Agent ツールを使って敵対的レビュー担当者を割り当てます。
- 変更行数が 200 行を超える
- 認証、決済、またはセキュリティ関連のファイルに触れている
- 新しい外部サービスとの連携を導入している
- 新しい暗号処理またはシークレットの取り扱いを含む
200 行未満の差分で、機密ファイルに触れていない場合は、このステップをスキップします。
サブエージェントへのプロンプト:
「git diff origin/<base> を使って、このブランチの差分を読んでください。攻撃者およびカオスエンジニアの視点で考えてください。このコードが本番環境で失敗する原因を見つけることがあなたの役割です。エッジケース、競合状態、セキュリティホール、リソースリーク、障害モード、気付かれないデータ破損、誤った結果を気付かれないまま生み出すロジックエラー、失敗を握りつぶすエラーハンドリング、信頼境界の違反を探してください。敵対的に、徹底的に調べてください。称賛は不要です。問題だけを挙げてください。各指摘を、FIXABLE(修正方法が分かる)または INVESTIGATE(人間の判断が必要)に分類してください。」
指摘事項を提示します。FIXABLE の指摘は Fix-First の流れに進みます(自動修正し、コードを変更した場合はテストを再実行します)。INVESTIGATE の指摘は参考情報のみです。
敵対的レビューの結果を保存します。ステップ 9 で PR の本文に含めます。
ステップ 4:コミット(git bisect しやすい単位)
目標: git bisect に適した、小さく論理的なコミットを作成します。
-
変更を論理的なコミットにまとめます。各コミットは、一貫性のある変更を 1 つ含みます。
-
コミットの順序 — これを基本とし、プロジェクトの構成に応じて調整します。
- まず基盤の変更: マイグレーション、設定、スキーマ、ルート、依存関係
- 次にコアロジック: モデル、サービス、ライブラリ(関連するテストを含む)
- 最後に表層部分: コントローラー、ビュー、CLI コマンド(関連するテストを含む)
- メタデータは必ず最後: 最後のコミットに VERSION + CHANGELOG + TODOS.md を含めます
ライブラリや CLI ツールの場合は、コア API → 内部モジュール → パブリックインターフェース → メタデータの順に調整します。 モノレポの場合は、レイヤーではなくパッケージごとにまとめます。
-
ルール:
- モジュール/サービスとそのテストは、同じコミットに含めます
- 差分全体が小さい場合(4 ファイル未満にまたがる 50 行未満)は、単一のコミットでもかまいません
- 各コミットは単独で有効でなければなりません。壊れたインポートを残さないでください
-
コミットメッセージを作成します:
<type>: <summary>(feat/fix/chore/refactor/docs)
ステップ 5:バージョン更新(自動判断)
VERSION ファイルが存在する場合:
-
現在のバージョンを読み取ります。
-
変更の量ではなく内容に基づいて、更新レベルを自動判断します。
MICRO(自動)— 内部のみの変更:
- バグ修正、誤字修正、コメントの更新、テストのみの変更
- パブリック API や動作を変更しないリファクタリング
- ドキュメントの更新
PATCH(自動)— ユーザー向けだが互換性を損なわない変更:
- 観測可能な動作を変更するバグ修正
- パフォーマンスの改善
- デフォルト値を持つ新しいオプションパラメーター
- 依存関係の更新
MINOR(確認)— 新しい機能:
- 新しいエンドポイント、コマンド、機能、またはパブリック API メソッド
- 新しいデータベーステーブル、または大幅なスキーマ追加
- 新しい外部サービスとの連携
MAJOR(確認)— 互換性を損なう変更:
- パブリック API メソッド/エンドポイントの削除または名称変更
- レスポンス形式または必須パラメーターの変更
- データ変換が必要なデータベースマイグレーション
- ランタイム/プラットフォームのサポート終了
-
新しいバージョンを算出して書き込みます。
VERSION ファイルが存在しない場合は、このステップをスキップします。
ステップ 6:CHANGELOG(自動生成)
CHANGELOG.md が存在する場合:
-
ヘッダーを読み取り、書式を確認します。
-
ステップ 4 のコミットメッセージを主な手掛かりとして、エントリーを自動生成します。
feat:で始まるコミット →### Addedfix:で始まるコミット →### Fixedrefactor:/chore:で始まるコミット →### Changed- 機能を削除するコミット →
### Removed - 分類できない変更は差分分析で補います
- 簡潔で内容の分かる箇条書きを記述します
- ファイルヘッダーの直後に、今日の日付で挿入します
変更内容の説明をユーザーに求めないでください。 コミットと差分から推測します。
CHANGELOG.md が存在しない場合は、このステップをスキップします。
ステップ 6.5:TODOS.md(自動更新)
TODOS.md が存在する場合:
- 差分と未完了の TODO を照合します
- 完了した項目を自動的に完了済みにする — 差分から作業の完了が明確に分かる場合に限ります(慎重に判断します)
- 完了した項目を、バージョンと日付を添えて「完了」セクションに移動します
- 次の形式で概要を出力します:
TODOS.md: N items marked complete. M items remaining.
TODOS.md が存在しない場合は、何もせずにスキップします。
ステップ 6.7:計画完了の監査
このブランチの計画ファイルが存在する場合は、計画に記載されたすべての内容が実際に反映されていることを確認します。計画ファイルが見つからない場合は、何もせずにスキップします。
プランファイルの検出
- 会話のコンテキスト(優先): ホストエージェントのシステムメッセージでプランファイルのパスが指定されている場合は、そのパスを直接使用します。
- ファイルシステムの検索(フォールバック):
docs/plans/、docs/designs/、.claude/plans/、プロジェクトのルートで、現在のブランチ名に一致する Markdown ファイルを探します。該当するファイルのうち、最終更新日時が最も新しいものを使用します。候補が複数あり、どれが該当するか明確でない場合は、「プランファイルが見つからない」と扱います。 - 検証: 最初の20行を読みます。現在のブランチの作業に関係していないようであれば、「プランファイルが見つからない」と扱います。
プランファイルが見つからない場合: 「プランファイルが検出されませんでした — プラン完了監査をスキップします。」と出力して、ステップ7に進みます。
サブエージェントとして実行
subagent_type: "general-purpose" を指定して Agent ツールを使用します。サブエージェントは新しいコンテキストでプランと差分を読み、親エージェントには結論を返します。サブエージェントへのプロンプト:
現在のブランチについて、プランの完了状況を監査してください。ベースブランチ:
<base>。プランファイル:<path>。実行可能な項目を抽出してください: チェックボックス(
- [ ]/- [x])、番号付きの実装手順、命令形の記述(「X を追加する」「Y を作成する」)、ファイル単位の仕様、テスト要件、データモデルの変更を含めます。最大50項目としてください。Context/Background/Problem セクション、未解決の質問(「TBD」「TODO: decide」)、明示的に延期された項目(「Out of scope:」「Future:」「P2:」「P3:」)、過去のレビュー報告は無視してください。各項目の検証方法を分類してください:
- DIFF-VERIFIABLE — このリポジトリの
git diff <base>...HEADに現れるはずの項目です。- CROSS-REPO — 兄弟リポジトリ内のファイルを指定しています。そのパスにアクセス可能なら
[ -f <path> ]を試してください。アクセスできない場合は UNVERIFIABLE としてください。- EXTERNAL-STATE — 外部システムの状態(DNS、OAuth の許可リスト、SaaS の設定など)を指定しています。常に UNVERIFIABLE としてください。
- CONTENT-SHAPE — ファイルが規約に従う必要があります。UNVERIFIABLE とする前に、プロジェクトのバリデーター(
validate-*、lint-docsなど)を実行してください。パスの具体性に関するルール: プラン項目で具体的なファイルシステムのパスが指定されている場合、
[ -f <path> ]に基づいて、必ず DONE または NOT DONE としてください。UNVERIFIABLE が有効なのは、パスが本質的に抽象的であるか、アクセスできない場合に限ります。項目ごとのステータス:
- DONE — 差分またはファイルシステムに明確な証拠があります。該当するファイルを記載してください。
- PARTIAL — 項目に向けた作業の一部はありますが、未完了です。
- NOT DONE — 検証を実行し、否定的な結果が得られました。
- CHANGED — 異なる方法で実装されていますが、同じ目的は達成されています。違いを記載してください。
- UNVERIFIABLE — 証明も反証もできません。具体的な手動確認事項を記載してください。
誠実さに関するルール: 成果物を処理するコードは、その成果物自体ではありません。Markdown 抽出ライブラリを提供することは、Markdown ファイルそのものを提供することと同じではありません。DONE と UNVERIFIABLE の判断に迷った場合は、UNVERIFIABLE を優先してください。
カテゴリ(Implementation/Tests/Migrations/Cross-Repo/External)ごとにまとめた Markdown チェックリストを出力し、各項目の先頭に
[STATUS]を付けてください。最後に、次の形式の要約行を記載してください:COMPLETION: X/Y DONE, A PARTIAL, B NOT DONE, C CHANGED, D UNVERIFIABLE
ゲートロジック
サブエージェントの応答後、次の優先順位で評価します。
-
NOT DONE の項目がある場合(不足している作業が判明している場合)。AskUserQuestion を使用します。
- 完了チェックリストを表示します。
- 「計画の {N} 項目が NOT DONE です。」
- 選択肢:A) 中止 — リリース前に実装する。B) そのままリリース — P1 TODO として先送りする。C) 意図的に削除 — スコープから除外する。
- 推奨:コア機能が不足している場合は A、軽微なドキュメント/設定の場合は B。
- A の場合:中止します。B の場合:続行し、各項目について
Deferred from plan: {path}を TODOS.md に追記します。C の場合:続行し、PR 本文に記載します。
-
UNVERIFIABLE の項目がある場合(NOT DONE の解決後、または NOT DONE がない場合のみ)。項目ごとの確認が必須です。一括確認はできません。 1 項目ずつ繰り返します。
- 各項目について、その項目に固有の手動確認を AskUserQuestion で尋ねます(「すべての項目を確認しましたか?」ではなく、「確認:
~/path/to/fileは存在しますか?」のように尋ねます)。 - 項目ごとの選択肢:Y) 完了を確認済み — 確認した内容を記載(自由記述)。N) 未完了 — リリースをブロックし、優先順位 1 に戻る。D) 意図的に削除。
- N が 1 つでもある場合:中止します。すべて Y または D の場合:続行し、PR 本文に
## Plan Completion — Manual Verificationsを追加して、Y の各項目の証拠と D の各項目が削除された旨を記載します。 - 上限: UNVERIFIABLE の項目が 5 件を超える場合、まず一覧を提示し、次のいずれかを尋ねます。(1)各項目を個別に確認する[推奨]。(2)中止してスコープを縮小する。(3)一括確認を明示的に承認する(このゲートが防止しようとしている失敗パターンであることを警告します)。
- 各項目について、その項目に固有の手動確認を AskUserQuestion で尋ねます(「すべての項目を確認しましたか?」ではなく、「確認:
-
PARTIAL の項目のみの場合(NOT DONE も UNVERIFIABLE もない場合): PR 本文に注記して続行します。ブロック対象ではありません。
-
すべて DONE または CHANGED の場合: 合格です。続行します。
サブエージェント失敗時のフェイルクローズ
サブエージェントが失敗するか、不正な形式の出力を返した場合、暗黙に合格として扱わないでください。親コンテキスト内で抽出を一度試してください。それも失敗した場合は、AskUserQuestion で次のように提示します。
「計画完了の監査を実行できませんでした({reason})。選択肢:A) 監査を省略してリリースする — 監査を省略したことを PR 本文に記録する。B) 中止して監査を修正する。」
推奨:B。暗黙のフェイルオープンは、このゲートが防止しようとしている失敗パターンです。
PR 本文
Step 9 で、チェックリストの概要を含む ## Plan Completion セクションを PR 本文に追加します。UNVERIFIABLE の項目を項目ごとの確認フローで確認した場合は、各確認を列挙した ## Plan Completion — Manual Verifications も追加します。
Step 7: 検証ゲート
絶対原則:新たな検証の証拠なしに、完了を主張してはなりません。
プッシュする前に、Step 4~6.5 でコードが変更されている場合は再検証します。
- Step 3 のテスト実行後にコードが少しでも変更されている場合(レビュー修正など)、テストを再実行します。新しい出力を貼り付けます。
- プロジェクトにビルド手順がある場合は、実行します。
- テストが失敗した場合: 中止します。プッシュしないでください。
Step 8: プッシュ
git push -u origin <branch-name>
復旧方法: プッシュに失敗した場合:
- ブランチ保護/pre-receive フックによる拒否: エラーを報告します。強制プッシュはしないでください。ユーザーが修正する必要がある内容(例:必須レビュー担当者、ステータスチェック)を提案します。
- 認証失敗: 報告して中止します。
- リモートとの分岐(fast-forward 不可): 報告して中止します。強制プッシュはしないでください。
git pull --rebase origin <branch-name>を実行して再検証するよう提案します。
Step 9: PR の作成
Step 9.1: PR メタデータの検出
-
ラベル: リポジトリのラベル規則を確認します。
gh label list --limit 20 --json name --jq '.[].name'変更の種類に一致するラベルを自動適用します。
bug/bugfixは fix: コミットに適用enhancement/featureは feat: コミットに適用- ロックファイルが変更された場合は
dependenciesを適用 - リポジトリでサイズラベルが使われている場合は適用(差分の行数に応じて S/M/L) 一致するラベルがない場合はスキップします。新しいラベルは作成しないでください。
-
レビュー担当者: CODEOWNERS を確認します。
cat .github/CODEOWNERS 2>/dev/null || cat CODEOWNERS 2>/dev/nullCODEOWNERS がある場合は、GitHub に自動割り当てさせます。それ以外の場合、レビュー担当者の割り当てはスキップします。
-
ドラフトモード: 次のいずれかに該当する場合は、ドラフト(
--draft)として作成します。- ブランチ名が
wip/またはdraft/で始まる - コミットメッセージに
[WIP]または[DRAFT]が含まれている - TODOS.md に、このブランチの作業に関連する進行中の項目がある
- ブランチ名が
ステップ 9.2:PR を作成する
gh pr create --base <base> \
--title "<type>: <summary>" \
[--draft] \
[--label "<label1>" --label "<label2>"] \
--body "$(cat <<'EOF'
## Summary
<bullet points from CHANGELOG or diff summary>
<If linked issues were detected in Step 1:>
Closes #<issue>
<or>
Relates to #<issue>
## Pre-Landing Review
<findings from Step 3.5, or "No issues found.">
<If adversarial review was run in Step 3.7:>
## Adversarial Review
<INVESTIGATE findings, or "No issues found.">
<FIXABLE findings that were applied are noted as resolved.>
## TODOS
<completed items, or "No TODO items completed in this PR.">
<If Step 6.7 ran:>
## Plan Completion
<checklist summary from Step 6.7, or "No plan file detected.">
<If UNVERIFIABLE items were confirmed via per-item flow:>
## Plan Completion — Manual Verifications
<each Y'd item with user evidence; each D'd item marked "intentionally dropped">
## Test plan
- [x] All tests pass
- [x] Verification gate passed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"
PR の URL を出力します。
復旧: gh pr create が失敗した場合:
- PR がすでに存在する場合:
gh pr view --json url --jq .urlを実行し、既存の URL を出力します。代わりに既存の PR の本文を更新するか確認してください。 - 権限がない場合: その旨を報告して停止します。
- ネットワークエラーの場合: 1 回再試行します。それでも失敗する場合は、その旨を報告して停止します。コードはプッシュ済みなので、ユーザーは PR を手動で作成できます。
重要なルール
- テストを省略しないでください。 テストが失敗した場合は停止します。
- 強制プッシュはしないでください。 通常の
git pushのみを使用します。 - 些細な確認を求めないでください(例:「プッシュする準備はできていますか?」「PR を作成しますか?」)。次の場合は必ず停止してください:バージョンの引き上げ(MINOR/MAJOR)およびリリース前レビューの ASK 項目。
- ビセクション可能なようにコミットを分割してください — 各コミットは 1 つの論理的な変更とします。
- TODOS.md の完了判定は慎重に行ってください。 差分から完了が明確に確認できる場合にのみ、項目を完了としてマークします。
- 最新の検証結果を確認せずにプッシュしないでください。 ステップ 3 の後にコードを変更した場合は、プッシュ前に再実行します。
- 失敗する前に復旧を試みてください。 各ステップには復旧手順があります。諦める前に、その手順に従ってください。
- 目標は、ユーザーが
/shipと入力した次に、PR の URL が表示されることです。