划分交付流水线阶段,需要同时回答三个问题:这条流水线要产出什么形态的交付物,每个环境层级验证到什么程度,哪些检查必须作为阻断门禁。本文给出一套可落地的划分方法,从交付物形态与环境层级两条主线拆出阶段,再用风险控制要求确定门禁位置,最终落成一张包含输入、动作、输出、环境、完成标准和责任人的阶段表,供多团队在同一套定义下交接。
要点总览(TL;DR)
- 划分流水线阶段先看交付物形态:源码、构建包、容器镜像、配置与脚本、数据库变更、文档与制品组合,各自对应不同的构建、打包与归档动作,阶段间以带版本标识的制品交接。
- 再看环境层级:开发自测、集成、测试/预发、生产逐级递进,每级只承担不重复的验证内容;涉及数据库结构、权限或对外接口变更的交付物必须验证到预发级。
- 风险控制决定门禁位置:高风险变更的检查前置为阻断条件,低风险变更的检查可并行或后置,避免所有检查一律阻断拖慢交付。
- 每个阶段用统一字段定义:阶段名、输入、动作、输出交付物、所在环境、完成标准、责任人;完成标准要写成可判定的条件。
- 多团队协作下为每个阶段指定责任人,交接以制品版本和验证结论为凭据,接收方确认后才进入下一阶段。
先定划分依据:交付物形态、环境层级与风险控制
流水线阶段划分常见的失败方式是凭经验照搬别人的阶段名,结果阶段与自己的交付物对不上,或者环境验证内容大量重复。稳妥的做法是先明确三条依据,再动手拆阶段。三条依据各自回答一个不同的问题:
| 划分依据 | 回答的问题 | 对阶段划分的作用 |
|---|---|---|
| 交付物形态 | 这条流水线要产出什么?以什么形态在阶段间流转? | 决定阶段要执行哪些构建、打包、归档动作,以及阶段之间的交接物是什么 |
| 环境层级 | 每个阶段在哪个环境验证?验证到什么深度? | 决定阶段的数量与顺序,以及每级环境承担的验证类型 |
| 风险控制要求 | 哪些检查必须阻断,哪些可以并行或后置? | 决定门禁的位置与强度,避免所有检查一律阻断拖慢交付 |
三者出现冲突时,取舍顺序是:以交付物的可验证性为先。也就是说,先确认某个交付物在哪个环境、用什么检查能够被有效验证,再围绕这个验证点设置环境与门禁。如果某个检查在当前环境无法给出可信结论,就应把它移到能验证的环境,而不是在无法验证的环境里加一道形式上的门禁。环境层级和门禁强度都服务于“交付物被真实验证”这一目标。
一个常见的冲突例子:团队希望在生产环境前设置尽可能多的检查,但部分检查(如依赖外部系统的集成行为)只能在预发环境验证。此时正确做法是把这类检查放在预发阶段作为准入条件,生产阶段只保留与生产配置、数据、权限相关的验证,避免同一检查在两个环境重复执行却都得不出结论。
按交付物形态拆分阶段:从源码到可部署制品
交付物形态决定了流水线在每个阶段要“做出什么”。先列出本次交付涉及的全部交付物形态,再为每种形态确定构建、打包与归档动作,阶段边界自然浮现。
| 交付物形态 | 典型动作 | 阶段间交接物 |
|---|---|---|
| 源码 | 拉取分支、静态检查、单元测试、编译 | 通过检查的代码版本(提交标识) |
| 构建包 | 打包、签名、生成版本号 | 带版本号的构建包 |
| 容器镜像 | 构建镜像、打标签、推送镜像仓库 | 带标签的镜像 |
| 配置与脚本 | 配置校验、环境参数注入、脚本语法检查 | 按环境区分的配置集 |
| 数据库变更 | 变更脚本审查、在测试库执行、回滚脚本准备 | 已演练的变更脚本及回滚方案 |
| 文档与制品组合 | 文档生成、版本归档、制品清单汇总 | 发布说明与制品清单 |
形态混合时,按“可独立验证的最小单元”决定合并还是拆分。如果配置变更和镜像构建可以分别验证、分别回滚,就应拆成两个阶段;如果某份文档必须与特定构建包一起发布、单独验证没有意义,就合并到同一个发布阶段。拆分过细会让阶段表膨胀、交接点增多;合并过粗则会让失败原因难以定位。
阶段之间以制品为交接物,下游阶段复用上游产物,不在下游重新构建。重复构建会带来两个问题:一是同一份源码在不同环境构建出不同产物,问题无法复现;二是构建结果与已验证的版本脱节,验证结论失去意义。因此每个阶段输出的制品都应带有可追溯的版本标识,下游阶段只做“取用—部署—验证”,不再执行构建动作。
按环境层级设置阶段:验证深度逐级递进
环境层级决定阶段在哪里验证、验证多深。典型层级为开发自测、集成、测试/预发、生产,每级承担不重复的验证内容,越往后验证越接近真实运行条件。
| 环境层级 | 主要验证内容 | 准入条件 |
|---|---|---|
| 开发自测 | 单元测试、静态检查、本地或开发环境冒烟 | 代码通过评审,基础检查全部通过 |
| 集成 | 模块间接口联调、依赖服务可用性、构建产物可部署性 | 上游制品已归档并带版本标识 |
| 测试/预发 | 端到端功能验证、回归测试、配置与生产一致性检查、数据库变更演练 | 集成阶段验证通过,测试数据与环境就绪 |
| 生产 | 发布后健康检查、关键业务路径验证、监控指标确认 | 预发验证通过,发布窗口与回滚方案确认 |
不重复验证是这张表的核心原则。单元测试在开发自测阶段完成,集成阶段不再重跑全量单元测试;端到端功能验证在测试/预发阶段完成,生产阶段只做发布后的健康确认。重复执行同一检查既消耗环境资源,也会让阶段表失去区分度。
多团队共用环境时,需要提前约定三件事:排队规则(谁在什么时间段使用环境)、隔离方式(按团队或按分支划分命名空间、数据库实例)、数据准备责任(谁负责在验证前准备和清理测试数据)。这些约定应写进阶段表的准入条件,而不是靠临时协调。
环境层级与交付物形态需要组合考虑。纯配置变更或文档更新,验证到集成级往往足够;涉及数据库结构变更、权限调整或对外接口变更的交付物,必须验证到预发级,因为这类变更的影响只有在接近生产的环境中才能暴露。判断标准是:该交付物的失败后果是否依赖生产环境的特定条件,如果是,就不能止步于集成级。
定义各阶段交付物与完成标准
阶段划分完成后,每个阶段都要用统一字段写清楚,才能被不同团队一致执行。建议使用以下字段:
| 字段 | 填写要求 |
|---|---|
| 阶段名 | 用“动作+对象”命名,如“镜像构建与推送”“预发端到端验证” |
| 输入 | 上游交付物的名称与版本标识 |
| 动作 | 本阶段执行的具体操作,逐条列出 |
| 输出交付物 | 本阶段产出的制品及其存放位置 |
| 所在环境 | 本阶段运行的环境名称 |
| 完成标准 | 可判定的通过条件 |
| 责任人 | 对本阶段结果负责的角色 |
完成标准要写成可判定的条件,避免“验证通过”“质量达标”这类主观描述。可判定的写法例如:“全部回归用例执行完毕且失败数为零”“接口响应时间在测试数据集下不超过约定阈值”“数据库变更脚本在测试库执行成功且回滚脚本验证通过”。判定条件应能被自动化检查或由责任人当场确认。
交付物的存放位置与版本标识同样要写进阶段定义。制品应存放在统一的制品库或镜像仓库,版本标识建议包含源码版本与构建序号,确保任意一个已部署版本都能回溯到对应的源码与构建记录。
阶段失败时的回退与重跑也要提前约定:失败后是回退到上一阶段重新产出制品,还是在本阶段修复后重跑;重跑时是否复用已有制品;已部署到环境的失败版本如何清理。这些约定写进阶段表,可以避免每次失败都临时决策。
角色分工与交接机制
多团队协作下,阶段之间的空白地带最容易出问题。需要为每个阶段明确一个责任人角色,并约定交接的触发方式与确认动作。
| 角色 | 主要职责阶段 | 交接动作 |
|---|---|---|
| 开发 | 开发自测、构建打包 | 提交代码并通过自测后,触发集成阶段,确认制品已归档 |
| 测试 | 集成、测试/预发 | 接收制品版本,执行验证,输出测试结论与缺陷记录 |
| 运维/平台 | 环境准备、部署执行、生产发布 | 确认环境就绪,执行部署,反馈部署结果与环境状态 |
| 发布负责人 | 预发到生产的准入确认 | 核对预发验证结论与回滚方案,确认发布窗口 |
交接的触发方式建议与阶段完成标准绑定:上游阶段完成标准满足即触发交接,下游责任人收到通知后执行确认动作(如确认制品版本、确认环境状态),确认完成才算交接结束。仅“通知已发出”不构成交接完成。
跨团队共用阶段需要明确责任归属。常见做法是指定一个阶段 owner 对阶段结果负责,其他团队作为参与方提供输入和验证支持;阶段失败时由 owner 组织定位,参与方按约定提供信息。异常与阻塞的上报路径也应写进阶段表:谁在什么时限内上报给谁,阻塞超过约定时间后由哪一级角色介入协调。
阶段划分落地后,工作项状态、交付物版本与流水线执行结果需要在同一处可见,交接才有依据。ONES 可将流水线与项目关联,在项目、迭代、需求中可视化代码提交、流水线构建与产品发布过程;集成 Jenkins、GitLab CI 等第三方流水线工具后,可同步流水线执行状态和日志,帮助团队在阶段交接时核对上游产物与执行结果。
示例:一条覆盖多环境的交付流水线阶段划分
以下示例为演示情景,设定某团队交付一个包含后端服务、容器镜像、配置变更和数据库变更的组合交付物,环境层级为开发自测、集成、测试/预发、生产。
| 阶段 | 输入 | 动作 | 输出交付物 | 环境 | 完成标准 | 责任人 |
|---|---|---|---|---|---|---|
| 代码检查与构建 | 代码分支 | 静态检查、单元测试、编译打包 | 带版本号的构建包 | 开发自测 | 静态检查零阻断项,单元测试全部通过 | 开发 |
| 镜像构建与推送 | 构建包 | 构建镜像、打标签、推送镜像仓库 | 带标签的镜像 | 开发自测 | 镜像推送成功且标签与构建版本一致 | 开发 |
| 集成验证 | 镜像、配置集 | 部署到集成环境,执行接口联调与冒烟 | 集成验证报告 | 集成 | 接口联调用例全部通过,冒烟无失败 | 测试 |
| 预发验证 | 镜像、配置集、数据库变更脚本 | 部署到预发,执行回归测试与数据库变更演练 | 回归报告、变更演练记录 | 测试/预发 | 回归失败数为零,变更脚本执行与回滚均成功 | 测试 |
| 发布准入确认 | 预发验证结论、回滚方案 | 核对验证结论与回滚方案,确认发布窗口 | 发布确认记录 | 测试/预发 | 验证结论齐全,回滚方案已确认 | 发布负责人 |
| 生产发布与确认 | 已确认的镜像与配置 | 执行发布,进行健康检查与关键路径验证 | 发布记录、监控确认 | 生产 | 健康检查通过,关键业务路径验证正常 | 运维/平台 |
风险控制在示例中的门禁位置:静态检查与单元测试作为第一道阻断门禁,未通过不进入镜像构建;集成验证通过是进入预发的前提;预发回归与数据库变更演练通过是发布准入的阻断条件;生产发布后的健康检查异常则触发回滚。低风险的文档更新类交付物可以并行处理,不占用上述阻断门禁。
示例中的多团队交接点有三处:开发向测试交接构建包与镜像版本,测试向发布负责人交接预发验证结论,发布负责人向运维交接发布确认记录。每处交接都以制品版本和验证结论为凭据,接收方确认后才进入下一阶段。
完成检查:阶段划分是否可执行
阶段表写完后,用以下清单逐项核对,全部满足才具备执行条件:
- 每个阶段都有明确的输入、动作、输出交付物、所在环境、完成标准和责任人,没有空缺字段。
- 完成标准均为可判定条件,能由自动化检查或责任人当场确认,没有“验证通过”“质量达标”这类主观表述。
- 交付物在阶段间可追溯:每个制品带版本标识,能从已部署版本回溯到源码与构建记录。
- 下游阶段复用上游制品,不存在重复构建。
- 环境层级与验证内容无重复、无遗漏:同一检查不在两个环境重复执行,每类交付物都有对应的验证环境。
- 门禁检查与风险等级匹配:高风险变更的检查已前置为阻断条件,低风险变更的检查可并行或后置。
- 每个阶段的责任人已确认,交接触发方式与确认动作已写入阶段表。
- 阶段失败时的回退与重跑约定已明确,包括制品复用与失败版本清理方式。
- 跨团队共用环境的排队、隔离与数据准备规则已约定,并体现在准入条件中。
- 异常与阻塞的上报路径已明确,包含上报时限与介入层级。
核对中发现空缺的条目,回到对应章节补齐即可。阶段表不是一次成型的文档,随着交付物形态和环境变化,应定期复核并更新。
常见问题
交付物形态和环境层级对阶段划分的结论不一致时,以哪个为准?
以交付物的可验证性为准。先确认某个交付物在哪个环境、用什么检查能够被有效验证,再围绕这个验证点设置环境与门禁。如果某个检查在当前环境无法给出可信结论,就把它移到能验证的环境,而不是在无法验证的环境里加一道形式上的门禁。环境层级和门禁强度都服务于“交付物被真实验证”这一目标。
配置变更和文档更新这类交付物,是否也必须走完所有环境层级?
不必一律走完。纯配置变更或文档更新,验证到集成级往往足够;涉及数据库结构变更、权限调整或对外接口变更的交付物,必须验证到预发级。判断标准是:该交付物的失败后果是否依赖生产环境的特定条件,如果是,就不能止步于集成级。低风险的文档更新类交付物可以并行处理,不占用阻断门禁。
多团队共用集成或预发环境时,最容易在哪个环节卡住?
常见卡点集中在三处:排队规则没有约定,多个团队同时占用环境;隔离方式不明确,按团队还是按分支划分命名空间、数据库实例没有共识;测试数据准备责任不清,验证前无人准备、验证后无人清理。建议把这三项写进阶段表的准入条件,而不是靠临时协调。跨团队共用阶段还应指定一个阶段 owner 对阶段结果负责,其他团队作为参与方提供输入和验证支持。
阶段失败后应该回退重做还是在本阶段修复重跑?
需要在阶段表里提前约定,避免每次失败临时决策。通常的判断是:如果失败原因出在上游制品本身(如构建产物缺陷),回退到上一阶段重新产出制品;如果失败原因在本阶段的部署或验证动作(如环境配置错误),在本阶段修复后重跑,并复用已有制品。同时约定已部署到环境的失败版本如何清理,以及重跑时是否复用已有制品。
阶段表落地后,如何让交接时的制品版本和执行结果有据可查?
交接的凭据是制品版本和验证结论,因此需要让工作项状态、交付物版本与流水线执行结果在同一处可见。ONES 可将流水线与项目关联,在项目、迭代、需求中可视化代码提交、流水线构建与产品发布过程;集成 Jenkins、GitLab CI 等第三方流水线工具后,可同步流水线执行状态和日志,帮助团队在阶段交接时核对上游产物与执行结果。
