shipit-skill — 開發者工具的一次性發布流程
將現有儲存庫從「跑得起來」推進到已發布 + 已列舉 + 可行銷。 共分四個階段,每個階段都有嚴格的退出條件。只有當退出條件已經滿足時,才能跳過該階段。
哲學:先觀察再建造。 先檢查既有的東西與生態系統的要求 — 就像你建議任何使用者不要重新發明輪子一樣。
第 0 階段 — 偵查(30 秒,一定要執行)
在動任何東西之前,執行以下檢查:
- 現有儲存庫狀態 —
git status、git remote -v、最近的git log。 - 套件註冊 — 名稱是否已被佔用?(
pip index versions <名稱>、npm view <名稱>、註冊表 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 會解析到最新版本並破壞全新的安裝。
驗證:在一個臨時虛擬環境中執行乾淨的 pip install .[extras] / npm install,然後針對容器執行 MCP 握手(initialize + tools/list)。
第 2 階段 — 發布
退出條件:套件已在註冊表上、GitHub Release 帶有標籤與說明、乾淨環境安裝已驗證。
- 版本提升 → 建構工件(
python -m build/npm pack)。 - 標籤 + GitHub Release:標題
vX.Y.Z,說明包含 Changes / Install / What-it-fixes。讓gh release create從標籤附加。 - 註冊表發布:
- PyPI:需要一個 token(細粒度的,限定範圍到該套件,Upload 權限)。如果 token 格式錯誤,PyPI 會回傳
403 Invalid or non-existent authentication information— UUID 風格的字串是錯誤的;真正的 PyPI token 以pypi-開頭。使用--username __token__的twine upload。 - npm:作用域名稱需要組織存在;用於自動化的細粒度 token 需繞過 2FA;
--//registry.npmjs.org/:_authToken內聯方式可避免將憑證寫入磁碟。
- PyPI:需要一個 token(細粒度的,限定範圍到該套件,Upload 權限)。如果 token 格式錯誤,PyPI 會回傳
- 全新安裝驗證(不可妥協):建立一個虛擬環境 / 乾淨目錄,從註冊表安裝,匯入模組 / 執行 CLI / 執行 MCP 握手。這可以捕捉到「在我的機器上可以」的打包錯誤。
- 陷阱:
- npm CDN 在首次發布後會提供數分鐘的緩存 404 — 不要驚慌,使用查詢參數清除緩存。
- 重試時出現
File already exists通常表示第一次嘗試成功了。 - 鎖定檔案偏移:重新命名套件 → 總是執行
npm install重新產生鎖定檔,否則npm ci會在 CI 中失敗。
第 3 階段 — 目錄列舉
退出條件:已列在 Glama 上並有評分徽章且awesome PR 已開啟(或已合併)。
- Glama(
glama.ai/mcp/servers):使用者透過瀏覽器提交(GitHub OAuth — 無法自動化)。提交前:Dockerfile 必須存在並通過內省檢查(請參閱第 1 階段)。提交後:頁面需要幾分鐘到幾小時才會出現 — 輪詢https://glama.ai/mcp/servers/<擁有者>/<儲存庫>和/badges/score.svg。一旦上線,將徽章加入儲存庫 README:[](https://glama.ai/mcp/servers/擁有者/儲存庫) - awesome-mcp-servers(以及其他精選清單):PR 由機器人審核。格式需符合清單當前的慣例(徽章 + 語言 + 範圍 + 作業系統 + 安裝指令)。維護者現在要求條目中包含 Glama 徽章 — 先提交 Glama。在 PR 標題中加入
🤖🤖🤖以選擇加入代理快速通道。Fork → 從最新的上游主分支建立分支 → 加入條目 → PR。如果先前的 PR 因不活躍而被關閉,請強制推送該分支或重新建立它。 - 其他目錄(Smithery, PulseMCP, mcp.so…):Smithery 會讀取儲存庫根目錄下的
smithery.yaml(stdio 啟動命令 + 可選的環境變數 schema)。
第 4 階段 — 推廣資料
退出條件:推廣文件的版本/連結/PR 編號與實際情況相符;各平台的貼文已準備好可貼上(使用者手動發文 — 沒有偽造的自動化)。
- 維護
promo/目錄,內含針對各平台的檔案(V2EX, 知乎, Reddit, X, 社群)。 - 新鮮度檢查(每當版本/PR 變更時執行):在推廣檔案中搜尋舊版本號碼、失效的 PR 連結、過時的發布 URL。更新或標記為過時。
- 事實紀律:發文前驗證每個數字/聲明 — 重新執行工具並比較輸出。錯誤的主張會在留言中被攻擊(例如,一個「沒有 LICENSE」的主張,實際上只是 GitHub 中繼資料的怪異現象)。
- 保持安裝指令不固定版本(
pip install pkg),這樣推廣資料就不會過時。
CLI 快速參考(shipit-skill)
執行以下命令來推動儲存庫通過各個階段。預設情況下,所有操作只會印出;會產生副作用的多為選擇性加入,需加上 --execute。
| 命令 | 作用 | 自動 / 印出 |
|---|---|---|
doctor [--json] | 環境自我檢查:gh 已認證、token 已設定、主分支上工作目錄乾淨 | 印出;有缺口時 exit 1 |
preflight [--dir .] [--version X.Y.Z] [--json] | 發布就緒度缺口報告 | 印出 |
init <dir> --server <srv> --pkg <pkg> [--force] [--dry-run] | 建立 CI/Dockerfile/smithery.yaml/推廣資料的骨架 | 寫入檔案 |
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 release→推廣檢查。只有在發布成功後才會建立標籤/Release;發布失敗會復原提交;重新執行會跳過已存在的標籤/Release;說明來自 CHANGELOG | 印出 / 執行 |
publish --lang python --pkg <pkg> [--server srv] [--execute] | 註冊表上傳(token 來自 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→編輯→推送→gh pr create | 印出 / 執行 |
Token:從不儲存在磁碟上。publish/release --execute 從環境變數讀取 PYPI_TOKEN 或 NPM_TOKEN;提示使用者提供並內聯傳遞。
自動化邊界
| 步驟 | 誰執行 |
|---|---|
| CI 檔案、Dockerfile、中繼資料、程式碼修正 | Agent |
| 建構工件、全新安裝驗證 | Agent |
| 註冊表發布(PyPI/npm) | Agent,使用使用者提供的 token |
| Glama 瀏覽器提交 | 使用者(OAuth) |
| awesome/其他 PR 建立 | Agent |
| 在各平台發文 | 使用者 |
絕對不要偽造憑證;明確要求提供 token 並內聯使用,絕不將其寫入檔案。
實戰疤痕(來自出貨 wheel-hub + zspace-cli)
mcp>=1.0在額外依賴中加上新版 SDK → 全新安裝會崩潰。請設定下限。- Python 3.9 無法安裝
mcp>=2.0;CI 矩陣必須區分基礎與額外依賴。 - YAML 區塊標量 + 內聯 Python heredoc = 損壞的工作流程。請使用指令碼檔案。
- MCP 2.x 的
Server物件沒有list_tools— 請使用@server.tool()裝飾器。 - Glama 內省需要在冒煙測試中將 stdin 保持開啟一段時間(
sleep 1)。 - PyPI token 格式:
pypi-...是真實的,UUID 是錯誤的。 - npm 的拼寫錯誤阻擋了
wheel-hub緊鄰wheelhub;作用域名稱有效。 .dockerignore遺漏 → 映像檔過大 / 建構上下文中包含秘密。