diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 0000000..50b478d --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -0,0 +1,71 @@ +# 文件名必须与 npmjs.com → Package → Settings → Trusted publishing 中填写的 +# 「Workflow filename」完全一致(含 .yml)。 + +name: Publish to npm + +on: + push: + tags: + - 'v*' + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: npm + + - run: npm ci + - run: npm test + - run: npm run build + + publish: + needs: test + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + + steps: + - uses: actions/checkout@v4 + + # Trusted publishing 要求 Node ≥22.14 且 npm CLI ≥11.5.1(见 npm 文档) + - uses: actions/setup-node@v4 + with: + node-version: '22' + registry-url: 'https://registry.npmjs.org' + cache: npm + + - name: Verify tag matches package.json version + run: | + REF="${GITHUB_REF_NAME}" + TAG_VER="${REF#v}" + PKG_VER=$(node -p "require('./package.json').version") + if [ "$TAG_VER" != "$PKG_VER" ]; then + echo "::error::Tag is ${REF} but package.json version is ${PKG_VER}. Run \`npm version\` and push the new tag." + exit 1 + fi + + - run: npm ci + + # Trusted publishing 需要 npm ≥11.5.1(Node 22 自带的 npm 可能不够新) + - name: Ensure npm for Trusted publishing + run: npm install -g "npm@^11.5.1" + + # 二选一:未配置仓库 secret NPM_TOKEN 时使用 OIDC(需在 npm 配置 Trusted Publisher) + - name: Publish to npm (OIDC Trusted Publisher) + if: ${{ secrets.NPM_TOKEN == '' }} + run: npm publish --access public + + - name: Publish to npm (automation token) + if: ${{ secrets.NPM_TOKEN != '' }} + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + run: npm publish --access public diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..8139248 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,45 @@ +# 发布到 npm + +推送以 `v` 开头的 tag(例如 `v2.0.1`)会触发 [npm-publish.yml](.github/workflows/npm-publish.yml):先按 `.nvmrc` 跑测试与构建,再在 Node 22 上执行 `npm publish`。 + +## 本机操作(日常) + +1. 在 `master`(或发版分支)上确认变更已合并。 +2. 升级版本并打 tag(会生成一条 version commit): + + ```bash + npm version patch # 或 minor / major + git push origin master --follow-tags + ``` + + 若不想自动生成 commit,可手改 `package.json` 的 `version` 后提交,再: + + ```bash + git tag v$(node -p "require('./package.json').version") + git push origin v$(node -p "require('./package.json').version") + ``` + +3. **Tag 必须与 `package.json` 的 `version` 一致**(workflow 会校验,例如 tag `v2.0.1` 对应 version `2.0.1`)。 + +## 方式 A:OIDC Trusted Publisher(推荐) + +无需长期保存 npm 发布 token。 + +1. 登录 [npmjs.com](https://www.npmjs.com/) → 进入包 **jssm4** → **Settings** → **Trusted publishing**。 +2. 选择 **GitHub Actions**,填写仓库(如 `zhangyu921/jssm4`),**Workflow filename** 填:`npm-publish.yml`(与仓库内文件名一致)。 +3. 保存。确认 GitHub 仓库 **未** 设置 `NPM_TOKEN` secret(或留空逻辑走 OIDC 的那条分支)。 + +要求见 [npm 文档:Trusted publishing](https://docs.npmjs.com/trusted-publishers)(含 Node / npm CLI 版本说明)。 + +## 方式 B:Automation token + +1. npm 网站创建 **Granular access token** 或 **Automation token**(具备对该包的 **write**)。 +2. 在 GitHub 仓库 → **Settings** → **Secrets and variables** → **Actions** 中新增 **`NPM_TOKEN`**。 +3. 推送 tag 后,workflow 会使用 `NODE_AUTH_TOKEN` 发布。 + +配置 token 后,OIDC 步骤会被跳过;若同时配置了 Trusted Publisher,以你实际使用的认证方式为准。 + +## 发版后 + +- 在 GitHub 上为该 tag 写 **Release notes**(可选但建议)。 +- 若已启用 Trusted Publisher,可按 npm 文档考虑收紧「仅允许 OIDC 发布、禁用 token 发布」。