# CI/CD 流水线[](#cicd-pipelines "Permalink") 流水线是持续集成、交付和部署的顶级组件。 流水线包括: * 流水线任务,定义*要做* 什么。 例如,编译或测试代码的流水线任务。 * Stages,定义*何时* 运行流水线任务。 例如,在编译代码的阶段之后运行测试的阶段。 流水线任务由 [Runners](/docs/ci/runners) 执行。 如果有足够的并发 runners,则可以并行执行同一阶段中的多个流水线任务。 如果一个stage中的*所有* 流水线任务都成功,则流水线将继续进行下一个 stage。 如果某个 stage 中的任何流水线任务失败,则(通常)不会执行下一个 stage,并且流水线会提前结束。 通常,流水线是自动执行的,创建后就无需干预。 但是,有时你还可以手动与流水线进行交互。 典型的流水线可能包含四个 stages,按以下顺序执行: * 一个`build`阶段,其流水线任务称为`compile` 。 * 一个`test`阶段,具有两个流水线任务,分别称为`test1`和`test2` 。 * 一个`staging`阶段,其流水线任务称为`deploy-to-stage` 。 * 一个`production`阶段,其流水线任务称为`deploy-to-prod` 。 **注意:**如果你有[从 GitCode 提取镜像的仓库](/docs/user/project/repo/repo-mirror#pulling-from-a-remote-repository-starter),则可能需要在项目的**设置 >仓库 >镜像仓库 >触发流水线更新镜像**中启用流水线触发。 ## 流水线类型[](#types-of-pipelines "Permalink") 流水线可以通过多种不同的方式进行配置: * **基本流水线**:在每个stage同时运行所有内容,随后是下一stage。 * **定向非循环图流水线(DAG)流水线**:基于流水线任务之间的关系,并且比基本流水线运行得更快。 * **多项目流水线**:将不同项目的流水线组合在一起。 * **父子流水线**:将复杂的流水线分解为一个父流水线,该流水线可以触发多个子流水线,这些子流水线都在同一项目中并以相同的 SHA 运行。 * **合并请求的流水线仅针对合并请求**:只在合并请求运行(而不是针对每次提交)。 * **合并结果流水线:是合并请求流水线**,其作用就像源分支的更改已被合并到目标分支一样。 * **合并列车**:使用流水线获取合并结果,以使合并一个接一个地排队。 ## 流水线配置[](#configure-a-pipeline "Permalink") 在 CI/CD 流水线配置文件中为每个项目定义了流水线及其组件流水线任务和 stages。 * 流水线任务是基本的配置组件。 * Stages 是通过使用[`stages`](/docs/ci/yaml#stages)关键字定义的。 有关 CI 流水线文件中配置选项的列表,请参见《 [GitCode CI/CD 流水线配置参考》](/docs/ci/yaml) 。 你还可以通过 GitCode UI 配置流水线的特定方面。 例如: * 每个项目的[流水线设置](/docs/ci/pipelines/settings) 。 * [流水线计划](/docs/ci/pipelines/schedules)。 * [自定义 CI/CD 变量](/docs/ci/variables#custom-environment-variables)。 ### 查看流水线[](#view-pipelines "Permalink") 你可以在项目的 **DevOps >流水线**页面下找到当前和历史流水线运行。你还可以通过导航到 **流水线**选项卡来访问合并请求的**流水线** 。 [![Pipelines index page](/docs/img/pipelines_index.png)](/docs/img/pipelines_index.png) 单击流水线打开**流水线详细信息**页面,并显示为该流水线运行的任务。在这里,你可以取消正在运行的流水线,在发生故障的流水线上重试流水线任务或[删除流水线](#delete-a-pipeline)。 可以在`/project/pipelines/[branch]/latest`找到指向给定分支的最后提交的最新流水线的链接。 另外, `/project/pipelines/latest`会将你重定向到项目默认分支上最后一次提交的最新流水线。 你可以通过以下方式过滤流水线列表: * 触发者 * 分支名称 * 状态 * 标签 ### 手动运行流水线[](#run-a-pipeline-manually "Permalink") 可以使用预定义或手动指定的[变量](/docs/ci/variables)手动执行流水线。 如果在流水线的正常操作之外需要流水线的结果(例如,代码构建),则可以执行此操作。 要手动执行流水线: 1. 导航到项目的 **DevOps >流水线** 。 2. 单击**运行流水线**按钮。 3. 在 **运行流水线**页面上: 1. 在 **运行分支或 tag** 字段中选择要为其运行流水线的分支或 tag。 2. 输入流水线运行所需的任何[环境变量](/docs/ci/variables) 。 3. 单击**运行流水线**按钮。 流水线将按照配置执行流水线任务。 ### 使用 URL 查询字符串运行流水线[](#run-a-pipeline-by-using-a-url-query-string "Permalink") 你可以使用查询字符串来预填充**运行流水线**页面。 例如,查询字符串使用以下内容`.../pipelines/new?ref=my_branch&var[foo]=bar&file_var[file_foo]=file_bar`预填充 **运行流水线** 页面: - **运行** 字段: `my_branch`。 - **变量** 部分: - Variable: - Key: `foo` - Value: `bar` - File: - Key: `file_foo` - Value: `file_bar` `pipelines/new` URL 的格式为: ```plaintext .../pipelines/new?ref=&var[]=&file_var[]= ``` 支持以下参数: * `ref` :指定用于填充" **运行为"**字段的分支。 * `var` :指定一个`Variable`变量。 * `file_var` :指定一个`File`变量。 对于每个`var`或`file_var` ,都需要一个键和一个值。 ### 向流水线添加手动交互[](#add-manual-interaction-to-your-pipeline "Permalink") 使用[`when:manual`](/docs/ci/yaml#whenmanual)关键字配置的手动操作允许你可在流水线前进之前需要手动交互。 你可以直接从流水线图执行此操作。 只需单击播放按钮即可执行该特定流水线任务。 例如,你的流水线可能会自动启动,但是需要手动操作才能部署到生产中。在下面的示例中, `production`阶段有一个需要手动操作的工作。 [![Pipelines example](/docs/img/pipelines.png)](/docs/img/pipelines.png) #### 在一个 stage 启动多个手动操作[](#start-multiple-manual-actions-in-a-stage "Permalink") 可以使用"全部播放手动"按钮同时启动一个阶段中的多个手动动作。 用户单击此按钮后,将触发每个单独的手动操作并将其刷新为更新状态。 此功能仅可用: * 至少具有开发者访问权限的用户。 * 如果阶段包含[手动操作](#add-manual-interaction-to-your-pipeline) 。 ### 删除流水线[](#delete-a-pipeline "Permalink") 在项目中具有[所有者权限的](/docs/user/permissions)用户可以通过以下方式删除流水线:单击 **CI/CD >流水线**以转到**流水线详细信息**页面,然后使用 **删除**按钮。 [![Pipeline Delete Button](/docs/img/pipeline-delete.png)](/docs/img/pipeline-delete.png) **警告**:删除流水线将使所有流水线缓存失效,并删除所有相关对象,例如构建、日志、工件和触发器。 **此操作无法撤消** ### 流水线配额[](#pipeline-quotas "Permalink") 每个用户都有一个个人流水线配额,该配额跟踪所有个人项目中共享 runners 的使用情况。每个组都有一个使用配额 ,该配额跟踪该组内创建的所有项目的共享 runners 的使用。 触发流水线时,无论是谁触发的,都会使用项目所有者的 [namespace](/docs/user/org#命名空间) 的流水线配额。在这种情况下,namespace 可以是拥有项目的用户或组。 #### 如何计算流水线持续时间[](#how-pipeline-duration-is-calculated "Permalink") 给定流水线的总运行时间不包括重试和挂起(排队)时间。 每个流水线任务都表示为一个`Period` ,它包括: * `Period#first` (流水线任务开始时)。 * `Period#last` (流水线任务完成时)。 一个简单的例子是: * A(1,3) * B(2,4) * C(6,7) 在示例中: * A 从 1 开始到 3 结束。 * B 从 2 开始到 4 结束。 * C 从 6 开始到 7 结束。 在视觉上,它可以被视为: ``` 0 1 2 3 4 5 6 7 AAAAAAA BBBBBBB CCCC ``` A,B 和 C 的并集是(1、4)和(6、7)。 因此,总运行时间为: ``` (4 - 1) + (7 - 6) => 4 ``` ### 受保护分支上的流水线安全[](#pipeline-security-on-protected-branches "Permalink") 在[受保护的分支](/docs/user/project/protected_branch)上执行流水线时,将强制执行严格的安全模型。 仅当[允许用户合并或推送到](/docs/user/project/protected_branch#using-the-allowed-to-merge-and-allowed-to-push-settings)该特定分支时,才可以在受保护的分支上执行以下操作: * 运行手动流水线(使用 [Web UI](#run-a-pipeline-manually)或[流水线 API](#pipelines-api) )。 * 运行预定的流水线。 * 使用触发器运行流水线。 * 在现有流水线上触发手动操作。 * 重试或取消现有流水线任务(使用 Web UI 或流水线 API)。 标记为**受保护的变量**只能由在受保护的分支上运行的流水线任务访问,从而防止不受信任的用户意外访问敏感信息,如部署凭据和令牌。 **Runners**标记为**保护**只能保护分支运行的流水线任务,防止不可信代码在受保护执行和不小心被访问保护部署密钥和其它凭证。 为了确保打算在受保护的 runner 上执行的流水线任务不会使用常规运行程序,必须对它们进行相应标记。