主题

Manual version release delivery

Manual version release delivery 是一种可复用的发布交付合同:维护者显式选择或确认一次 release target,系统再用可插拔的 Version Policy 校验版本、绑定 source identity、完成 reservation、经过 PR 与质量门禁、创建显式 Release,并让部署与 recovery 复用该 identity 下对应的不可变产物。

  • 交付
  • 运维
  • 工具

目录

Definition

Manual version release delivery 是一种可复用的发布交付合同:维护者显式选择或确认一次 release target,系统再用可插拔的 Version Policy 校验版本、绑定 source identity、完成 reservation、经过 PR 与质量门禁、创建显式 Release,并让部署与 recovery 复用该 identity 下对应的不可变产物。这里的 manual 指 release decision 有明确的 owner 或 workflow_dispatch 输入,不指允许 workflow 绕过分支保护或直接改写 main。

Version Policy 必须把 target grammar、trusted baseline、ordering/monotonicity、identity、publication mapping、reservation/idempotency、concurrency、recovery 和 validation 写成可审查的输入输出契约。SemVer 可以作为一种可插拔 grammar;日期版本、单调 build number、发行列车编号或组件自定义 grammar 也可以使用,只要 parser、comparator、collision 和 publication mapping 都明确。VERSION 文件、alpha/beta/rc、Git tag 以及 provider deployment 都只是实现适配,不是本 Topic 的普遍规则。

采用 SemVer 时,owner 在单一 release-target 字段中选择 patch、minor、major 或明确的 final/prerelease version;执行端的 Version Policy 再根据 trusted final baseline 解析 canonical version。Manual release 不从 PR 数量、label、文件名、兼容性分类或任何 per-PR record 推导 target;可选的 SemVer change governance 只在 owner 另行要求兼容性判断时使用,不是本 Topic 的 target input 或 release-eligibility gate。

release target 与 workflow 解析出的 canonical version 是两个阶段。symbolic target 由执行端 policy 根据 trusted baseline 确定性解析为完整版本,并在 reservation 中绑定;Agent 可以校验并传递 owner input,但不得用自己计算的 exact X.Y.Z 替换该 input。explicit-version path 则验证 owner 提供的完整版本。两条解析路径可以共享同一个 release-target 输入字段,路径由 policy grammar 判定。

本 Topic 不把版本号从 merge 顺序、PR 数量、当前 VERSION 或某个 label 猜出来,也不把 CI 绿色、Release 页面存在或部署成功互相替代。它是 release identity 与交付边界的 reusable guidance,不是某个仓库的兼容性分类 Policy、Policy Skill 安装说明、供应商部署手册或生产发布授权。

When to use

当仓库需要手动触发版本发布,且一次发布要在多个 workflow、artifact consumer、release surface 或部署目标之间保持同一 identity 时使用。典型信号包括 workflow_dispatch、显式 release-target intent、受保护的 release tag/record、独立的 Release 与 Deploy 阶段,或需要对失败发布进行 retry/recovery 的交付链路。手动入口确认 intent 后,符合该 identity 与质量门禁的后续阶段可以自动衔接(projects/televy-backup.md、skills/style-playbook/references/topics/github-actions-scheduling/TOPIC.md)。

当版本 grammar 可能扩展、多个运行可能并发争抢同一 target、或发布需要证明“哪个 source commit 产生了哪个 artifact”时,应在实现前建立 Version Policy。如果项目只有一个 package registry 的原生版本字段、没有手动 release decision、没有跨步骤 identity,也许只需 package manager 的既有发布合同;不要仅因仓库有一个 VERSION 文件或一个 GitHub workflow 就套用本 Topic。

如果 owner 只说“发布当前 candidate”而没有提供 target,应停止并请求 owner 选择一个 release target;不得默认 patch、读取历史 impact、从 baseline 预先计算 exact version,或把缺少兼容性分类当成发布阻断。owner 明确提供 symbolic 或 exact target 后,才沿对应 policy path 验证并执行。

已有 label-driven release 的其他仓库也可以使用本 Topic,但必须让 label 合同与 manual input 之间只有一个明确的版本真相源。采用 PR labels 的项目应单独使用 PR label release Topic;target-only manual release 项目不应安装或调用该 route(skills/style-playbook/references/topics/pr-label-release/TOPIC.md)。

Habits / defaults

  • 默认用一个字段表达 release target。 SemVer 项目的 owner 在同一字段中提供 patch、minor、major 或明确的 final/prerelease;symbolic 与 explicit 是执行端的解析分支,不要求增加 mode、version、impact 三组用户输入。
  • 只让 target 与 trusted baseline 参与版本解析。 candidate source、PR metadata、CI、policy、reservation 和 artifact digest 负责证明发布 identity 与交付结果,但不能替代 owner target、选择版本或引入 per-PR release record。target 只在建立新 identity 时解析;同一 identity 的 retry/recovery 读取已绑定版本,不能重新执行下一版分配。
  • 把兼容性治理保持为可选边界。 只有 owner 明确要求 public API 或 persistent state compatibility classification 时,才读取 SemVer change governance 及其可选 assessment template。该 classification 不会自动成为 Manual target、required check、release eligibility 或 durable release state;本项目不采用这条集成路径。
  • baseline 与 monotonicity 独立于版本文件。 正常新发布的 target 应大于该 policy 声明的 trusted final baseline;相同 target 只允许作为同一 identity 的 idempotent retry/recovery。baseline 可以来自受保护 tag、append-only release record、package registry 或别的已验证来源,但不能退回到 VERSION、merge order、最后一次 workflow artifact 或“下一个 pending”猜测。没有 baseline 时,policy 必须显式定义 bootstrap 行为或拒绝发布。
  • candidate boundary 是运行时 identity 证据。 release unit 可以从最后一个已完成 final source(不含)到 dispatch 固定的 source(含)定义;base/source SHA、PR provenance、commit verification 和 source CI 应在执行端读取并验证,不应通过每个 PR 的 checked-in record 持久化发布影响。
  • identity 要能重建且不可含糊。 至少保存 release unit/component、canonical version、source 或 merge SHA、policy identity/version、reservation ID、artifact digest 和 publication target;若 policy 使用 channel、tag、environment 或 package name,也必须纳入 identity 或明确其映射。相同 tuple 应返回同一结果,版本 collision、tag 被其他 SHA 占用或 publication target 已属于另一 identity 时必须停止,不能静默分配 successor。
  • reservation 要先于不可逆副作用。 在创建 Release、上传 artifact 或部署前为 identity 写入 durable claim,使用唯一 claim key 和 compare-and-swap/原子条件更新记录 owner、状态、target、source boundary 与 expiration/release 规则。重复 dispatch 可以复用同一 claim;不同 source、不同 policy 或不同 owner 争抢同一 key 时必须显式冲突。并发规则应按 GitHub Actions scheduling 区分可取消的 preview、required gate 和 release/deploy run;需要保留的 release evaluation 不应被新 manual run 静默取消(skills/style-playbook/references/topics/github-actions-scheduling/TOPIC.md)。
  • validation 分层且在边界重验。 dispatch target、policy parser、trusted baseline、reservation、source head、commit verification、artifact digest、Release mapping 和 deployment target 都应有可执行检查;reservation 前、Release 前和 Deploy 前必须重新读取权威事实。缺少权限、签名、provenance、required check、target ownership 或 artifact 时应 fail closed,而不是以“稍后人工确认”继续。
  • PR、verified commit 与 exact-head merge 是默认保护层。 release source 应先进入正常 PR,完成适用的 PR CI、review、required checks 与 policy validation,再以精确 source head 产生 merge identity。release workflow 不应绕过 PR 直接写 main,merge 后应再次确认 exact head/base 与 identity;这条保护层不等于要求 PR label 或 per-PR impact evidence。
  • 把 quality gates 写成 repo-local contract。 在 quality-gates 中声明 PR、main/release、deploy、signed-commit、review 和 waiver 的边界与真实 check names;PR gate 证明候选可合并,Release gate 证明 merge identity 可发布,Deploy gate 证明 artifact 可到达目标。不要把一条 CI 绿色或 GitHub UI 当前状态当成全部 release readiness,且 branch protection/ruleset 应与 checked-in 声明对齐(skills/style-playbook/references/topics/quality-gates/TOPIC.md)。
  • Release 是显式阶段,Deploy 复用对应产物。 merge 后由明确的 Release 操作把 canonical version、source/merge SHA、provenance 和各产物 digest 绑定到发布记录、tag、registry 或其他 policy-defined surface;只有 Release 成功或可验证地已完成,Deploy 才能继续。每种交付产物构建一次并固化 digest,其对应的所有部署目标复用同一已验证产物;同一 release 下的静态包、package 和镜像可以是不同产物,不要求共享内容或 digest。EdgeOne Makers static-site deploy 展示了多个静态站点目标复用同一产物的一种适配,但 provider production、默认域名 smoke test、DNS/证书与 provider token 都是 owner-side prerequisites,不是本 Topic 的默认步骤(skills/style-playbook/references/topics/edgeone-makers-static-site-deploy/TOPIC.md)。
  • 分别声明上游完成与下游结果。 上游完成条件必须覆盖该 policy 声明的全部产物、来源与 digest 验证,不能只依据 tag 或 Release 页面。不同产物可以共享 release identity,但各自保留 digest 并由对应消费者复用;下游通知与部署单独记录状态,通知成功不等于部署成功,通知失败是否阻塞后续发布由项目合同明确声明。
  • retry 复用 same identity。 发布、上传、部署、receipt 或通知失败时,retry 必须带着同一 canonical version、source/merge SHA、reservation/identity 和 artifact digest,补齐缺失步骤即可。same-identity recovery 不重新计算 baseline、不重写 tag、不改版本/channel、不创建 successor;如果旧 merge 根本没有合法 identity,应创建一个 policy 明确允许的新的 PR/release boundary,而不能把历史 merge 伪装成 recovery(projects/televy-backup.md)。
  • provenance 与通知最小化而完整。 release record 与 artifact provenance 至少能回到 policy、source/merge SHA、canonical version、reservation、digest、workflow run/attempt 与 Release/Deploy result。失败通知使用独立、可审计的 sidecar 或等价路径,包含排障所需的 repository/workflow/run URL/SHA/attempt/identity/recovery target,但不得泄露 token、secret、私有路径、无关用户数据或 caller code;transport、secret 和渠道必须经过项目自己的 selection gate,不能从 Topic 样例自动推断(skills/style-playbook/references/topics/release-failure-notification/TOPIC.md)。
  • owner prerequisites 要先于 rollout。 owner 必须批准 version grammar/policy revision、baseline source、release unit、权限与 branch protection、PR/review/check names、reservation storage、artifact retention、Release/Deploy targets、required secrets、环境审批、smoke test、notification transport 与 recovery operator。域名、证书、provider project、registry ownership 和真实生产凭据属于 owner-side setup;文档或 Topic 不能代替这些前置条件,也不能据此执行生产发布。
  • 把设计文档当作当前真相。 将 policy schema、state machine、failure semantics、owner prerequisites、workflow names 和 recovery matrix 写进 docs/、ADR 或 repo-local contract,且让 validator、CI 和 generated index 能引用相同路径。system-design-docs 的重点是文档本身参与系统约束;只写一段 README 说明而不让 gate 或 recovery 读取它,会留下不可验证的漂移(skills/style-playbook/references/topics/system-design-docs/TOPIC.md)。

Reference implementations

  • projects/style-playbook-skills.md:当前仓库的 target-only manual release adaptation;.github/release-contract.json、docs/adr/0007-manual-release-intent.md 和 docs/specs/manual-version-release-delivery/SPEC.md 共同证明单一 target、trusted final baseline、固定 source、tag/Release/artifact identity 和不持久化 per-PR release evidence。该项目明确不采用本 Topic 的 durable reservation/completion refs 默认实现。
  • projects/resume.md:另一个项目的历史 candidate-bound consumer 样本,只用于说明一种可选的旧集成边界,不是 target-only manual release 的默认输入,也不应被当前仓库复制。
  • projects/televy-backup.md 是 identity-chain 样本:.github/release-contract.json、release_reservation.py、release_preparation.py、release_completion.py 与 release.yml 展示了 baseline、append-only reservation、verified commit、completion gate、显式 Release、provenance 和 same-SHA recovery 如何串成一条链。它的 final-tag-first、VERSION preparation 以及 prod/beta/rc/dev grammar 是项目适配,不能升级为本 Topic 的 universal rule。
  • projects/isolarail.md 与 skills/style-playbook/references/topics/edgeone-makers-static-site-deploy/TOPIC.md 代表单一 artifact 的部署侧:先构建一个组合静态产物,再交给 GitHub Pages 与 EdgeOne;EdgeOne project、token、域名、证书和 smoke test 仍由 owner 另行准备。它证明 artifact boundary,不证明所有项目都应使用 EdgeOne。
  • skills/style-playbook/references/topics/quality-gates/TOPIC.md 提供 required checks、signed commits、default-branch protection、PR/main/release 分层和 waiver 的审查边界;它不替 Version Policy 选择 grammar 或 baseline。
  • skills/style-playbook/references/topics/github-actions-scheduling/TOPIC.md 提供 event 分类、concurrency、manual dispatch、required gate 的排队/取消语义;它不等于 release identity 或 publication success。
  • skills/style-playbook/references/topics/pr-label-release/TOPIC.md 是其他项目采用 label-driven release 时的独立参考;它不适用于本项目的 target-only manual release。
  • skills/style-playbook/references/topics/release-failure-notification/TOPIC.md 提供 identity-aware 与 generic failure sidecar 的分层,以及 transport selection、metadata-only 和 privacy-safe payload 的边界;它不替项目选择 notifier。
  • skills/style-playbook/references/topics/system-design-docs/TOPIC.md 代表把系统合同、质量门禁与生成/读取链路作为 current truth 的文档方式;发布 policy 的 schema、state transition 与恢复约束应遵循这一文档边界。

Failure modes

  • 把每个 PR 的 impact record、candidate SHA 或聚合结果当作 target-only manual release 的必备输入,会把兼容性治理和版本 identity 混在一起;应只接收 owner 的单一 target,并由执行端验证 trusted baseline、source 和产物。
  • 让 Agent 以 patch 作为无输入 fallback、从 baseline 计算 exact version,或把 owner 未明确提供的 prerelease 当作可接受输入,会悄悄替换 owner intent;应先请求 target,再区分 symbolic 与 explicit policy path。
  • 把 manual 理解成完整版本号必填,或把 symbolic/explicit 两种语义展开成多组互斥表单字段,会把版本解析职责转给 owner;SemVer 常规入口应以单字段表达 owner 选择,由执行端 policy 解析 canonical version。
  • 把 SemVer 的点号解析、alpha/beta/rc 后缀或 vX.Y.Z tag 当成所有项目的默认 grammar,会使日期、build number 或组件版本无法安全接入;应先声明可插拔 Version Policy,并为每种 policy 单测 parse、compare、format、collision 与 publication mapping。
  • 从 VERSION、最后一个 workflow artifact、PR merge 顺序或“下一个待处理 PR”推导 target,会在并发、重跑和历史迁移时产生不可审计的 successor;应使用唯一 trusted baseline,并对缺失或不可比较的 baseline fail closed。
  • 在 build、tag 或 deploy 之后才 reservation,或只把 claim 放在短命 workflow artifact 中,会让两个 manual run 同时发布同一 target;应使用 durable claim、owner/token 校验、CAS 状态转移和明确的 idempotent retry。
  • 让 release workflow 直接写 main,或把 PR CI green 当作已完成 Release,会绕过 review、exact-head merge、质量门禁和发布记录;应保持 PR、merge、Release、Deploy 的状态可观察且职责分离。
  • 为消费同一产物的每个部署目标重新构建,或允许下游按自己的 latest/tag 重新拉取,会造成多目标内容漂移;应让这些目标复用对应的已固化 digest,部署失败时保留原产物供同 identity recovery 使用。同一 release 声明的不同产物各自验证,不把镜像与数据包强行视为相同内容。
  • recovery 重新计算 successor、改写已存在 tag、改变 channel 或把缺少 identity 的历史 merge 当作 same-SHA recovery,会破坏审计与回滚边界;前者只能重试原 identity,后者应走新的显式 release boundary。
  • label 与手动 input 同时修改版本却没有 canonical precedence、冲突检测和迁移记录,会造成 gate、Release 与通知看到不同 intent;target-only 项目应明确排除 label route,label-driven 项目则必须由自己的 Policy 定义唯一真相源。
  • 失败通知只写“release failed”,或在 secret-bearing workflow 中 checkout caller code,会丢失 SHA、run attempt、identity 和 recovery context,并扩大隐私/执行边界;应使用 metadata-only sidecar、最小权限、redaction 和 transport selection gate。
  • 把 provider、域名、证书、registry ownership 或真实 secret 当成文档即可满足的默认条件,会把未授权的生产操作带进通用 Topic;应把 owner prerequisites 单独列出,并在缺少配置时 fail closed。
  • 只维护文档而不运行 policy validator、catalog audit、workflow contract test 和 recovery test,会使生成索引、required check 名称或当前真相漂移;发布 policy 变更必须让设计文档、验证器与交付索引一起通过门禁(projects/style-playbook-skills.md)。

Evidence index

  • projects/style-playbook-skills.md
  • projects/resume.md
  • projects/televy-backup.md
  • projects/isolarail.md
  • docs/adr/0007-manual-release-intent.md
  • docs/specs/manual-version-release-delivery/SPEC.md
  • .github/release-contract.json
  • .github/workflows/release.yml
  • tools/manual_release.py
  • skills/style-playbook/references/topics/quality-gates/TOPIC.md
  • skills/style-playbook/references/topics/github-actions-scheduling/TOPIC.md
  • skills/style-playbook/references/topics/pr-label-release/TOPIC.md
  • skills/style-playbook/references/topics/release-failure-notification/TOPIC.md
  • skills/style-playbook/references/topics/edgeone-makers-static-site-deploy/TOPIC.md
  • skills/style-playbook/references/topics/system-design-docs/TOPIC.md
  • https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency