shipit-skill — 開発者ツール向けワンパスローンチパイプライン は何をしますか?
既存のリポジトリを「動く状態」から公開・リスト掲載・マーケティング可能な状態に導きます。 4 つのフェーズで構成され、各フェーズには厳格な出口基準があります。フェーズのスキップは、その出口基準が既に満たされている場合のみ許可されます。
哲学: 構築前にまず調査せよ。 何が既に存在し、エコシステムが何を要求しているかを最初に確認する — ユーザーに「車輪の再発明」をしないように助言するのと同じです。
フェーズ 0 — 偵察(常時30秒)
何かに手を触れる前に、以下のチェックを実行してください:
- 既存リポジトリの状態 —
git status、git remote -v、最近のgit log。 - パッケージ登録状況 — 名前は使われていますか?(
pip index versions <name>、npm view <name>、レジストリ CDN)。名前の衝突は頻繁に発生します。スコープ付き npm 名(@org/pkg)はタイポスクワッティングルールを回避できます。 - 類似プロジェクト — GitHub で直接の競合プロジェクトを検索してください。存在する場合は、差別化ポイントを明示的に記録し、単なるコピーを作らないでください。
- 「出口基準」のギャップ — CI は? Dockerfile は? GitHub Release は? Glama / awesome ディレクトリに掲載されている? プロモーション資料は最新? 不足しているもののチェックリストを作成します。このチェックリストが以降の作業の指針となります。
出力: 簡潔なギャップレポート + 計画。ギャップが大きい場合は、フェーズ 1 の前に確認を得てください。
フェーズ 1 — エンジニアリングベースライン
出口基準: デフォルトブランチで CI がグリーン、パッケージメタデータが正しい、Dockerfile が存在する(MCP/CLI サーバーの場合)。
- CI: GitHub Actions を追加。Python: サポート対象バージョンのマトリックスを組むが、より新しいインタープリタを必要とするエクストラに注意(例:
mcp>=2.0には py3.10+ が必要 — ベースは 3.9、エクストラは 3.12 でテスト)。常に lint + テスト + サーバーが出荷される場合はコンテナ MCP ハンドシェイクジョブを含める。 - Dockerfile: Glama やコンテナユーザーに必要。stdio MCP サーバーの場合: ベースイメージ + パッケージインストール +
CMD [サーバーコマンド]。公開パッケージが検証済みでない限り、ソースからビルド(COPY src) — 古い PyPI/npm リリースは静かにイントロスペクションを壊します。 .dockerignore: イメージを最小限に保つ(.git、テスト、プロモーション、ドキュメントを含めない)。- メタデータからのバージョン: MCP
serverInfo.versionと CLI--versionは、ハードコードされた文字列ではなくパッケージバージョンを読み取らなければなりません。 - 依存関係の下限: コードが新しい SDK API をターゲットにしている場合、依存関係の下限を設定してください(
mcp>=2.0)。>=1.0のままにしないでください — pip/npm は最新版に解決され、新規インストールを壊します。
検証: 一時的な venv で pip install .[extras] / npm install をクリーンに実行し、コンテナに対して MCP ハンドシェイク(initialize + tools/list)を実行します。
フェーズ 2 — 公開
出口基準: レジストリにパッケージ、タグ付きの GitHub Release とリリースノート、クリーンな環境でのインストール確認。
- バージョンアップ → ビルド成果物の生成(
python -m build/npm pack)。 - タグ + GitHub Release: タイトル
vX.Y.Z、リリースノートには 変更点 / インストール方法 / 修正内容 を含める。gh release createでタグからアタッチ。 - レジストリ公開:
- PyPI: トークンが必要(粒度はパッケージ単位、権限は Upload のみ)。トークンが不正な場合、PyPI は
403 Invalid or non-existent authentication informationを返します — UUID 形式の文字列は誤りです。実際の PyPI トークンはpypi-で始まります。twine uploadは--username __token__を使用。 - npm: スコープ付き名の場合は組織が存在する必要があります。自動化のためにはバイパス 2FA 権限付きの粒度トークンが必要。
--//registry.npmjs.org/:_authTokenをインラインで指定すれば、認証情報をディスクに書き込まずに済みます。
- PyPI: トークンが必要(粒度はパッケージ単位、権限は Upload のみ)。トークンが不正な場合、PyPI は
- 新規インストール確認(必須): venv / クリーンなディレクトリを作成し、レジストリからインストールし、モジュールをインポート / CLI を実行 / MCP ハンドシェイクを実施。これにより「私の環境では動く」パッケージングバグを検出できます。
- ハマりポイント:
- npm CDN は初回公開後も数分間 404 をキャッシュすることがあります — 慌てず、クエリパラメータでキャッシュを破棄してください。
- 再試行時に
File already existsエラーが出る場合、通常は初回の公開が成功しています。 - ロックファイルの不一致: パッケージ名を変更した場合は必ず
npm installを実行してロックファイルを再生成してください。そうしないと CI でnpm ciが失敗します。
フェーズ 3 — ディレクトリ登録
出口基準: Glama にスコアバッジ付きで掲載、かつ awesome PR が作成(またはマージ)されている。
- Glama (
glama.ai/mcp/servers): ユーザーがブラウザ経由で送信(GitHub OAuth — 自動化不可)。送信前に: Dockerfile が存在し、イントロスペクションに合格する必要があります(フェーズ 1 参照)。送信後、ページが表示されるまでに数分から数時間かかることがあります —https://glama.ai/mcp/servers/<owner>/<repo>と/badges/score.svgをポーリング。公開されたらリポジトリの README にバッジを追加:[](https://glama.ai/mcp/servers/owner/repo) - awesome-mcp-servers(および類似のキュレーションリスト): PR はボットによってトリアージされます。そのリストの現在の規約(バッジ + 言語 + スコープ + OS + インストールコマンド)に従ってフォーマットしてください。メンテナーは現在、エントリに Glama バッジを要求しています — Glama を先に提出してください。PR タイトルに
🤖🤖🤖を追加すると、エージェント高速トラックにオプトインできます。Fork → 最新のアップストリーム main からブランチを作成 → エントリを追加 → PR。以前の PR が非アクティブでクローズされた場合は、ブランチを force-push するか再作成してください。 - 他のディレクトリ(Smithery、PulseMCP、mcp.so など): Smithery はリポジトリルートの
smithery.yamlを読み取ります(stdio 起動コマンド + オプションの環境変数スキーマ)。
フェーズ 4 — プロモーション資料
出口基準: プロモーション資料のバージョン/リンク/PR 番号が実際と一致している。プラットフォームごとの投稿はペースト可能な状態であること(ユーザーが手動で投稿 — 偽の自動化は禁止)。
promo/ディレクトリにプラットフォームごとのファイル(V2EX、知乎、Reddit、X、コミュニティ)を管理。- 鮮度チェック(バージョンや PR が変更されるたびに実行): promo ファイル内の古いバージョン番号、切れた PR リンク、古いリリース URL を grep で検索。更新するか、古いものとしてマーク。
- 事実の正確性: 投稿前にすべての数値/主張を検証 — ツールを再実行して出力を比較してください。誤った主張はコメントで徹底的に攻撃されます(例: 「LICENSE がない」という主張が、実際は GitHub メタデータのちょっとした問題だったケース)。
- インストールコマンドはピン留めしない(
pip install pkg)ことで、プロモーション資料が陳腐化するのを防ぎます。
CLI クイックリファレンス (shipit-skill)
以下のコマンドでリポジトリを各フェーズに進めます。デフォルトではすべて表示のみで、副作用を伴うバリアントは --execute でオプトインします。
| コマンド | 動作 | 自動 / 表示のみ |
|---|---|---|
doctor [--json] | 環境自己チェック: gh 認証、トークン設定、main のクリーンなツリー | 表示;ギャップがあれば終了コード 1 |
preflight [--dir .] [--version X.Y.Z] [--json] | ローンチ準備態勢ギャップレポート | 表示 |
init <dir> --server <srv> --pkg <pkg> [--force] [--dry-run] | CI/Dockerfile/smithery.yaml/promo の雛形を作成 | ファイル書き込み |
ci --lang python [--server srv] [--write path] [--release] | ci.yml を出力;--release で release.yml を出力 | 表示 / 書き込み |
| `bump patch | minor | major |
release --lang python --pkg <pkg> [--repo o/r] [--execute] | doctor ゲート → バンプ→ビルド→公開→タグ→gh リリース→プロモーションチェック。タグ/リリースは公開成功後にのみ作成;公開失敗はコミットをロールバック;再実行は既存のタグ/リリースをスキップ;リリースノートは CHANGELOG から | 表示 / 実行 |
publish --lang python --pkg <pkg> [--server srv] [--execute] | レジストリアップロード(トークンは PYPI_TOKEN/NPM_TOKEN 環境変数から)+ 新規インストール確認 | 表示 / 実行 |
check-promo --dir promo --version X.Y.Z [--prs id=state,...] [--no-links] [--report] [--fix] | 古いバージョン / 不明な PR / 壊れたリンク;--report で JSON 出力;--fix で古いバージョンを書き換え + 不明な PR をマーク | 表示 / JSON / 修正 |
check-glama --repo o/r [--poll N] [--add-badge] [--json] | Glama 掲載を待機;--add-badge で掲載確認後に README にバッジを書き込み;--json で構造化出力 | 表示 / 書き込み |
awesome-pr --upstream o/r --repo o/r --fork o/r --branch b [--execute --category C --description D --install I] | PR レシピ、または実際に fork→編集→push→gh pr create | 表示 / 実行 |
トークン: ディスクに保存されません。publish/release --execute は PYPI_TOKEN または NPM_TOKEN を環境変数から読み取ります。ユーザーにトークンを要求し、インラインで渡します。
自動化の境界
| ステップ | 実行主体 |
|---|---|
| CI ファイル、Dockerfile、メタデータ、コード修正 | エージェント |
| ビルド成果物、新規インストール確認 | エージェント |
| レジストリ公開(PyPI/npm) | エージェント、ユーザーが提供するトークンを使用 |
| Glama ブラウザ送信 | ユーザー(OAuth) |
| awesome/その他 PR 作成 | エージェント |
| プラットフォームへの投稿 | ユーザー |
認証情報を決して偽造しないでください。トークンを明示的に要求し、インラインで使用し、決してファイルに書き込まないでください。
実戦での教訓(wheel-hub + zspace-cli の出荷から)
- エクストラに
mcp>=1.0を指定し新しい SDK を使用すると、新規インストールがクラッシュします。下限を設定してください。 - Python 3.9 では
mcp>=2.0をインストールできません。CI マトリックスはベースとエクストラを分割する必要があります。 - YAML ブロックスカラー + インラインの Python ヒアドキュメント = 壊れたワークフロー。スクリプトファイルを使用してください。
- MCP 2.x の
Serverオブジェクトにはlist_toolsがありません —@server.tool()デコレーターを使用してください。 - Glama イントロスペクションは、スモークテストで標準入力をしばらく開いたままにする必要があります(
sleep 1)。 - PyPI トークンの形式:
pypi-...が正しく、UUID は誤り。 - npm のタイポスクワッティング防止ルールは、
wheel-hubとwheelhubの併存をブロックします。スコープ付き名前が有効です。 .dockerignoreが欠けていると、巨大なイメージやビルドコンテキストへのシークレット漏洩の原因になります。