# 发布流程 > ⚠️ **这份文档是上游留下的,本 fork 没有照搬它的基础设施。** > 上游有 `.github/workflows/publish.yml`(OIDC + Trusted Publisher 自动发布)和 > `tools/check-doc-counts.mjs`(文档数字闸)。**这个 fork 两样都没有。** > 下面凡是引用它们的地方,都要按「本 fork 的实际做法」一节来读。 面向维护者。用户安装看 [README](../README.md)。 ## 一次版本发布(本 fork 的实际做法) 没有 CI,没有自动发布,全部手工: ```bash # 1. 改版本号:只有 package.json 的 version 是权威 # 本项目没有 package-lock.json(用 pnpm),所以没有需要同步的副本 # 2. 本地跑一遍验证,必须全绿(当前基线 130 项) node verify-groups.mjs node verify-behavior.mjs node verify-ack.mjs node verify-persona.mjs node verify-member-session.mjs node verify-title.mjs # 3. 语法自查(没有 CI 替你跑,这一步别省) for f in lib/*.js *.js *.mjs; do node --check "$f" || exit 1; done # 4. 看一眼真的会被装出去的是什么 npm pack --dry-run # 5. 提交并打 tag git add -A && git commit -m "1.0.5-groups.2:<改了什么>" git tag v1.0.5-groups.2 git push origin main --tags ``` > **这个 fork 还没发到 npm。** 如果哪天要发,`package.json` 里不能有 `private: true` > (本包没有这一项),并且要在 npm 上给包配一次 Trusted Publisher——见下面 > 「认证方式」一节,但**先把工作流文件补回来**,否则那套配置没有东西去用它。 ## QQ 没有构建步骤,所以这里和微信版不一样 | 微信那边有 | QQ 这边 | |---|---| | `pnpm build` / `pnpm run dist` | **没有**。本插件就是普通 JavaScript,仓库里的文件就是装出去的文件 | | `pnpm run pack` + `pnpm run verify-pack` | 换成 `npm pack --dry-run`:同样能列出实际进包的文件,而且不需要额外的打包脚本 | | `ERR_PNPM_PACKAGE_VERSION_NOT_FOUND` 这个坑 | **不存在**。那是 `pnpm pack` 在 private workspace 根目录上的行为;本包是单包、有 `version`,`npm pack` 也没有歧义 | | Git 安装要过 `allowBuilds` 询问 | **不用**。没有 `prepare` 脚本要跑,装下来直接能用 | | `matrix` 跑两个 Node 版本 | 上游只跑 Node 24。本 fork 不跑 CI,本地用哪个版本就说哪个版本 | ## 认证方式:OIDC,不用 token(⚠️ 本 fork 尚未配置) > **现状:这一节描述的是上游的做法,本 fork 没有对应的工作流。** > 如果你要启用自动发布,得先从上游把 `.github/workflows/publish.yml` 取回来, > 把它里面的仓库名改成本仓库,然后再做下面这次性配置。 工作流**不含任何密钥**。它用 GitHub 签发的 OIDC 身份向 npm 证明"我确实是这个仓库的这条工作流", npm 拿它跟包上配置的 **Trusted Publisher** 核对。 **这是一次性配置**,在 npmjs.com 上: ``` 包页面 → Settings → Trusted Publisher → GitHub Actions ``` 四个字段**逐字匹配**,填错的表现**只是发布时 403**——不会有别的提示,也不会有更早的警告: | 字段 | 值 | |---|---| | Organization or user | `104laiye` | | Repository | `dsh-qq-group-plugin` | | Workflow filename | **`publish.yml`** ← 是文件名,不是路径 | | Environment | **留空**(工作流没有 environment) | **为什么不用 token**(这段是历史,别再走回去): npm 在 2025-12 吊销了**全部经典 token**;替代它们的 granular token 带的"绕过 2FA"能力正在被限制—— 包页面顶部的横幅写着 direct publishing 到 **2027-01** 就不允许了。**Trusted Publisher 是 npm 自己推荐的 替代方案**,而且更彻底:**没有密钥可以泄漏、轮换或过期**。 > 所以:**不需要创建任何 secret。** 如果你看到旧文档说要配 `NPM_TOKEN`,那是过期信息。 ## 其他前提 | 项 | 位置 | 说明 | |---|---|---| | 仓库为 public | 仓库 Settings | `--provenance` 需要公开仓库才能生成可信签名 | | `id-token: write` | 需在工作流里 | OIDC 握手用;删了它发布必然失败,而且**没有别的凭据可以退回去**。本 fork 目前没有这个工作流 | | 仓库名是 `dsh-qq-group-plugin` | 仓库 Settings | Trusted Publisher 的 Repository 字段和它逐字一致 | **先干跑一次**:Actions → Publish → Run workflow,`dry-run` 默认 true,会把所有校验跑一遍但不发布。 (同样,本 fork 没有这个工作流。) ## 版本号该改哪里 只有 `package.json` 的 `version` 是权威。本项目**没有 `package-lock.json`**——用的是 pnpm, `pnpm-lock.yaml` 里不含版本号副本,所以不存在"两处不一致"的问题。 > **上游那一套「三处文档写着同一组测试数量、由 check-doc-counts.mjs 把关」在本 fork 不存在。** > 那三套测试(`scripts/`)、那个闸(`tools/`)、那份 workflow 都没搬过来。 > 本仓库唯一的测试是根目录那六个 `verify-*.mjs`,**130 项**,手记在这里和 README 里就行。 ## 出问题怎么查 | 现象 | 原因 | |---|---| | 发布时 **403**,且信息提到 trusted publisher | npm 那四个字段有拼写不符(最常见:把 workflow 写成路径 `.github/workflows/publish.yml`)。本 fork 没有自动闸,只能自己核对上表 | | 发布时 403,且提到 2FA | Trusted Publisher 没配上,npm 退回到了"要求 2FA"的老路径 | | `npm publish` 直接说包是 private | `package.json` 里的 `private: true` 没删 | | provenance 报错 | 仓库是 private,或 workflow 缺 `id-token: write` | | 发布后 npm 页面还是旧版本,且注册表报 404 | **首次发布新版本要人工审核**,几分钟后自动上线。`npm view dsh-qq-group-plugin versions` 里没出现就是还在审 | | tag 与版本不一致 | 忘了改 `package.json` 的 `version` | | 干跑打印了 "dry run: everything above passed" 之后什么都没发生 | **这是预期**:`dry-run` 默认 true,只跑校验不发布。真要发就推 tag | | 发布成功但用户装不了 | 少了 `files` 条目。先跑 `npm pack --dry-run` 看实际清单——它列出什么,用户就装到什么 | | 用户装到旧版本 | profile 的 `package.json` 里**锁了精确版本**。写 `^x.y.z` 才会跟着升 | | 改完 `files` 本地一切正常,CI 却红了 | 本 fork 没有 CI,这条不适用;用 `npm pack --dry-run` 看清单即可 |