流水线阶段是持续交付流水线中按顺序划分的一段可执行环节,每段承担一类明确的验证或交付任务,例如构建、测试、部署。本文从定义、组成要素、概念边界和衔接机制入手,说明如何判断某个环节算不算一个阶段,并用一条典型交付流程演示阶段划分,帮助读者在阅读流水线配置或讨论交付流程时使用一致的判断标准。
要点总览(TL;DR)
- 流水线阶段是持续交付流水线中按顺序划分的一段可执行环节,围绕一个明确的验证或交付目标组织操作,并产生供后续环节使用的产出物。
- 判断一个环节是否构成阶段,可看四个要素:触发条件、执行动作、产出物、进入下一阶段的条件。
- 阶段划分粒度可粗可细,取决于交付目标与风险控制需要;流水线与平台对接、发布审批与质量门禁属于相邻主题,不纳入阶段定义。
- 阶段之间通过执行顺序、产出传递和状态判定衔接,失败时可选择停止、回退或从失败阶段重跑。
- 阶段与构建任务、部署环境、质量门禁、流水线模板处于不同概念层级,混用会让流水线描述含混。
流水线阶段指什么:一句话定义与关键要素
流水线阶段(Pipeline Stage)是持续交付流水线中按执行顺序划分的一段可执行环节,它围绕一个明确的交付目标组织一组操作,并产生可供后续环节使用的产出物。一个阶段结束时,流水线要么满足条件进入下一阶段,要么因失败而停止或转入处理分支。这一定义包含三层含义:阶段是流水线的组成单位,阶段有明确的进入与退出条件,阶段之间通过产出物建立依赖。
判断某个环节是否构成一个阶段,可以看它是否同时具备以下四个要素:
| 要素 | 含义 | 判断示例 |
|---|---|---|
| 触发条件 | 什么情况下进入这个阶段,例如代码提交、上一阶段成功、人工确认 | “合并到主干后自动进入构建阶段”具备触发条件 |
| 执行动作 | 阶段内实际执行的操作集合,可以是一个或多个任务 | 编译代码、运行单元测试、打包镜像 |
| 产出物 | 阶段结束后留下的可识别结果,如构建产物、测试报告、部署记录 | 生成的可执行包与测试报告 |
| 进入下一阶段的条件 | 判定本阶段是否通过的标准,如全部测试通过、部署健康检查成功 | 测试通过率达标才允许进入部署阶段 |
阶段与整条流水线是部分与整体的关系。流水线描述从代码变更到交付上线的完整路径,阶段则是这条路径上按目标切分出的段落。一条流水线通常包含多个阶段,阶段数量与内容由交付目标决定,没有统一的标准段数。理解这一点,可以避免把某个工具界面上的固定栏目直接当作阶段定义。
流水线阶段包括什么、不包括什么
属于阶段本身的内容包括:执行环节及其顺序、每个环节的输入与输出、环节之间的依赖关系,以及环节内部的执行动作。这些内容共同回答“这一步做什么、拿什么做、做完留下什么”。阶段划分的粒度可以粗也可以细:小团队可能把编译和单元测试合并为一个“构建验证”阶段,交付要求高的团队则可能把静态检查、单元测试、集成测试拆成多个阶段,以便问题定位更精确。
以下内容属于相邻主题,不纳入阶段的定义范围:流水线与各类研发平台的对接配置、发布审批流程与质量门禁规则设计、具体工具的产品功能测评与选型。这些内容与阶段有关联,例如门禁规则会决定阶段能否进入下一环节,但它们描述的是规则设计或工具配置,回答的是另一个问题。
| 内容 | 是否属于阶段本身 | 归属说明 |
|---|---|---|
| 构建、测试、部署等执行环节 | 属于 | 阶段的核心内容 |
| 阶段顺序与输入输出 | 属于 | 阶段之间的结构关系 |
| 流水线与代码平台、制品库的对接配置 | 不属于本文重点 | 属于工具链集成主题 |
| 发布审批流程、质量门禁规则 | 不属于本文重点 | 属于发布准入主题,与阶段衔接相关但概念不同 |
| 阶段划分的粗细程度 | 属于 | 是阶段设计的一部分,取决于交付目标与风险控制需要 |
需要说明的是,边界划分的目的是让讨论有共同对象,并不意味着一篇讲阶段的文章不能提到门禁或集成。当门禁规则决定阶段能否继续时,它作为阶段衔接的条件出现;当集成配置决定流水线能否取到代码时,它作为阶段运行的前提出现。区分的是概念归属,而非禁止关联。
阶段如何串起一次交付:运行机制与组成
阶段之间通过三种机制衔接:执行顺序、产出传递和状态判定。顺序决定谁先谁后,产出传递决定下一阶段拿什么继续,状态判定决定是否允许继续。三者共同作用,使流水线成为一条可追踪的交付路径,而非若干孤立步骤的集合。
顺序执行与并行执行。顺序执行指前一阶段完成后才启动下一阶段,适合存在强依赖的环节,例如先构建出制品才能部署。并行执行指多个阶段同时运行,适合彼此独立的验证,例如单元测试与静态代码检查可以同时进行,以缩短反馈时间。并行阶段通常需要在汇合点统一判定结果,任何一个并行分支失败都可能影响后续流程。
阶段间的产出物传递。上一阶段的产出成为下一阶段的输入,这是阶段划分能够成立的关键。构建阶段产出制品,测试阶段消费该制品并产出测试报告,部署阶段消费制品并产出部署记录。产出物需要有明确的存放位置和版本标识,否则下游阶段无法确认自己验证的是哪一次构建的结果。
失败后的停止、回退与重跑。阶段失败时,常见处理方式有三种:停止整条流水线,等待人工排查;回退到上一可用版本或上一环境;在修复后从失败阶段重跑,复用此前阶段的产出。选择哪种方式取决于失败性质和产出物是否仍然有效。例如测试失败通常只需修复后重跑测试阶段,而生产部署失败可能需要回退并重新走发布流程。
阶段状态的观察。每个阶段通常有等待、运行中、成功、失败、已取消等状态,阶段状态汇总为整条流水线的状态。观察阶段状态的价值在于定位阻塞点:当流水线停在某个阶段时,团队能直接看到是构建失败、测试未通过还是部署检查未完成。对于把流水线与项目管理关联起来的团队,阶段状态还可以与需求、任务等工作项对应,帮助判断某个需求的交付进行到哪一步。ONES DevOps 解决方案支持集成 Jenkins、GitLab CI 等第三方流水线工具,集成后自动同步流水线数据、更新执行状态和日志,并可在项目、迭代、需求中查看流水线构建与产品发布等过程,这为阶段状态的跨角色观察提供了一种承载方式。
流水线阶段与构建、任务、环境、门禁的区别
阶段容易与几个相邻概念混淆,区别在于它们回答的问题不同:阶段回答“交付路径上这一段做什么”,构建任务回答“具体执行了哪个操作”,环境回答“在哪里运行”,门禁回答“是否允许继续”,模板回答“如何复用一套配置”。
| 概念 | 回答的问题 | 与阶段的关系 |
|---|---|---|
| 流水线阶段 | 交付路径上这一段承担什么验证或交付任务 | 本身是划分单位,包含一个或多个任务 |
| 构建任务 | 具体执行了哪条命令或哪个作业 | 是阶段内部的执行单元,一个阶段可包含多个任务 |
| 部署环境 | 代码或制品运行在哪个环境 | 是阶段动作的作用对象,例如“部署到预发”是一个阶段,预发是环境 |
| 质量门禁与审批 | 满足什么条件才允许继续 | 是阶段进入下一阶段的条件,属于规则而非阶段本身 |
| 流水线模板 | 如何复用一套阶段与任务配置 | 是阶段的组织与复用方式,模板可以预置阶段结构 |
以“部署到预发环境”为例:部署是一个阶段,预发是环境,部署脚本是阶段内的任务,部署后的人工确认是门禁。四者出现在同一句话里,但概念层级不同。把环境名当作阶段名、把门禁当作阶段,都会让流水线描述变得含混,也不利于后续调整。
一个具体例子与常见误解
下面用一条演示性的交付流水线说明阶段划分。该示例用于解释阶段思路,不代表任何具体产品的实际配置。
| 阶段 | 输入 | 主要动作 | 产出 | 进入下一阶段的条件 |
|---|---|---|---|---|
| 构建 | 代码提交记录 | 拉取代码、编译、打包制品 | 带版本号的制品 | 构建成功且制品入库 |
| 自动化测试 | 构建阶段产出的制品 | 运行单元测试、接口测试 | 测试报告与通过率 | 测试全部通过或达到约定阈值 |
| 预发部署 | 同一制品 | 部署到预发环境并执行冒烟检查 | 部署记录与检查结果 | 部署成功且冒烟检查通过 |
| 生产发布 | 预发验证通过的制品 | 按发布策略上线并观察 | 发布记录与运行状态 | 发布完成,异常在可接受范围 |
这条流水线中,每个阶段都有清晰的输入、动作和产出,上一阶段的产出直接成为下一阶段的输入。如果测试阶段失败,流水线停在测试环节,构建产物仍然保留,修复后可以从测试阶段重跑,无需重新构建。如果预发部署失败,则需要判断是制品问题还是环境问题,再决定回退或重试。
围绕阶段划分,有几个常见误解值得澄清:
- 阶段数量越多越好。阶段数量应与风险控制需要匹配。阶段过多会增加等待和交接成本,阶段过少则问题暴露得晚、定位范围大。合适的划分让每类问题在对应的阶段被拦住。
- 阶段等于某个工具页面。阶段是交付流程的结构概念,工具页面只是它的呈现方式。不同工具对阶段的叫法和展示可能不同,判断标准仍是触发条件、执行动作、产出物和进入条件。
- 阶段一旦划定不可调整。阶段划分应随交付目标变化而调整。团队引入新的验证手段、合并环境或改变发布节奏时,阶段结构也需要相应修改,调整后应同步更新相关文档和协作约定。
当阶段划分确定后,团队还需要让阶段状态在协作中被看见。ONES 可将流水线与项目关联,在项目、迭代、需求中可视化代码提交、流水线构建、产品发布等 CI/CD 过程,使开发、测试和项目管理者基于同一份执行状态判断阻塞位置;对于需要把交付进度与需求交付对应起来的团队,这种关联减少了在多个系统之间核对状态的动作。
常见问题
阶段划分得越细,交付质量就越高吗?
不一定。阶段划分的收益来自让问题在更早、更小的范围内暴露,但每增加一个阶段,也会增加等待、交接和状态核对的动作。判断粒度是否合适,可以看两点:每类问题是否都有对应的阶段拦住,以及阶段之间的等待是否已经成为交付瓶颈。如果某个阶段长期没有独立发现过问题,可以考虑与相邻阶段合并;如果某类问题反复在后期才暴露,则值得拆出更早的验证阶段。
流水线阶段失败后,应该整条重跑还是从失败阶段继续?
取决于失败性质和此前产出物是否仍然有效。测试阶段失败时,构建产物通常仍然可用,修复后从测试阶段重跑即可,无需重新构建。如果失败涉及制品本身或环境状态,例如构建产物损坏、预发环境被污染,则需要回到更早的阶段重新生成或恢复环境。生产发布失败往往需要先回退,再按发布流程重新走一遍。团队可以事先约定哪些阶段支持重跑、哪些情况必须回退,减少临时判断的分歧。
阶段状态和需求状态如何对应起来?
两者描述的对象不同:阶段状态描述一次流水线执行进行到哪一步,需求状态描述一个工作项在研发流程中的位置。把两者关联起来,可以让团队看到某个需求的代码提交、构建、发布分别处于什么状态,从而判断交付阻塞在哪里。ONES DevOps 解决方案支持集成 Jenkins、GitLab CI 等第三方流水线工具,集成后自动同步流水线数据、更新执行状态和日志,并可在项目、迭代、需求中查看流水线构建与产品发布等过程。关联方式需要结合团队的工作项结构和流水线配置来设计。
并行阶段的结果如何判定是否继续?
并行阶段通常在汇合点统一判定。常见做法是设定汇合规则,例如所有并行分支都成功才进入下一阶段,或允许非关键分支失败但记录结果。规则需要与阶段目标一致:如果并行的是单元测试和静态检查,两者都关系到代码质量,通常要求全部通过;如果并行的是不同环境的兼容性验证,则可能按优先级设定必须通过的分支。汇合规则确定后,应让阶段状态能够反映每个分支的结果,避免只看汇总状态而忽略具体失败项。
阶段结构确定后,调整时需要注意什么?
阶段划分应随交付目标变化而调整,例如引入新的验证手段、合并环境或改变发布节奏。调整时需要注意三点:一是同步更新流水线配置与相关文档,避免描述与实际执行不一致;二是检查依赖该阶段产出物的下游环节,确认产出物的位置和标识仍然可用;三是与协作方对齐新的进入条件,特别是涉及人工确认或跨团队交接的环节。调整不必一次到位,可以先在小范围流水线上验证,再推广到主要交付路径。
