Skip to content
Development
Skill

/pdlc-ship

发布工作流(收评审通过的功能 → 跑测试 → bump VERSION → 更 CHANGELOG → tag)

From plugin
pdlc
1838 skills2 hooks

Claude Code

$ npx -y skills add kanfu-panda/pdlc-skills --skill pdlc-ship --agent claude-code

SKILL.md

pdlc-ship.SKILL.md
name: pdlc-ship
description: 发布工作流(收评审通过的功能 → 跑测试 → bump VERSION → 更 CHANGELOG → tag)
argument-hint: "[--version <x.y.z>] [--skip-tests (仅 hotfix)] | --tag-after-merge [v<x.y.z>]"
allowed-tools: Read, Write, Edit, Bash, Glob, Grep
layer: 2
stage: ship
produces:
  - VERSION
  - CHANGELOG.md
  - docs/05_deployment/releases/v<version>-release-notes.md
  - .git/refs/tags/v<version>
requires:
  - docs/.pdlc-state/
next_step: pdlc-deploy
terminal_state: ship_done

发布工作流

串联发布一个版本所需的所有步骤:收评审通过的功能 → 跑测试 → 升级 VERSION → 更新 CHANGELOG → 写发布说明草稿 → 创建 tag。CI 配置默认不动(见 §1.6)。

<!-- @include templates/prompts/iron-law.md(已内联于下方,无需另读) --> ⛔ **IRON LAW · 不可违反的硬门禁**

以下规则为**不可协商**的执行约束:

1. **文件必须落盘**:所有带编号(功能ID / 缺陷ID)的文档,必须作为实际文件写入磁盘,不可仅在对话中输出。 2. **阶段必须落章**:每个阶段完成后必须在状态机 `docs/.pdlc-state/<feature-id>.json` 追加 history,不可跳过。 3. **测试必须存在**:进入 `/pdlc-implement` 前,对应测试必须存在且处于红灯状态。违反则中止。 4. **自检必须执行**:段二自检为强制步骤,不得以"已经很好了"为由跳过。 5. **防循环**:段三修复为单次,不递归。无法自动修复的问题记录到报告,继续往下走。 6. **状态必推进**:成功执行某 phase 后 `current_stage` 必须变更。收尾时若发现 `current_stage` 未推进,视为失败并报错,**不得静默返回**(防止外层循环拿滞后的状态空转烧额度)。唯一例外:命中人工点主动 block 时,`current_stage` 保持不变但必须写 `last_phase_result.ok=false` + `blocked_reason`。

**违反任一条 = 立即中止当前命令,输出违规详情,等待人工介入。** <!-- @include-end templates/prompts/iron-law.md -->

> ⛔ **发布是破坏性·不可逆操作**:打 tag / bump 版本 / 触发 CI/CD 属破坏性范畴。**`--autonomous` 对本命令无效**——即使带该参数,§1.1(未完成功能)与 §1.2(测试门)的人工确认仍必须真实由人应答。自主循环(`/pdlc-loop-run`)停在「评审通过、`next_step` 为 `pdlc-ship`」(循环文档里称 `review_done`),永不进入本命令。

段一:执行

> 参数带 `--tag-after-merge`:只做「合并后补打」(见 1.5 末尾),跳过下面全部步骤。

1.1 前置检查

1. 确认当前分支不是 `master` / `main`(参考 CLAUDE.md §5) 2. 确认工作区干净(`git status` clean) 3. 盘点 `docs/.pdlc-state/` 下的功能(跳过 `_` 前缀的索引文件与 `statusline.json`),逐个归入四类:

  • **可发布**:`next_step` 为 `pdlc-ship`,且 `last_phase_result.ok` 不是 `false`——评审(或功能编排)已通过、等着发布。这一类**纳入本次发布**
  • **已发布**:`current_stage` 为 `ship_done` 或 `deploy_done`——上一次发布已纳入,本次不再收
  • **旧版终态写法**:`current_stage` 以 `_done` 结尾但不是上面两个(如 `feature_done` / `fix_done` / `review_done`)——旧版本写入,分不清是「已发布」还是「评审通过、待发布」。逐个列出,**请人确认**归入可发布还是已发布;`--autonomous` 也不替人判
  • **进行中**:其余全部(含 `last_phase_result.ok` 为 `false` 的阻塞功能)
  • 有进行中的功能 → 列出来并询问是否继续(用户明确同意才继续;进行中的功能不纳入本次发布)
  • 可发布为空 → 告知「没有评审通过、待发布的功能」,询问是否仍要发布(如只发文档 / 依赖升级)

4. **质量闸门检查**(若项目有 `docs/00_standards/quality-targets.yml`): 读 `docs/07_reviews/quality/` 下**最近一份 `.md` 报告**(同名 `.html` 只是视图, 闸门一律以 `.md` 为准——两者若不一致,信 `.md`):

  • 无任何报告 → 提示先跑 `/pdlc-quality`,询问是继续还是先出报告
  • 报告**总判定未达标** → **默认不放行**;要发必须由人**显式 override 并写明理由**,

该理由需记入本次发布的 CHANGELOG 或发布说明(不允许无声跳过)

  • 报告**过期**——分两档处理,**不是所有过期都等价**(见下)
  • 达标且未过期 → 在发布报告里引用该报告路径、日期与 commit SHA 作为质量证据

过期判定:按「改动了什么」分两档

报告头部记着生成时的 `<!-- 仓库版本: <commit SHA> -->`(由 `/pdlc-quality` 落盘时写入)。 取该 SHA,跑 `git diff --name-only <SHA>..HEAD` 看这期间动了什么:

| 这期间改动命中 | 判定 | 理由 | |---|---|---| | `docs/01_requirements/prd/`、`docs/00_standards/quality-targets.yml`、`docs/00_standards/e2e-flow-map.yml`、`docs/00_standards/test-commands.yml` | **硬闸·不放行** | 报告里的 PRD ↔ `core_flows` 对账与 E2E 覆盖矩阵的**输入变了**,结论不再成立。重跑单测补不回对账——必须重跑 `/pdlc-quality` | | 只有其它代码 / 文档 | 提示已过期,**建议**重跑 | 对账仍成立,测量数字可能略旧 | | 报告里没有 `仓库版本` 字段,或该 SHA 在本仓库解析不了 | **按「不可判」处理**:明确告知无法核对新鲜度,建议重跑 | 与三态语义同一条纪律——「查不了」不等于「没问题」,不得静默当作未过期 |

> ⛔ 硬闸同样允许人**显式 override 并写明理由**(与「总判定未达标」同一条通道,理由须记入 > CHANGELOG 或发布说明),但**不得无声跳过**。

`quality-targets.yml` 变动要单独看一眼「闸门是不是被调松了」

若上表命中的文件里**包含 `quality-targets.yml`**,除了要求重跑,还必须把 `git diff <SHA>..HEAD -- docs/00_standards/quality-targets.yml` **原样展示给人**, 并逐条点出下列「变松」信号——**命中任何一条都要人明确确认,不得只当作普通过期**:

  • 覆盖率目标数字**下降**(如 85 → 70)
  • `core_flows` 条目**减少**(核心流被移出闸门视野)
  • lint 策略**放宽**(如 zero-warnings 改为允许若干 warning)
  • 新增了**豁免声明**(把某些 PRD / 流程排除在对账之外)

> **为什么单列**:报告达标之后把目标调低,重跑一次照样是绿的——日期新、SHA 新、结论"达标", > 但**尺子本身变短了**。这与 `/pdlc-test-setup --refresh` 的「严向自动、松向人确认」是同一条 > 原则换个位置:**放松闸门永远是人的决定,不能由流程默默吸收。**

1.2 发布前测试门(参考 CLAUDE.md §6)

**必须主动询问用户**(不得默认跳过,也不得默认强制跑):

📦 发布前测试门检查:是否先跑全量单测 + E2E 测试?

[选项 A] 跑测试(推荐)
  → 后端:./gradlew test 或 mvn test
  → 前端:pnpm test 或 npm test
  → E2E:pnpm exec playwright test(如有)

[选项 B] 跳过测试 —— 仅适用于生产 hotfix
  → 理由:<请说明>
  → 自动记录到 commit 消息

请选择 A 或 B。

若选 B:本命令的参数必须含 `--skip-tests` 且有理由说明,否则中止。

1.3 版本号处理

1. 读取当前 `VERSION` 文件 2. 若本命令的参数带 `--version x.y.z`,用指定值;否则按语义化规则建议:

  • 本次发布含 fix 且无 feature → 补丁号 +1
  • 含 feature 且无 breaking → 次版本号 +1
  • 含 breaking → 主版本号 +1

3. 写回 `VERSION`

1.4 更新 CHANGELOG.md

1. 取 §1.1 盘点出的**可发布**功能(含人工确认归入可发布的旧版终态写法) 2. 分组:缺陷(`B` 开头的 ID)→ "修复";history 里有 `refactor` 阶段的功能 → "重构";其余 → "新增" 3. 每条用"- <简要描述>(<feature-id>)"格式写入 CHANGELOG 的 `[未发布]` 段(开发各阶段可能已按同一格式为该功能追加过条目——`[未发布]` 段里已有同一 ID 的,不重复写) 4. 把 `[未发布]` 改为 `[<new-version>] - <今日日期>`

1.4.1 发布说明草稿(可直接作 PR 描述)

按 `assets/release-notes-template.md` 写 `docs/05_deployment/releases/v<new-version>-release-notes.md`,把这次发布散在各处的结论汇到一页, 开 PR 时直接 `gh pr create --body-file <这个文件>`,发 Release 时也能用。**只写这个文件,不开 PR、不合 PR、不推送。**

  • **来源**:本次纳入的功能(§1.1 的可发布清单)各自的 PRD「背景与目标」、`docs/07_reviews/code/<ID>-*-review.md` 的评审总结与「需人工处理」项、

状态文件里 `last_phase_result.checks`(读的是推进到 `ship_done` **之前**的那份,即评审阶段的结果),以及 §1.1 的质量报告结论、§1.2 测试门的选择、§1.5 的 tag 去向

  • **数字照抄**:问题数、`checks` 的值原样搬,不重算、不美化;`null` 照写 `null`。某项产物不存在就写「无」,不要补写一份
  • **「需要人跟进」不能省**:评审里的需人工项、质量闸门 override、过期提示,本次发布交给人的事都列在这里;真的一项都没有才写「无」
  • **不加工具署名**:草稿是给人发出去的文字,不写「由某某工具生成」之类的署名或链接
  • tag 去向此时还没定(§1.5 才判断):先写「待定」,§1.5 判断完回来改成「已打 v<new-version>」或「待合并后打」,再一起提交

1.5 提交,按合并方式决定何时打 Tag

**先推进状态机,再提交**:对每个纳入的功能按段四的规则运行状态推进脚本(`--stage ship --next pdlc-deploy --done`),让 `ship_done` 随发布提交一起进库。先提交后推进的话,状态文件的改动留在发布提交之外——squash 合并时就丢了,主干上这些功能会一直显示「待发布」。

git add VERSION CHANGELOG.md docs/05_deployment/releases/v<new-version>-release-notes.md docs/.pdlc-state/<纳入的功能ID>.json
git commit -m "release: v<new-version>"

若选项 B(跳过测试):commit 消息末尾追加 `[skip-tests: <理由>]`。

**tag 必须指向最终留在主干上的那个提交。**本命令跑在发布分支上,分支怎么合进主干决定了现在打的 tag 还算不算数:

| 合并方式 | 发布分支上的提交会不会原样进主干 | 本命令的做法 | |---|---|---| | 普通合并(merge commit)/

Read more
@kanfu-panda
Ships withpdlc

Author: kanfu-panda Repo: github.com/kanfu-panda/pdlc-skills License: MIT pdlc-skills is built on one rule: an AI saying "done" doesn't count — exit codes do.

Stars on GitHub

Momentum

stars in total
18
Star history of kanfu-panda/pdlc-skills on GitHub, a chart by star-history.com

Other skills on pdlc.

pdlc-add-app

pdlc-add-app

在已有项目里加一个前端应用(先探测布局,跟随现有目录与技术栈);新项目一次性初始化用 /pdlc-bootstrap

@kanfu-panda@kanfu-pandaInstall Skill
pdlc-add-service

pdlc-add-service

在已有项目里加一个后端服务(先探测布局,跟随现有目录与技术栈);新项目一次性初始化用 /pdlc-bootstrap

@kanfu-panda@kanfu-pandaInstall Skill
pdlc-adopt

pdlc-adopt

已有代码、还没有 PDLC 文档的老项目接入——只读扫描后逆向生成基线文档并做健康检查,不改代码;空目录新项目用 /pdlc-bootstrap

@kanfu-panda@kanfu-pandaInstall Skill
pdlc-arch

pdlc-arch

架构分析(生成/更新 docs/ARCHITECTURE.md 系统架构总览 · surface 型)

@kanfu-panda@kanfu-pandaInstall Skill
pdlc-bootstrap

pdlc-bootstrap

空目录从一句话描述初始化新项目(服务 / 应用拆分、技术栈、目录骨架与 PDLC 文档目录);已有代码的项目用 /pdlc-adopt

@kanfu-panda@kanfu-pandaInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc11d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about pdlc-ship.

Which coding agents can use pdlc-ship?
pdlc-ship installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.