Ship to Prod
ユーザーが作業完了後に「ship it」などと言った場合、二度聞かずに以下の手順を実行してください。
フローは現在のブランチに依存します。環境を一度検出し、その後の手順で再利用します。
環境の検出
最初にこれらを並行して実行します。
- パッケージマネージャー: リポジトリルートのロックファイルを確認します。
pnpm-lock.yaml->pnpmyarn.lock->yarnbun.lockbまたはbun.lock->bunpackage-lock.json->npmpackage.jsonにpackageManagerフィールドがあれば、そちらを使用します。- 見つからない場合、デフォルトで
npmを使用します。
- デフォルトブランチ:
git symbolic-ref refs/remotes/origin/HEAD(フォールバックとしてgit config init.defaultBranch)。両方失敗した場合、デフォルトでmainを使用します。 - PR用ツール:
gh --version。ghがインストールされ認証済みの場合、PR作成とマージに使用します。それ以外の場合は、ユーザーが手動で作成できるようPRのURLを表示します。 - シェル: 現在のシェルを検出します。Windows(PowerShell)の場合、ヒアドキュメントが使えないため、
git commitには複数の-mフラグを使用します。bash/zsh/fishおよびその他のUnixシェルではヒアドキュメントを使用します。
これらを <pkg>、<default-branch>、<gh-available>、<shell> として残りのフローで保存します。
手順
1. クリーンアップ(オプション)
コミット前にAIが生成したゴミを除去する2つのスキルがあります。両方が利用可能な場合は実行します。
deslop: デフォルトブランチに対する現在の差分からAIコードのスロップ(不要なコメント、信頼できるパスに対する防御的チェック、anyキャスト、深いネスト)を除去します。unslop: 散文(UI文字列、コメント、コミットメッセージ、PR説明)からAIテキストの兆候を除去します。このセッションで作成したテキストに対して呼び出します。
いずれかのスキルがフラグを立てた問題を、先に進む前に修正します。
どちらかのスキルがインストールされていない場合、黙ってスキップしないでください。不足しているスキルをインストールするかどうかをユーザーに尋ね、以下の選択肢を提示します。両方のスキルがCursor AIの公式プラグインリポジトリ(https://github.com/cursor/plugins)から提供されているため、信頼できるソースであることを伝えます。
- グローバル(将来すべてのプロジェクトで使用する場合):
npx skills add https://github.com/cursor/plugins --skill deslop unslop -g - ローカル(このプロジェクトのみ):
npx skills add https://github.com/cursor/plugins --skill deslop unslop - スキップ(今回だけ): 不足しているスキルなしで続行します。オプションの依存関係がなくてもフローを妨げないでください。
ask_user_question ツールを使用して選択肢を提示します。ユーザーがグローバルまたはローカルを選択した場合、インストールコマンドを実行し、スキルが利用可能になったことを確認してから呼び出します。インストールが失敗した場合、またはユーザーがスキップを選択した場合、利用可能なものでフローを続行します。
2. 作業の検証
以下の順序で実行し、問題があれば修正してから続行します。<pkg> を検出したパッケージマネージャーに置き換えます。npm では常に run が必要です(例:npm run format)。pnpm/yarn/bun では直接呼び出し可能です(例:pnpm format)。
<pkg> run format(または pnpm/yarn/bun では<pkg> format): 自動フォーマット<pkg> run lint(または pnpm/yarn/bun では<pkg> lint): 変更したファイルのリントエラーを修正(他のファイルの既存の問題は無視)<pkg> run typecheck(または pnpm/yarn/bun では<pkg> typecheck): 終了コード0でパスする必要あり<pkg> run build(または pnpm/yarn/bun では<pkg> build): 終了コード0でパスする必要あり
スクリプトが存在しない場合(例:format スクリプトがない)、そのステップをスキップして記録します。欠落しているオプションのスクリプトがあってもフロー全体を失敗させないでください。typecheck と build は、存在する場合は必須です。どちらも存在しない場合、警告を出して続行します。
利用可能なチェックがすべてパスするまでコミットに進まないでください。
検証後に git status がクリーン(ステージ済みも未ステージもなし)の場合、「shipするものはありません」と報告して停止します。空のコミットは試みないでください。
3. 現在のブランチの評価
git branch --show-current を実行して現在のブランチ名を取得します。<default-branch> と比較します。そして判断します。
<default-branch>上の場合: コミットして直接プッシュします。PRもマージも不要です。手順5にスキップします。- 他のブランチの場合: コミット、プッシュ、
<default-branch>へのPR作成、マージを行います。手順4に進みます。
4. 変更内容の確認
git status、git diff、git log --oneline -5 を並行して実行し、変更内容を理解しコミットスタイルに合わせます。
5. ステージングとコミット
git add -A を実行し、従来のコミットメッセージ(feat/fix/refactor)でコミットします。
コミットメッセージ形式:
<type>: <short description>
<optional body>
bash/zsh/fishおよびその他のUnixシェルでは、ヒアドキュメントを使用します:
git commit -m "$(cat <<'EOF'
type: subject
body
EOF
)"
PowerShell(Windows)ではヒアドキュメントが使えないため、複数の -m フラグを使用します:
git commit -m "type: subject" -m "body"
6. プッシュ
git push(ブランチに上流がまだない場合は git push -u origin <branch>)を実行します。
7. フィーチャーブランチの場合: PR作成とマージ
<gh-available> の場合:
- PR本文を一時ファイルに書き込み、
--body-fileを使用してPRを作成します(すべてのシェル、PowerShellを含む、で動作します):gh pr create --base <default-branch> --head <current-branch> --title "<title>" --body-file <temp-file>
gh pr createが戻ったら一時ファイルを削除します。ディスクに残さないでください。- マージ戦略は指定せずにマージし、ユーザーのリポジトリのデフォルトが適用されるようにします:
gh pr merge <number>
PR本文形式:
## Summary
<bullet points>
#### Test plan
- [ ] <checklist>
gh が利用できない場合:
- ブランチをプッシュします(手順6)。
- ユーザーが手動でPRを作成するために開くべきURLを表示します:
<repo-url>/compare/<default-branch>...<current-branch> - 停止します。ユーザー自身でPRを作成しマージしてもらいます。
ghなしでマージを試みないでください。
8. 現在のブランチを維持する
マージ後、作業ブランチを削除しないでください。次の機能のために開いたままにします。
9. 確認
PRのURL(該当する場合)とマージ/プッシュステータスをユーザーに報告します。
コンフリクト対応
フィーチャーブランチが <default-branch> より遅れている場合、プッシュ前にリベースします:
git fetch origin <default-branch>
git rebase origin/<default-branch>
コンフリクトを解決し、プッシュ + PR + マージを続行します。
注意事項
- ターゲットは常に検出された
<default-branch>であり、ハードコードされた名前ではありません。 - マージ後、作業ブランチを決して削除しないでください。
<default-branch>上の場合、コミットしてプッシュするだけです。PRは不要です。- ユーザーが急いでいても、検証ステップを決してスキップしないでください。
deslopステップはオプションです。スキルが見つからない場合、スキップにフォールバックする前にインストール(グローバルまたはローカル)を提案します。