发布指南
本指南说明 dependfix 的 npm 发布流程、版本策略与发布自动化配置。
发布包清单
包清单单点声明:发布包列表定义在 scripts/packages.config.mjs(
publishable: true的包进入发布链路,npmPublishable !== false的包进入 npm 发布)。 新增发布包时:① 在该文件登记;② 补充包 README;其余(changelog 生成、release 计划映射、CI 校验)自动生效。
当前 Monorepo 的发布单元:
| 包 | 说明 | npm 地址 |
|---|---|---|
dependfix | CLI 应用入口(含 dependfix bin 命令,薄壳:参数解析 + runner) | https://www.npmjs.com/package/dependfix |
@dependfix/core | 核心领域模型库 | https://www.npmjs.com/package/@dependfix/core |
@dependfix/engine | 执行引擎(编排/采集/修复/研判,cli/mcp/platform 共享) | https://www.npmjs.com/package/@dependfix/engine |
@dependfix/skills | 产品 Agent Skill 权威源(dependfix-remediator,纯内容包) | https://www.npmjs.com/package/@dependfix/skills |
@dependfix/mcp | MCP Server(stdio 传输,7 个 tool 暴露扫描/修复能力) | https://www.npmjs.com/package/@dependfix/mcp |
@dependfix/platform | Nuxt 管理平台(控制面:仓库/凭据管理、扫描触发、结果展示)—— 不发布到 npm,仅 docker 通道 | — |
依赖关系:
dependfix依赖@dependfix/core、@dependfix/engine与@dependfix/skills(运行时解析 skill 内容);@dependfix/engine依赖@dependfix/core;@dependfix/mcp依赖@dependfix/core与@dependfix/engine;apps/platform依赖@dependfix/core、@dependfix/engine与dependfix(仅 build 期,不进入发布图)。npm 发布顺序:被依赖方先行(@dependfix/core→@dependfix/engine→@dependfix/skills→dependfix→@dependfix/mcp)。@dependfix/platform走npmPublishable: false的 tag-only 分支:跳过pnpm publish但仍创建 annotated tag,与 docker publish 通道协作(详见"platform 发布通道")。
platform 发布通道(独立于 npm)
apps/platform 是 Nuxt 应用而非 npm 库,参与 release 链路的目的是"版本号 + CHANGELOG + git tag"三件套,与 docker 镜像协作:
- 版本号:
apps/platform/package.json:version独立递增,semver 由release:version维护(dependency backflow:core/engine/cli 升级时 platform 至少 patch 跟随) - CHANGELOG:
apps/platform/CHANGELOG.md由pnpm changelog按path: 'apps/platform'过滤生成(与其他 5 个 npm 包走同套scripts/changelog.mjs流水线) - Git tag:
release:publish检测npmPublishable === false→ actiontag-only:跳过pnpm publish、仍创建@dependfix/platform@<x.y.z>annotated tag(保证 changelog 历史可比) - Docker tag:
release.yml完成后主动workflow_dispatch docker.yml,传platform_version入参;docker.yml 仅在 inputs 非空时打platform-<x.y.z>tag(与latest+YYYY-MM-DD+sha-<short>三元组并列;master push 触发时 inputs 为空,仅打原三元组) - 版本号治理:
apps/platform加入packages.config.mjs的PACKAGES列表(publishable: true / rootChangelog: false / publishOrder: 6 / npmPublishable: false);依赖dependabot的apps/platform/package.json排除(避免 dependabot 接管平台版本) - 历史背景:platform 改动历史已聚合进根 CHANGELOG 的
dependfix@x.y.z段(如dependfix@0.3.3段内**platform:**scope 多条),T1310 后改为独立apps/platform/CHANGELOG.md,根段不再以 platform 内容为主。
版本策略
- 0.x 即预览版:当前处于开发阶段,
0.1.0及后续0.x版本直接作为latest发布,不加beta等预发布后缀。理由:0.x在 semver 中本身就是"初始开发、API 不稳定"语义,已充分表达预览状态;- npm 默认不安装带预发布后缀的版本(需显式
dependfix@beta),会给预览测试设置障碍。
- 稳定信号来自
1.0.0:API 稳定后发布1.0.0,届时再启用@v1滚动 tag(GitHub Action 引用)。 - tag 推送纪律:git 默认不推送 tag——本地开发建议
git config --global push.followTags true(日常 push 自动带 annotated tag);补打 tag 后必须显式--tags推送并核验(教训见 经验归档 §二十六)。 - 版本号由自研 release 脚本管理:
pnpm release:plan基于 git log 自动推导各包 bump 级别(见"release:plan 生成规则"),可人工修正;pnpm release:version执行版本提升(含依赖传导);CHANGELOG 由pnpm changelog基于 conventional commits 生成(见"CHANGELOG 策略")。设计文档见 release-pipeline.md。
发布架构
| 阶段 | 触发方式 | 认证方式 | 发布命令 |
|---|---|---|---|
首次发布 0.1.0 | 手动(一次性) | npm 账号登录(npm login) | pnpm publish(本地) |
后续版本 0.1.1+(0.x 阶段) | workflow_dispatch 手动触发 | OIDC Trusted Publishing(无 NPM_TOKEN) | pnpm release:publish(CI) |
1.0.0+(正式版,规划) | 手动 + schedule 定时自动发布(可选 push) | OIDC Trusted Publishing | pnpm release:publish(CI) |
0.x 阶段仅手动发布:
release.yml未启用on.push/on.schedule自动触发(每次推送触发 release 不符合 0.x 预览期的发布节奏)。定时自动发布配置已按 momei 模式内嵌(每周六 UTC+0 12:00 = UTC+8 20:00),1.0.0 正式版发布后取消schedule注释即可启用,自动发布逻辑(版本提升 + 日志生成 + 提交推送)无需额外配置。发布底层始终是
pnpm publish(release:publish内部调用它),它会自动把workspace:*依赖替换为实际版本号,保证发布产物可被消费者正常安装。不要改用裸npm publish:npm 不会替换workspace:*,会把字面量发布到 registry。
前置配置(一次性)
1. npmjs.com 配置 Trusted Publisher
为每个包分别配置(每个包只能配置一个 Trusted Publisher):
- 打开
https://www.npmjs.com/package/<包名>/access(注意是包级设置页,不是账号设置页); - 在 Trusted Publisher 区域点击添加;
- 选择 GitHub Actions 并填写:
- Organization or user:
dependfix - Repository:
dependfix - Workflow filename:
release.yml - Allowed actions:
npm publish
- Organization or user:
- 五个包(
dependfix、@dependfix/core、@dependfix/engine、@dependfix/skills与@dependfix/mcp)都要配置。
⚠️ 包必须已存在于 npm 上才能配置 Trusted Publisher(npm/cli#8544)。因此尚未发布的新包(如
@dependfix/engine、@dependfix/mcp)的首次发布必须先手动完成(见下),之后才能配置并启用 OIDC。
2. package.json 元数据
repository.url 建议与 GitHub 仓库保持一致(dependfix/dependfix,大小写敏感):OIDC 的匹配依据是 npmjs.com 上配置的 Trusted Publisher,provenance 依据 GitHub Actions 环境,两者虽不读取该字段,但保持正确有利于 npm 包页展示与发包工具校验:
{
"homepage": "https://github.com/dependfix/dependfix#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/dependfix/dependfix.git"
},
"bugs": {
"url": "https://github.com/dependfix/dependfix/issues"
}
}3. CI 环境要求
- pnpm 版本:发布走
pnpm publish的 OIDC 路径。pnpm 11.0.3 存在 OIDC 回归(pnpm/pnpm#11566,已修复),CI 使用pnpm/action-setup@v4默认解析的最新 pnpm(11.x 后期 / 12.x)即可; release.yml已配置permissions: id-token: write。
首次发布(0.1.0,手动,一次性)
前置条件:
pnpm publish默认执行 gitChecks(当前分支为master、工作区干净、与 remote 同步),不满足会中止发布。先确认:
git branch --show-current # 期望 master
git status --porcelain # 期望无输出(工作区干净)
git fetch && git log HEAD..@{u} # 期望无输出(无落后提交)正式发布:
# 1. 质量门全绿
pnpm lint
pnpm typecheck
pnpm test
pnpm build
# 2. 检查包内容(确认 dist / bin / README / LICENSE 都在;@dependfix/skills 为纯内容包,确认 dependfix-remediator/ 与 README 在发布内容中)
pnpm --filter @dependfix/core pack --pack-destination "$env:TEMP" # Windows PowerShell
pnpm --filter @dependfix/engine pack --pack-destination "$env:TEMP" # Windows PowerShell
pnpm --filter @dependfix/skills pack --pack-destination "$env:TEMP" # Windows PowerShell
pnpm --filter dependfix pack --pack-destination "$env:TEMP" # Windows PowerShell
pnpm --filter @dependfix/mcp pack --pack-destination "$env:TEMP" # Windows PowerShell
# bash/zsh 使用:pnpm --filter @dependfix/core pack --pack-destination /tmp
# 3. 本地试跑构建产物
node packages/cli/dist/bin.mjs --help
# 4. npm 登录(一次性,pnpm publish 复用 npm 凭据)
npm login
# 5. 发布(顺序重要:被依赖方先行——@dependfix/core → @dependfix/engine → @dependfix/skills → dependfix → @dependfix/mcp)
# 必须使用 pnpm publish:它会替换 workspace:* 为实际版本
pnpm --filter @dependfix/core publish
pnpm --filter @dependfix/engine publish
pnpm --filter @dependfix/skills publish
pnpm --filter dependfix publish
pnpm --filter @dependfix/mcp publish
# 6. 打 tag(手动发布**不会**自动创建 tag,必须手动补打 `<pkg>@<version>` 格式:
# changelog 分段锚点与 release:plan 推导基线都依赖它——参照 scripts/changelog.mjs 的
# tags.prefix(`git rev-parse --verify <prefix><version>`)与 scripts/create-release-plan.mjs
# 的"最新 tag"基线解析;缺失时后续 changelog 分段会把全部历史并入当前版本段)
# 推荐用脚本辅助(自动检测"npm 已发布但本地无 tag"的版本并补打,锚点自动取
# touch 该包路径的最新 commit,幂等可重跑):
pnpm tag:released --dry-run # 预览将创建的 tag(针对当前 package.json 版本,建议每次发布后立即执行)
pnpm tag:released # 确认后执行补打
# 手动方式(锚点约束:每个 tag 必须指向"同时 touch 该包路径"的 commit,
# 见"CHANGELOG 策略";锚点查询:git log -1 --format=%H -- packages/<path>):
git tag @dependfix/core@0.1.0 <core-anchor> # 指向 touch packages/core 的 commit
git tag @dependfix/engine@0.1.0 <engine-anchor> # 指向 touch packages/engine 的 commit
git tag @dependfix/skills@0.1.0 <skills-anchor> # 指向 touch packages/skills 的 commit
git tag dependfix@0.1.0 <cli-anchor> # 指向 touch packages/cli 的 commit
git tag @dependfix/mcp@0.1.0 <mcp-anchor> # 指向 touch packages/mcp 的 commit
git tag v0.1.0 # (可选)GitHub Release 展示用
git push origin --tags
# 推送后核验(tag 曾因 CI 静默失败/本地漏推而长期不同步,教训见经验归档 §二十六):
git fetch origin --tags && git tag | while read t; do git ls-remote --tags origin "$t" >/dev/null || echo "未同步: $t"; done
# 7. 验证
npm view dependfix version # 期望 0.1.0,dist-tags.latest
npm view @dependfix/core version # 期望 0.1.0
npm view @dependfix/engine version # 期望 0.1.0
npm view @dependfix/skills version # 期望 0.1.0
npm view @dependfix/mcp version # 期望 0.1.0
npm view dependfix dependencies # 期望 @dependfix/core 与 @dependfix/skills 为具体版本(非 workspace:*)
npm i -g dependfix && dependfix --version # 或临时目录 npx dependfix --help
# 8.(可选)GitHub Release(预览版标记 pre-release)
gh release create v0.1.0 --generate-notes --prerelease
# 9. 在 npmjs.com 为五个包配置 Trusted Publisher(见"前置配置")后续版本(0.1.1+)
release:plan 生成规则
版本提升级别由 pnpm release:plan(scripts/create-release-plan.mjs)从 git log 自动推导,规则参照 semantic-release / conventionalcommits:
| commit 类型 | bump | 说明 |
|---|---|---|
feat | minor | |
fix / perf / revert | patch | |
BREAKING(! 后缀或 BREAKING CHANGE: footer) | 0.x → minor;1.0.0+ → major | 0.x 阶段不直接跳到 1.0.0(0.x 语义中 minor 即可表达破坏性变更) |
refactor / docs / chore / build / ci / test / style | 不 bump | 变更仍会进入 CHANGELOG,随同轮其他发布附带 |
- 包影响面:按 commit 改动路径映射(
packages/core→@dependfix/core、packages/cli→dependfix、packages/skills→@dependfix/skills);依赖传导(如 core 升级后 cli 的依赖范围更新)由release:version的传导闭包自动处理,无需手动声明; - 每轮只保留一个计划文件:固定文件名为根目录
release-plan.md(gitignore 临时产物:生成 → 人工 review →release:version消费后删除);脚本检测到该文件已存在时会拒绝覆盖(防止丢失人工修正),需先删除或人工合并; - 人工兜底(生成后必须 review):
- breaking 判定只识别 commit 中显式标注的
!/BREAKING CHANGE:footer,未标注的破坏性变更(如以build:类型提交的纯 ESM 改造)需手动修正计划文件的 bump 级别; - 推导基线为最新 git tag,若存在"手动发布但未打 tag"的版本(如
@dependfix/skills0.1.0 手动发布晚于v0.1.0tag),推导会包含已发布内容——按实际发布决策剔除本轮不发布的包; - summary 仅为 git 追踪可读说明,不进 CHANGELOG(见"CHANGELOG 策略"),无需精心撰写。
- breaking 判定只识别 commit 中显式标注的
常规流程
# 1. 自动生成发布计划(从 git log 推导版本提升级别,生成 release-plan.md,见"release:plan 生成规则")
pnpm release:plan
# 2. 人工 review release-plan.md:检查 bump 级别与包清单,剔除本轮不发布的包,
# 修正未标注 breaking 的破坏性变更;确认无误后继续
# 3. 版本提升(消费 release-plan.md:依赖传导计算 + 更新各包 package.json 版本,删除计划文件)
# --dry-run 可先预览变更(版本计算 + 传导),不写回
pnpm release:version --dry-run # 预览
pnpm release:version # 确认后执行
# 4. 生成 CHANGELOG(基于 conventional commits 重新生成六份日志,见"CHANGELOG 策略")
pnpm changelog
# 5. 审查并提交(含包级 CHANGELOG.md 与 package.json 版本变更)
git add -A && git commit -m "chore(release): 版本提升至 x.y.z"
# 6. push 到 master(提交本身不触发发布;0.x 阶段发布由手动 workflow_dispatch 触发)
git push origin master
# 7. 手动触发发布:GitHub Actions → Release → Run workflow(workflow_dispatch)定时自动发布(1.0.0+ 启用)
release.yml 已内嵌 schedule 定时发布(每周六 UTC+0 12:00 = UTC+8 20:00,参照 momei),1.0.0 正式版发布后取消 schedule 注释即启用。定时触发时 CI 自动完成:
release:plan(推导计划,无推导结果则跳过)+release:version(消费计划提升版本)+pnpm changelog(生成日志)+ 提交并推送 master(semantic-release 风格提交:chore(release): x.y.z [skip ci]+ 根 CHANGELOG 版本段全文)——全流程由pnpm release:auto-version脚本化执行(无变更安全 no-op,见 scripts/README.md);- 随后执行与手动发布相同的完整流程:质量门 → changelog 校验 →
release:publish(OIDC)→ push tags。
手动发布(workflow_dispatch)时跳过自动版本提升步骤(版本已在本地提升并提交)。
CI 发布行为
release.yml(workflow_dispatch 手动触发;1.0.0 后增加 schedule 定时触发)依次执行:
- (仅
schedule触发)Auto version & changelog:自动版本提升 + CHANGELOG 生成 + 提交推送(pnpm release:auto-version脚本化执行); - lint → typecheck → test → build(质量门,任一失败即中止);
Verify changelog is up to date:校验六份 CHANGELOG(根级 +packages/cli/packages/core/packages/engine/packages/skills/packages/mcp)已包含当前版本段(防止漏跑pnpm changelog直接发布;普通提交版本未变时自动通过);pnpm release:publish:- 只发布"本地版本未出现在 npm registry"的包(fetch 直连 registry 对比,见 经验归档 §三十二),无待发布版本时安全退出(天然处理包版本不同步);
- 在 pnpm 项目内部调用
pnpm publish:自动替换workspace:*为实际版本,发布顺序按publishOrder(@dependfix/core/@dependfix/engine/@dependfix/skills先于dependfix/@dependfix/mcp); - 通过 OIDC trusted publishing 认证(
id-token: write+ npmjs.com 的 Trusted Publisher 配置),无需NPM_TOKEN; - 发布前校验 HEAD 锚点(HEAD 必须 touch 待发布包路径,防误在非发布提交执行);
- 发布成功后本地创建
<pkg>@<version>格式的 annotated git tag(如dependfix@0.1.1)+v<锚版本>聚合 tag(锚 = 主交付物优先,见"GitHub Release 自动化"); - 幂等自愈:npm 已发布但本地无 tag(上次发布中途失败等中间态)时自动补 annotated tag(HEAD 锚点校验通过才打,否则安全跳过),并计入 v tag 锚点解析——重跑 CI 即可全链路恢复,无需手动补打(见"tag 策略与包版本不同步");
Push release tags:将release:publish创建的本地 tag 推送到 GitHub(git push <url> --tags,显式 token URL + 推送后核验,通过GITHUB_TOKEN认证);Create GitHub Release(pnpm release:github):读release-publish-result.json为本轮发布创建聚合 GitHub Release——tag 为v<锚版本>,notes 为版本矩阵 + 根 CHANGELOG 最新段(core-only 轮次取锚包包级段),0.x 阶段标 pre-release;Release 已存在则跳过,创建失败仅警告不阻断(npm 已发布完成,可后补gh release create)。
GitHub Release 自动化
- 每轮发布创建一个聚合 GitHub Release(非每包一个):锚版本 = 主交付物优先(
dependfix→@dependfix/core→@dependfix/engine→@dependfix/skills→@dependfix/mcp,即本轮实际发布列表中 rootChangelog 锚包优先、其余按 publishOrder); - v tag:
release:publish在全部包发布成功后创建v<锚版本>annotated tag(指向发布提交,幂等不覆盖),随Push release tags全量推送并核验; - notes:本轮发布包版本矩阵 + 根 CHANGELOG 最新版本段(与 release commit body 同源格式);根段为空(core-only)时取锚包的包级 CHANGELOG 段;两处均无则跳过创建;
- pre-release:0.x 阶段所有 Release 标记 pre-release(与版本策略一致);
- 幂等与失败:Release 已存在(重跑)跳过;创建失败
::warning::不阻断 CI(可后补gh release create v<版本> --notes-file <file>); - 首次手动发布(0.1.0)仍按上文手动
gh release create(CI 发布链路自此自动创建)。
tag 策略与包版本不同步
- 发布不需要手动打
v*tag:release:publish只发布有变更的包,包版本不同步(例如只 bump 了dependfix,@dependfix/core未变)时未变更的包会被自动跳过,不存在"一个 tag 表达不了多版本"的问题; release:publish成功后会为每个发布的包创建<pkg>@<version>格式的 git tag(changesets / lerna 生态惯例,沿用),由 CI 的Push release tags步骤推送到 GitHub,供 GitHub Release 关联与后续精确回溯;v<锚版本>聚合 tag 用于 GitHub Release 关联(锚版本 = 主交付物优先,见"GitHub Release 自动化");与 1.0.0 后规划的v1滚动 tag 命名空间兼容(固定 tag + 移动 tag 共存);- 注意:若发布成功但后续步骤失败导致重跑(如 CI git identity 缺失致 tag 创建失败,见 经验归档 §三十七),
release:publish会自动检测"npm 已发布但本地无 tag"的中间态并补打 annotated tag(HEAD 锚点校验通过时,校验失败则安全跳过)——重跑即可全链路恢复(<pkg>@<version>tag +v<锚版本>tag + GitHub Release);仅当 HEAD 不 touch 包路径时才需手动pnpm tag:released补打; - 首次发布的
v0.1.0tag 仅用于 GitHub Release 展示与 Action 引用;文档中的uses: dependfix/dependfix@v1滚动 tag 待1.0.0稳定版发布后再启用。
CHANGELOG 策略
- release 脚本不负责生成 changelog,仅负责版本提升(
release:version)与发布(release:publish); - CHANGELOG 由
pnpm changelog生成(scripts/changelog.mjs),基于 conventional commit 消息 +conventional-changelog-cmyr-config(与 momei / semantic-release-cmyr-config 生态同一套格式):- 根级
CHANGELOG.md:全仓库的 feat/fix/refactor 类 commit(chore/ci/docs 等类型由 preset 过滤,不进入日志;全局改动如 CI / 文档 / workspace 配置自然不展示),版本段以dependfix@tag 序列划分(dependfix 为主交付物,core 单独发布的变更会随下一次 dependfix 发布段出现); - 包级
CHANGELOG.md(packages/cli、packages/core、packages/skills等):按git log -- <path>精确过滤——只有实际改动该包路径的 commit 才会进入对应日志(一个 commit 同时改两个包时会同时出现在两包日志中,这是真实影响面的体现);@dependfix/skills的同步脚本scripts/sync-skills.mjs属仓库根路径,不匹配任何包,其改动只进根级日志; - 分组语言由根
package.json的changelog.language: "zh"控制(中文 emoji 分组:✨ 新功能 / 🐛 Bug 修复 / 📦 代码重构 等);
- 根级
- 全局改动归属约定:根目录文件(
docs/、.github/、pnpm-workspace.yaml等)不匹配任何包的 path,不会出现在包级日志;若某全局改动确实影响包行为(如 overrides 改依赖解析),应在 commit 中落在包路径内或拆分提交,否则只记录在根级日志; - 生成是增量追加的:已存在的 CHANGELOG.md 只更新未发布版本段(版本号等于当前 pkg 版本且尚无对应 tag 的段,即最新 tag 之后的全部新增 commit),已发布历史段完整保留文件现状——历史 commit 重写或手动编辑均不被覆盖;文件不存在时首次全量生成;无未发布内容(版本等于最新 tag)时文件保持不变;
- 残留未发布段自动清理:发布中断(如 CI 打 tag 失败)会遗留"版本低于当前版本、无对应 tag、npm 未发布"的旧版本段,后续再次提升版本时旧段不再被增量逻辑管理,残留会产生内容重复的两个版本段。生成时自动清理此类残留段(经验归档 §三十七):本地 tag 存在 / npm 已发布(手动发布无 tag 场景)/ npm 查询失败均保守保留,仅确认未发布(registry fetch 三态 false)才删除;
- 生成时机与边界行为:在
release:version之后、publish 之前运行(此时新版本尚无 tag,未发布段输出全部新增 commit);若在版本等于最新 tag 时运行(如 core-only 发布后、或发布后立即重跑),未发布段无新增内容(writer 可能产生的空版本段会被自动过滤),文件保持不变; - 版本标题与 tag:根级与包级日志的版本段均按
dependfix@/@dependfix/core@/@dependfix/skills@tag 序列划分(release:publish自动创建)。手动发布补 tag 约束:分段锚点是"tag 指向的 commit 自身携带的 gitTags",包级日志还有git log -- <path>过滤——因此补打历史 tag 时必须指向同时 touch 该包路径的 commit(0.1.0 补打dependfix@0.1.0/@dependfix/core@0.1.0指向 dc607026,该 commit 同时改动两包 eslint.config.js);若 tag 指向纯 docs/全局 commit(如v0.1.0→ c213fc21),包级日志因 path 过滤看不到锚点,全部历史会并入当前版本段(表现为 changelog 非增量); - 依赖变更提示差异:changesets 原会在依赖包变更时向依赖方日志写入
Updated dependencies行,本方案不自动生成(npm 安装时会自动带上新依赖版本,不影响使用); - 依赖版本:必须使用
conventional-changelog@^7(8.x 模板引擎与 cmyr-config 3.x 不兼容)。
已知限制与排查
| 现象 | 原因与处理 |
|---|---|
| 包首次发布时 OIDC 报错 | npm 的 Trusted Publisher 要求包已存在才能配置(npm/cli#8544)。初始版本必须手动发布(pnpm publish + npm login),之后版本可走 OIDC |
| 手动触发发布后所有包都被跳过 | 没有待发布版本(release:version 未执行或已发布过);这是正常行为,不是错误 |
| 定时发布中途失败(质量门/发布挂) | master 可能处于"版本已提升未发布"状态:人工 workflow_dispatch 重试发布即可,或等待下一定时周期自愈(release-plan.md 未消费则幂等重跑) |
npm publish 发布产物中带 workspace:* | 使用了裸 npm publish。npm 不替换 workspace 协议,必须使用 pnpm publish(release:publish 内部即走此路径) |
| OIDC 发布报 E404 / E401(pnpm 11.0.3) | pnpm 11.0.3 存在 OIDC 回归(pnpm/pnpm#11566,已修复)。升级 pnpm(或改用 pnpm/action-setup 默认最新版) |
| OIDC 发布报 E401 / Unable to authenticate | 检查:Trusted Publisher 的 workflow 文件名是否与 release.yml 完全一致(大小写敏感);id-token: write 权限是否在发布 job 上;是否使用 GitHub-hosted runner |
pnpm changelog 输出英文分组 | 根 package.json 缺少 changelog.language: "zh"(cmyr-config 从 cwd 的 package.json 读取语言) |
pnpm changelog 报模板错误 | conventional-changelog 被解析为 8.x。必须使用 conventional-changelog@^7(8.x 模板引擎与 cmyr-config 3.x 不兼容) |
| CI 报 "CHANGELOG 缺少版本段" | 版本已提升但漏跑了 pnpm changelog(发布前必须生成并提交日志) |
| 包级 CHANGELOG 非增量(0.2.0 段吞掉全部历史) | <pkg>@<version> 锚点 tag 缺失,或指向的 commit 未 touch 该包路径(path 过滤后看不到锚点)。处理:补打/移动 tag 到 touch 该包路径的 commit 后重跑 pnpm changelog |
release:publish 报 "Committer identity unknown" | CI runner 全局 git config 无 user.name/user.email(annotated tag 创建需要 identity;此前 identity 仅在 schedule-only 的 Auto version 步骤中配置,手动触发时缺失)。处理:release.yml 已在 Release Publish 前显式配置 github-actions[bot] 身份;旧 run 遗留的中间态(npm 已发布但 tag 缺失)直接重跑即可自愈补 tag |
release:publish 报"HEAD 不是 touch <path> 的提交" | 在非发布提交上执行了发布(未走 release:version + changelog 提交)。处理:完成版本提升与 changelog 提交后再发布 |
| GitHub Release 未创建(CI 仅警告) | 创建失败不阻断发布(npm 已发布完成)。处理:手动补建 gh release create v<版本> --notes-file <notes.md> --prerelease,notes 可从根/包级 CHANGELOG 对应版本段截取 |
| GitHub Release 显示旧版本号 | v<锚版本> 以主交付物优先(dependfix 未发布时取 core 等);core-only 轮次的 Release 版本号代表该轮核心变更包,属预期行为 |
关于 provenance
- npm 官方在 trusted publishing(OIDC)下会为
npm publish自动生成 provenance 声明;pnpm publish的 provenance 需要显式--provenance标志; - 0.1.0 预览阶段不强制要求 provenance(不阻塞发布);后续如需要,可评估在
release:publish中透传--provenance(CI OIDC 环境可用,本地手动发布不可用)。