交付流水线是把代码从提交到形成可交付版本之间的构建、测试、制品打包与环境部署等动作,按固定顺序串联并自动执行的机制。本文围绕定义、组成、运行过程与范围边界展开,平台对接配置和发布审批不在本文重点内。
要点总览(TL;DR)
- 交付流水线是由代码变更触发、按预设阶段顺序自动执行构建、测试、打包与部署,并产出可交付版本的执行链路,四个要素是触发、阶段顺序、自动执行、可交付产物。
- 它的范围止于交付动作的执行:构建、测试、打包、部署与执行记录属于流水线;与代码平台、制品库、云平台的对接归研发工具链集成,发布准入与审批门禁归发布审批与质量门禁。
- 一条流水线由触发源、阶段与任务、运行环境与执行器、制品与版本、状态与反馈、配置即代码六部分组成,其中配置即代码常被忽略,影响流水线本身的可维护性。
- 持续集成流水线通常止于构建与自动化测试,交付流水线继续延伸到制品打包与环境部署;发布流程负责放行决策,与流水线的执行动作分工不同。
- 流水线跑通只说明执行成功,不等于可以发布;阶段数量应与验证需要匹配,主链路保持精简,重任务放到定时或按需触发的分支中。
交付流水线的准确定义
交付流水线(Delivery Pipeline)可以这样表述:它是一条由代码变更触发、按预设阶段顺序自动执行构建、测试、打包与部署任务,并最终产出可交付版本的执行链路。这个定义包含四个要素,缺一项就很难称为完整的交付流水线。
| 要素 | 含义 | 判断要点 |
|---|---|---|
| 触发 | 流水线由明确事件启动,如代码提交、合并请求、定时任务或人工手动发起 | 能否说清“什么事件会让它跑起来” |
| 阶段顺序 | 构建、测试、打包、部署等任务按依赖关系排列,前序阶段通过才进入后续阶段 | 阶段之间是否存在明确的先后与准入关系 |
| 自动执行 | 触发后各阶段由系统调度执行,无需人工逐步操作 | 中间环节是否需要人反复手动干预 |
| 可交付产物 | 每次运行产出可识别、可留存的构建产物或部署结果 | 运行结束后是否留下可被后续环节取用的产物 |
流水线与持续集成、持续交付的关系是承载与被承载。持续集成强调频繁合并代码并自动验证,持续交付强调让软件始终处于可发布状态,两者都是实践主张;交付流水线则是把这些实践落到具体执行动作上的载体。团队说“我们在做持续集成”,通常指每次提交都触发流水线跑构建和测试;说“我们在做持续交付”,通常指流水线一直延伸到可部署环境的验证环节。
交付流水线包括什么、不包括什么
交付流水线的范围止于交付动作的执行本身。构建、测试、打包、部署这些“做事”的环节属于流水线;决定“能不能放行”的审批规则、以及流水线与外部系统如何连接,属于相邻主题。判断某一步是否属于流水线,可以问一句:这一步是在执行交付动作,还是在决定是否放行,或者是在配置系统之间的连接?
| 内容 | 归属 | 说明 |
|---|---|---|
| 代码编译构建、单元测试与集成测试执行 | 属于流水线 | 流水线的核心执行阶段 |
| 制品打包、归档与版本标识 | 属于流水线 | 产出可交付产物并留存 |
| 向测试环境、预发环境执行部署 | 属于流水线 | 部署动作本身由流水线执行 |
| 每次运行的执行记录、日志与结果回传 | 属于流水线 | 形成可追溯的执行轨迹 |
| 流水线与代码平台、制品库、云平台的对接配置 | 归研发工具链集成 | 解决系统之间如何连通与同步 |
| 发布准入条件、审批流程与质量门禁规则 | 归发布审批与质量门禁 | 解决是否允许放行的问题 |
这条边界在实际工作中容易模糊。例如,流水线在部署到生产环境前暂停等待审批,暂停这个动作由流水线执行,但审批规则怎么定、谁有权批,属于发布审批主题。把两者分开描述,团队在讨论问题时才能定位到正确的环节:流水线跑失败,查执行;流水线跑成功但没放行,查审批。
一条交付流水线由哪些部分组成
把流水线拆开看,它由六个部分构成。每个部分承担独立职责,缺失时会在运行中表现出不同的问题。
| 组成部分 | 职责 | 缺失后的典型表现 |
|---|---|---|
| 触发源 | 定义流水线何时启动,常见为代码提交、合并请求、定时或手动触发 | 只能靠人记得去点,改动容易漏跑验证 |
| 阶段与任务 | 按顺序编排构建、测试、扫描、打包、部署等任务 | 步骤散落在个人操作里,执行顺序和完整性无法保证 |
| 运行环境与执行器 | 提供任务运行的计算环境,保证每次执行条件一致 | 出现“本地能跑、流水线跑不过”的环境差异问题 |
| 制品与版本 | 标识每次运行产出的产物并留存,供后续环境取用 | 部署时找不到对应版本,或无法确认线上跑的是哪次构建 |
| 状态与反馈 | 记录成功失败状态,把结果通知到相关角色 | 失败无人知晓,问题发现时间被拉长 |
| 配置即代码 | 把流水线定义写入版本库,随代码一起评审和变更 | 流水线配置只存在个别人手里,改动无记录、难复现 |
这六个部分中,配置即代码常被忽略。流水线定义如果只保存在工具界面上,修改就没有评审记录,出问题时也难以回滚到上一个可用版本。把定义纳入版本管理后,流水线本身的变更和业务代码的变更走同一套评审流程,执行链路才真正可维护。
一次交付流水线是怎么跑起来的
下面按一次典型运行描述链路,每步标注输入与产出,便于对照自己团队的流水线检查断点。
- 触发。开发者提交代码或发起合并请求,代码平台产生事件。输入是代码变更,产出是一次待执行的流水线运行实例。
- 首个阶段启动。调度系统拉取对应版本的代码,分配执行环境,启动构建任务。输入是代码版本与流水线定义,产出是运行中的任务。
- 阶段推进。构建通过后进入测试阶段。单元测试、集成测试可以并行分支执行,缩短整体时长;有依赖关系的阶段保持串行。输入是构建产物,产出是测试结果。
- 失败处理。任一阶段失败,后续阶段中断,运行标记为失败并通知相关角色。修复后可重跑整条流水线,或从失败阶段继续。涉及已部署环境的失败,需要按预案回退到上一可用版本。
- 制品归档。打包阶段产出制品,写入制品库并打上版本标识。输入是构建结果,产出是可被检索和取用的制品。
- 环境部署。部署阶段从制品库取出指定版本,部署到目标环境。输入是制品版本号,产出是环境中的运行实例。
- 记录形成。整次运行的触发来源、各阶段状态、日志与产物版本汇总为执行记录,供后续追溯和问题定位。
这条链路中有两个关键衔接点:一是制品库,它把“构建”和“部署”解耦,部署不再依赖重新构建;二是执行记录,它把一次运行的所有信息固定下来,事后能回答“这个版本是什么时候、由哪次提交、经过哪些阶段产生的”。
当团队需要把流水线执行情况与需求、任务对应起来时,可以在项目管理工具中承载这层关联。ONES 支持集成 Jenkins、GitLab CI 等第三方流水线工具,集成后自动同步流水线数据并更新执行状态和日志;在项目、迭代、需求中可查看代码提交、流水线构建、产品发布等过程,帮助团队把一次构建结果回溯到对应的需求与任务上,识别交付中的阻塞环节。
容易混淆的几个相邻概念
交付流水线常与四个概念混用。区分它们的关键不在名词,而在范围终点和职责分工。
| 概念 | 与交付流水线的区别 | 判断问句 |
|---|---|---|
| 持续集成流水线 | 范围通常止于构建与自动化测试,终点是验证这次提交是否可用;交付流水线继续延伸到制品打包与环境部署 | 这条流水线跑完后,是否直接产出可部署的版本? |
| 发布流程 | 发布流程处理放行决策,包括审批、准入条件与发布窗口;交付流水线执行具体动作 | 这个问题是在问“怎么做”,还是在问“能不能做”? |
| 研发工具链集成 | 集成解决流水线与代码平台、制品库、云平台之间的连接与数据同步;流水线关注连接建立之后的执行 | 讨论的是系统之间怎么连,还是连上之后怎么跑? |
| 自动化脚本集合 | 脚本集合缺少统一编排、状态管理和执行记录;流水线把这些脚本组织成有顺序、有状态、可追溯的执行单元 | 失败时能否知道哪一步、哪次运行出的问题? |
其中最容易混淆的是持续集成流水线与交付流水线。两者在早期阶段高度重合,差别在终点:前者回答“这次改动有没有破坏现有功能”,后者还要回答“这次改动能不能形成一个可交付的版本”。团队规模扩大后,把这两个终点分开设置,可以让快速反馈和完整交付各按合适节奏运行。
具体例子与常见误解
以下为一个中等规模研发团队的演示性示例,用于说明流水线的实际形态,不代表特定企业情况。
该团队的主干分支配置了一条交付流水线,触发源为合并请求和主干提交。阶段依次为:代码静态检查、单元测试、构建打包、集成测试、制品归档、部署到测试环境、部署到预发环境。静态检查与单元测试并行执行,约数分钟给出反馈;集成测试依赖构建产物,串行执行;制品归档后,测试环境与预发环境部署取用同一版本制品。每次运行的状态和日志同步到项目管理工具,与对应需求关联。预发环境验证通过后,是否发布到生产由发布审批流程决定,不在流水线内完成。
围绕这个例子,有四个高频误解值得纠正。
- 误解一:有自动化脚本就等于有交付流水线。脚本能自动执行命令,但如果没有统一触发、阶段编排、状态记录和产物管理,执行结果无法复现也无法追溯。流水线的价值在于把零散脚本组织成有秩序的执行单元。
- 误解二:流水线跑通就等于可以发布。流水线通过说明构建、测试、部署动作执行成功,是否发布还要看准入条件、审批结论和发布窗口。执行成功是发布的前提之一,不是发布本身。
- 误解三:流水线越长越完整。阶段数量应与验证需要匹配。把耗时很长、与本次改动无关的检查都塞进主链路,会拉长反馈时间,反而降低提交频率。常见做法是主链路保持精简,重任务放到定时或按需触发的分支中。
- 误解四:流水线只与开发和运维有关。流水线的触发往往对应需求与任务的完成节点,执行结果直接影响需求能否交付。产品与测试角色需要知道某次改动跑到哪一步、卡在哪个阶段,这些信息来自流水线执行记录,而不只是开发和运维的内部事项。
理解这四个误解后,再回到定义:交付流水线是一条有触发、有顺序、自动执行、产出可交付版本的执行链路。它的边界在“执行”二字,向外连接工具链集成,向上衔接发布审批,各自解决不同问题。
常见问题
交付流水线和持续集成流水线在团队里需要分开建吗?
不必强行分成两条独立流水线,关键是明确终点。持续集成流水线的终点是验证这次提交是否可用,交付流水线的终点是产出可部署的版本。早期阶段两者高度重合,可以共用同一套阶段定义,在构建与测试之后继续接制品打包和环境部署。
当团队规模扩大、提交频率上升时,可以把快速反馈部分和完整交付部分拆成不同触发条件:每次提交跑构建与单元测试,合并到主干或按需触发时再跑完整的交付链路。这样既保证反馈速度,也保证可交付版本按一致方式产生。
流水线在部署到生产前暂停等待审批,这个暂停算流水线的一部分吗?
暂停这个动作由流水线执行,属于流水线的运行机制;但审批规则怎么定、谁有权批准、准入条件是什么,属于发布审批与质量门禁的范围。两者在同一个运行实例里衔接,职责却不同。
区分清楚的好处是定位问题更快:流水线在某个阶段执行失败,查执行日志和环境;流水线执行成功但停在等待审批,查审批规则和放行条件。团队讨论时把这两类问题分开,能减少互相推诿。
流水线定义放在工具界面里配置,和写进代码库有什么区别?
主要差别在变更管理和可复现性。定义保存在工具界面时,修改往往没有评审记录,出问题也难以回滚到上一个可用版本;不同环境的配置差异只能靠人记忆。
把流水线定义纳入版本库后,它和业务代码走同一套评审流程,每次修改都有记录、可对比、可回滚。这对多人协作的团队尤其重要:新成员能直接从代码库看到流水线怎么编排,不必依赖口头交接。是否采用配置即代码取决于团队协作规模和变更频率,小团队初期用界面配置也能运转。
流水线执行记录和需求、任务对不上,通常是什么原因?
常见原因是流水线运行与工作项之间缺少关联标识。代码提交信息里没有引用需求或任务编号,流水线执行记录就只是一次孤立的构建,事后无法回答“这个版本对应哪个需求”。
解决方式是在提交环节建立关联:提交信息引用工作项编号,或在项目管理工具中把代码分支与需求、任务绑定。ONES 支持集成 Jenkins、GitLab CI 等第三方流水线工具,集成后自动同步流水线数据并更新执行状态和日志;在项目、迭代、需求中可查看代码提交、流水线构建、产品发布等过程,把一次构建结果回溯到对应的工作项上。具体关联字段和追溯深度以实际配置为准。
流水线阶段越多,交付质量就越有保障吗?
阶段数量与质量保障不是简单的正比关系。每个阶段都会占用反馈时间,主链路越长,开发者等待结果越久,提交频率可能随之下降,反而削弱持续集成的效果。
更实用的做法是按验证目的分层:与本次改动直接相关、能快速给出结论的检查放在主链路;耗时较长、覆盖范围广的检查放到定时触发或按需触发的分支中。判断标准是这条检查能否在合理时间内给出可行动的结论,而不是阶段清单看起来是否完整。
