Communitygithub.com

SSBrouhard/npm-package-release-hardening

用於強化 npm 套件發布流程的代理技能——在公開發布前偵測內嵌的機密資訊、執行環境不符問題與壓縮包垃圾檔案。可在任何支援技能的代理程式中使用。

npm-package-release-hardening 是什麼?

這項技能旨在將 npm 套件從「本地可運作」狀態提升至「誠實、可審查且可安全發布」的狀態。它優先考慮真實的驗證而非感覺,重點檢查套件的壓縮包內容、執行環境契約、CI/CD 流程、GitHub 設定以及相依性更新衛生。技能支援 npm、pnpm 和 yarn 等套件管理工具,並能自動根據 lockfile 偵測使用何種工具。它會驗證 package.json 的真實性(如名稱、版本、授權、入口點等)、執行環境地板規則(engines.node)、進行壓縮包審查、確保 GitHub 基礎設定(CI、Dependabot、CODEOWNERS 等)完善,並提供分支保護與發布前檢查清單。最終回報僅包含實際驗證過的項目,確保發布流程的透明度與安全性。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add SSBrouhard/npm-package-release-hardening

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

npm 套件發布強化

目標

將 npm 套件從「本地可運作」狀態提升至「誠實、可審查且可安全發布」的狀態。優先進行真正的驗證而非感覺:套件壓縮包內容、執行環境契約、CI、GitHub 設定以及相依性更新衛生。

從這裡開始

  1. 確認確切的儲存庫:
pwd
git status --short --branch
git remote -v
  1. 檢查套件表面:
cat package.json
ls -la
find .github -maxdepth 3 -type f -print 2>/dev/null
  1. 從 lockfile 偵測套件管理工具:
  • package-lock.json -> npm
  • pnpm-lock.yaml -> pnpm
  • yarn.lock -> yarn

以下使用 npm 指令作為預設值,但請在需要時轉換為偵測到的套件管理工具對應指令。

套件契約

確保 package.json 說實話:

  • name:發布目標是有意圖且可用的
  • version:當前預期發布的版本
  • description、keywords:對註冊表搜尋足夠實用
  • license:存在且與 LICENSE 檔案相符
  • repository、homepage、bugs:指向公開儲存庫。如果公開儲存庫 URL 尚未最終確定,請將其標記為發布前的明確待辦事項,而不是默默地省略它們
  • type、exports、main、bin:與使用者將匯入或執行的內容相符
  • files:將壓縮包限制為可發布的成品
  • engines.node:套件實際支援的最低執行環境
  • prepublishOnly 或等效指令:防止發布過時的建置輸出

對於 CLI 套件,請確認 bin 目標已建置、在相關情況下可執行,並透過使用者將執行的指令進行冒煙測試。

執行環境地板規則

Node 引擎是一個承諾,而非裝飾。

  • 如果 engines.node 設定為 >=20,則 CI 必須測試 Node 20。
  • 保持 @types/node 與最低支援執行環境的主要版本行一致。
  • 建議將 @types/node 精確鎖定在該執行環境行的最新修補版本。
  • 除非同時提高 engines.node,否則不要合併高於執行環境地板的 @types/node 主要版本變更。
  • engines.node 是建議性質的:npm 只會發出警告,除非使用者設定 engine-strict,否則不會強制阻止安裝,因此在地板版本上執行 CI 才是真正執行承諾的方式。

原因:Node 型別僅供開發使用,但它們會改變 TypeScript 所允許的內容。@types/node@26 可能會允許程式碼編譯,但會使用對 Node 20 使用者來說會失敗的 API。

驗證指令

對於 npm 專案:

npm ci
npm run build --if-present
npm test --if-present
npm audit --omit=dev
npm pack --dry-run

對於 pnpm/yarn,請使用等效的 install/build/test/audit/pack 指令。如果審計支援不同,請直接說明,不要假裝。

對於 CLI,也請至少執行一項由外向內的冒煙測試:

node dist/path/to/cli.js --help
npm pack --dry-run

如果可行,請將打包好的 .tgz 安裝在臨時目錄中,並完全按照使用者的方式執行二進位檔。

壓縮包審查

npm pack --dry-run 是註冊表的事實真相。檢查內容:

  • 包含建置輸出
  • 包含 README.md 和 LICENSE
  • 排除僅限原始碼的垃圾檔案、暫存檔、測試檔、私人文件、測試裝置、本地資料庫、機密資訊
  • 套件大小合理
  • CLI bin 路徑出現在壓縮包中

如果缺少 files 欄位,請新增它。不要依賴 .gitignore 作為發布政策。

GitHub 基礎設定

新增或驗證:

  • .github/workflows/ci.yml
  • .github/dependabot.yml
  • .github/CODEOWNERS
  • .github/pull_request_template.md
  • SECURITY.md

對 GitHub 擁有的 action 使用目前支援的主要版本。如果 Actions 警告某個 action 執行環境已棄用,請在 CI 通過後更新該 action 的主要版本。

CI 通常應包含:

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@CURRENT_MAJOR
      - uses: actions/setup-node@CURRENT_MAJOR
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm run build --if-present
      - run: npm test --if-present

將 node-version 調整為套件的最低支援執行環境,並將每個 @CURRENT_MAJOR 替換為 action 的當前主要版本標籤(例如 actions/checkout@v4)——鎖定到一個真實的主要版本,切勿提交佔位符。

Dependabot 基礎設定

同時設定套件和 GitHub Actions 更新:

version: 2
updates:
  - package-ecosystem: npm
    directory: /
    schedule:
      interval: weekly
    open-pull-requests-limit: 5
    commit-message:
      prefix: deps
      include: scope

  - package-ecosystem: github-actions
    directory: /
    schedule:
      interval: weekly
    open-pull-requests-limit: 5
    commit-message:
      prefix: deps
      include: scope

當 Dependabot 在設定落地後立即開啟 PR 時,請將其視為設定已生效的證據。分類這些 PR;不要盲目地合併所有通過檢查的 PR。

Dependabot 分類

使用以下經驗法則:

  • 執行環境相依性的修補/次要版本:如果檢查通過且發布說明無關緊要,則合併。
  • 執行環境相依性的主要版本:檢查發布說明並對真實套件行為進行冒煙測試。
  • 開發工具的主要版本:如果建置/測試/打包通過且不改變執行環境契約,則合併。
  • 高於執行環境地板的 @types/node:關閉或替換為鎖定到執行環境地板的版本。
  • GitHub Actions 的主要版本:如果 CI 通過且移除了棄用警告,則合併。

如果有兩個 PR 在小型設定檔中發生衝突,請合併其中一個並更新另一個,或直接應用第二個 PR,並附上明確的註解說明它已被取代。

GitHub 遠端強化

套用儲存庫/帳戶支援的設定,然後使用 gh 或 API 讀取來驗證實際設定。

有用的設定:

gh repo edit OWNER/REPO \
  --delete-branch-on-merge \
  --enable-squash-merge \
  --enable-merge-commit=false \
  --enable-rebase-merge=false \
  --allow-update-branch

gh api --method PUT repos/OWNER/REPO/vulnerability-alerts --silent
gh api --method PUT repos/OWNER/REPO/automated-security-fixes --silent
gh api --method PUT repos/OWNER/REPO/actions/permissions/workflow \
  -f default_workflow_permissions=read \
  -F can_approve_pull_request_reviews=false --silent

對於 Actions 允許清單,當工作流程僅使用 GitHub 擁有的 action 時,建議僅使用 GitHub 擁有的 action。如果需要第三方 action,請明確允許最小的集合。

公開儲存庫通常會解鎖更多安全性控制項。免費方案上的私人儲存庫可能會封鎖:

  • 分支保護或規則集
  • 程式碼掃描
  • 機密掃描
  • 推送保護

直接說明封鎖項目。不要將不可用的控制項回報為已啟用。

分支保護

當可用時,使用以下設定保護預設分支:

  • 合併前需要拉取請求
  • 需要 CI 狀態檢查
  • 如果需要,要求分支保持最新
  • 需要解決對話
  • 封鎖強制推送
  • 封鎖刪除
  • 如果使用僅限壓縮合併,則要求線性歷史

啟用保護後,除非使用者明確要求並理解繞過方式,否則停止直接推送到 main。

閘道 PR 工具

如果使用自動化審查/閘道工具,請在要求閘道建立 PR 之前,確保遠端有預設/基礎分支。新的空白遠端通常需要先進行初始的 main 推送;否則閘道可以驗證並推送功能分支,但會因為沒有基礎引用而無法建立 PR。

發布檢查清單

在 npm publish 之前:

  • npm whoami 顯示預期的帳戶
  • npm view PACKAGE_NAME name version 確認名稱狀態
  • 要發布的提交上的 CI 為綠色
  • 已審查 npm pack --dry-run 的結果
  • README 中的安裝/使用範例與實際行為相符
  • repository、homepage 和 bugs 能解析到真實的公開儲存庫(如果 URL 尚未最終確定,則明確標記為待辦事項)
  • 沒有阻止發布的 Dependabot/安全性警示遺留
  • 版本提升是有意圖的,已在 git 中標記(git tag vX.Y.Z && git push --tags),並反映在 CHANGELOG 或 GitHub Release 中
  • 作用域套件(@scope/name)使用 --access public 發布(作用域套件預設為限制/私人)

對於使用網頁/通行金鑰/2FA 驗證的帳戶:

npm publish --auth-type=web

建議從 CI 發布,並使用 Provenance 來建立可驗證的供應鏈連結。Provenance 需要公開套件、支援的 CI(例如 GitHub Actions)以及工作上的 id-token: write 權限:

npm publish --provenance --access public

發布後:

npm view PACKAGE_NAME version
npm view PACKAGE_NAME bin files engines repository --json
npx -y PACKAGE_NAME --help

如果使用 Provenance 發布,請確認註冊表在套件頁面上顯示了 Provenance /「Built and signed」證明。

最終回報

僅報告實際驗證過的項目:

  • 已執行的套件檢查
  • 壓縮包結果
  • 相依性 PR 決策
  • 已建立或合併的提交/PR
  • 已確認的 GitHub 設定
  • 因方案/能見度而封鎖的控制項
  • 發布標籤和 Provenance 狀態(如果已發布)
  • 發布指令或發布後驗證(如果仍由使用者擁有)

相關技能