{{< details >}}

  • Tier: Flagship
  • Offering: JihuLab.com, 私有化部署

{{< /details >}}

{{< history >}}

  • 引入于极狐GitLab 17.2,使用名为 pipeline_execution_policy_type功能标识。默认启用。
  • 在极狐GitLab 17.3 中 GA。功能标志 pipeline_execution_policy_type 已删除。

{{< /history >}}

使用流水线执行策略来管理和实施多个项目的 CI/CD 作业,只需一个配置。

流水线执行策略架构

{{< history >}}

  • 在极狐GitLab 17.4 中,启用了 suffix 字段。
  • 在极狐GitLab 17.7 中,更改了流水线执行,以便在 .pipeline-policy-pre 阶段完成后,后续阶段等待。

{{< /history >}}

包含流水线执行策略的 YAML 文件由一个对象数组组成,这些对象匹配嵌套在 pipeline_execution_policy 键下的流水线执行策略架构。你可以在每个安全策略项目下配置最多五个策略。任何在前五个之后配置的策略都不会被应用。

当你保存新的策略时,极狐GitLab 会根据 这个 JSON 架构 验证其内容。如果你不熟悉如何阅读 JSON 架构,以下部分和表格提供了替代方案。

字段 类型 必须 描述
pipeline_execution_policy array of pipeline execution policy true 流水线执行策略列表(最多五个)

流水线执行策略架构

字段 类型 必须 描述
name string true 策略名称。最多 255 个字符。
description (optional) string true 策略描述。
enabled boolean true 启用(true)或禁用(false)策略的标志。
content object of content true 引入项目流水线的 CI/CD 配置引用。
pipeline_config_strategy string false 可以是 inject_policyinject_ci(已弃用)或 override_project_ci。有关更多信息,请参见流水线策略
policy_scope object of policy_scope false 根据您指定的项目、群组或合规框架标签调整策略范围。
suffix string false 可以是 on_conflict(默认)或 never。定义处理作业命名冲突的行为。on_conflict 为作业名称应用唯一后缀,以防止破坏唯一性。never 导致流水线失败,如果项目和所有适用策略中的作业名称不是唯一的。
skip_ci object of skip_ci false 定义用户是否可以应用 skip-ci 指令。默认情况下,忽略 skip-ci 的使用,因此具有流水线执行策略的流水线无法被跳过。

请注意以下内容:

  • 触发流水线的用户必须至少拥有读取访问权限才能访问策略中指定的流水线执行文件,否则流水线无法启动。
  • 如果流水线执行文件被删除或重命名,则强制实施策略的项目中的流水线可能会停止工作。
  • 流水线执行策略作业可以分配给两个保留阶段之一:
    • .pipeline-policy-pre 在流水线开始时,在 .pre 阶段之前。
    • .pipeline-policy-post 在流水线结束时,在 .post 阶段之后。
  • 在任何保留阶段注入作业都能保证始终有效。执行策略作业也可以分配给任何标准(构建、测试、部署)或用户声明的阶段。然而,在这种情况下,根据项目流水线配置可能会忽略作业。
  • 不可能在流水线执行策略之外将作业分配给保留阶段。
  • 无论 needs 关键字如何,流水线中的作业都不会开始,直到 .pipeline-policy-pre 阶段完成。要在流水线开始时运行非阻塞作业,请添加一个自定义阶段,该阶段在 .pre 阶段之前运行。例如:stages: [custom-non-blocking-stage, .pre]
  • 为流水线执行策略选择唯一的作业名称。有些 CI/CD 配置基于作业名称,如果同一流水线中存在多个相同的作业名称,可能会导致意外结果。例如,needs 关键字使一个作业依赖于另一个作业。如果有多个名为 example 的作业,则依赖于 example 作业名称的作业只依赖于一个随机的 example 作业实例。
  • 即使项目缺少 CI/CD 配置文件,流水线执行策略仍然有效。
  • 策略的顺序对于应用后缀很重要。
  • 如果应用于给定项目的任何策略具有 suffix: never,则如果另一个具有相同名称的作业已经存在于流水线中,流水线将失败。
  • 流水线执行策略在所有分支和流水线来源上强制执行。您可以使用 工作流规则 来控制何时强制执行流水线执行策略。

作业命名最佳实践

{{< history >}}

  • 名称冲突处理引入于极狐GitLab 17.4。

{{< /history >}}

没有可见的指示器表明作业是由安全策略生成的。为了更容易识别由策略创建的作业并避免作业名称碰撞,请在作业名称中添加唯一的前缀或后缀。

示例:

  • 使用:policy1:deployments:sast。这个名称在所有其他策略和项目中可能是唯一的。
  • 不使用:sast。这个名称在其他策略和项目中可能会重复。

流水线执行策略根据 suffix 属性处理命名冲突。如果有多个具有相同名称的作业:

  • 使用 on_conflict(默认),如果作业名称与流水线中的另一个作业发生冲突,则会添加后缀。
  • 使用 never,在发生冲突时不添加后缀,并且流水线失败。

根据作业合并到主流水线的顺序添加后缀。

顺序如下:

  1. 项目流水线作业
  2. 项目策略作业(如果适用)
  3. 群组策略作业(如果适用,按层次结构排序,最高级群组作为最后应用)

应用的后缀格式如下:

:policy-<security-policy-project-id>-<policy-index>

结果作业示例:sast:policy-123456-0

如果一个安全策略项目中的多个策略定义了相同的作业名称,则数字后缀对应于冲突策略的索引。

结果作业示例:

  • sast:policy-123456-0
  • sast:policy-123456-1

作业阶段最佳实践

在流水线执行策略中定义的作业可以使用项目 CI/CD 配置中定义的任何 阶段,也包括保留阶段 .pipeline-policy-pre.pipeline-policy-post

{{< alert type=”note” >}}

如果您的策略仅在 .pre.post 阶段中包含作业,则策略的流水线被评估为 empty。它不会与项目的流水线合并。

要在流水线执行策略中使用 .pre.post 阶段,您必须至少包含一个在不同阶段运行的其他作业。例如:.pipeline-policy-pre

{{< /alert >}}

当您使用 inject_policy 流水线策略 时,如果目标项目不包含自己的 .gitlab-ci.yml 文件,则所有策略阶段都会被注入到流水线中。

当您使用(已弃用的)inject_ci 流水线策略时,如果目标项目不包含自己的 .gitlab-ci.yml 文件,则只有默认的流水线阶段和保留阶段可用。

当您在您无权修改的 CI/CD 配置项目上强制执行流水线执行策略时,您应在 .pipeline-policy-pre.pipeline-policy-post 阶段中定义作业。这些阶段始终可用,无论任何项目的 CI/CD 配置如何。

当您使用多个流水线执行策略和自定义阶段的 override_project_ci 流水线策略时,阶段必须以相同的相对顺序定义,以确保彼此兼容:

有效配置示例:

  - override-policy-1 stages: [build, test, policy-test, deploy]
  - override-policy-2 stages: [test, deploy]

无效配置示例:

  - override-policy-1 stages: [build, test, policy-test, deploy]
  - override-policy-2 stages: [deploy, test]

如果一个或多个 override_project_ci 策略具有无效的 stages 配置,流水线将失败。

content 类型

字段 类型 必须 描述
project string true 项目在同一极狐GitLab 实例上的完整项目路径。
file string true 相对于根目录(/)的完整文件路径。YAML 文件必须具有 .yml.yaml 扩展名。
ref string false 用于检索文件的 ref。默认情况下未指定时为项目的 HEAD。

在策略中使用 content 类型来引用存储在另一个存储库中的 CI/CD 配置。这使您可以在多个策略中重用相同的 CI/CD 配置,从而减少维护这些配置的开销。例如,如果您有一个自定义密钥检测 CI/CD 配置,您想在策略 A 和策略 B 中实施,您可以创建一个 YAML 配置文件并在两个策略中引用该配置。

前提条件:

  • 在实施 content 类型的策略的项目上运行的流水线的用户必须至少具有对包含 CI/CD 的项目的读取访问权限。
  • 在强制执行流水线执行策略的项目中,用户必须至少具有对包含 CI/CD 配置的项目的读取访问权限才能触发流水线。

    在极狐GitLab 17.4 及更高版本中,您可以在安全策略项目的一般设置中启用 流水线执行策略 设置,为策略项目中指定的 CI/CD 配置文件授予所需的读取访问权限。启用此设置后,触发流水线的用户将获得读取由流水线执行策略强制执行的 CI/CD 配置文件的权限。此设置不会授予用户访问存储配置文件的项目的其他部分的权限。有关详细信息,请参阅 自动授予访问权限

skip_ci 类型

{{< history >}}

  • 引入于极狐GitLab 17.7。

{{< /history >}}

流水线执行策略提供对谁可以使用 [skip ci] 指令的控制。您可以指定某些用户或服务帐户被允许使用 [skip ci],同时仍确保执行关键的安全和合规检查。

使用 skip_ci 关键字来指定用户是否可以应用 skip_ci 指令来跳过流水线。当未指定关键字时,skip_ci 指令被忽略,防止所有用户绕过流水线执行策略。

字段 类型 可能的值 描述
allowed boolean true, false 允许(true)或禁止(false)使用强制执行流水线执行策略的流水线的 skip-ci 指令的标志。
allowlist object users 指定始终被允许使用 skip-ci 指令的用户,无论 allowed 标志如何。使用 users: 后跟一个包含 id 键表示用户 ID 的对象数组。

策略范围架构

要自定义策略实施,您可以定义策略的范围,以包括或排除指定的项目、群组或合规框架标签。有关详细信息,请参阅 范围

流水线执行策略限制

出于性能原因,极狐GitLab 限制了可以作为安全策略项目或流水线的一部分运行的流水线执行策略的数量。默认情况下,这些是流水线执行策略的最大数量:

  • 每个安全策略项目五个
  • 每个流水线五个

调整策略限制

{{< history >}}

  • 可配置的限制引入于极狐GitLab 17.11。

{{< /history >}}

每个安全策略项目最多 5 个流水线执行策略 的限制可以在不同级别进行调整:

调整实例的限制

{{< details >}}

  • Offering: 私有化部署

{{< /details >}}

在极狐GitLab 私有化部署实例上,管理员可以调整整个实例的限制,最多为 20 个流水线执行策略:

  1. 转到 管理员区域 > 设置 > 安全和合规
  2. 展开 安全策略 部分。
  3. 每个安全策略配置允许的最大流水线执行策略数量 设置新值。
  4. 选择 保存更改

调整顶级群组的限制

极狐GitLab 实例管理员可以修改顶级群组的限制。这些群组限制可以超出已配置或默认的实例限制。

{{< alert type=”note” >}}

增加这些限制可能会影响系统性能,尤其是对于复杂策略或同时应用多个策略时。

{{< /alert >}}

要调整顶级群组的限制:

  1. 转到 管理员区域 > 概览 > 群组
  2. 在要修改的顶级群组的行中,选择 编辑
  3. 每个安全策略配置允许的最大流水线执行策略数量 设置新值。
  4. 选择 保存更改

当为单个群组设置的限制为零时,系统将退回到使用实例范围内的默认值。这确保了限制为零的群组仍然可以根据实例默认配置创建流水线执行策略。

管理对 CI/CD 配置的访问

当您在项目上实施流水线执行策略时,触发流水线的用户必须至少具有对包含策略 CI/CD 配置的项目的读取访问权限。您可以手动或自动授予项目访问权限。

手动授予访问权限

要允许用户或群组运行强制执行流水线执行策略的流水线,您可以邀请他们加入包含策略 CI/CD 配置的项目。

自动授予访问权限

您可以自动授予对策略 CI/CD 配置的访问权限,以便在具有强制执行流水线执行策略的项目中运行流水线的所有用户。

前提条件:

  • 确保流水线执行策略 CI/CD 配置存储在安全策略项目中。
  • 在安全策略项目的一般设置中启用 流水线执行策略 设置。

如果您还没有安全策略项目并且想要创建第一个流水线执行策略,创建一个空项目并将其链接为安全策略项目。 要链接项目:

  1. 在要实施策略的群组或项目中,选择 安全 > 策略 > 编辑策略项目
  2. 选择安全策略项目。

项目成为安全策略项目,并且设置变得可用。

{{< alert type=”note” >}}

要使用 $CI_JOB_TOKEN 创建下游流水线,您需要确保项目和群组被授权请求安全策略项目。 在安全策略项目中,转到 设置 > CI/CD > 作业令牌权限 并将授权的群组和项目添加到允许名单中。或者,您可以授权所有群组和项目。 如果您没有看到 CI/CD 设置,请转到 设置 > 通用 > 可见性、项目功能、权限 并启用 CI/CD

{{< /alert >}}

配置

  1. 在策略项目中,选择 设置 > 通用 > 可见性、项目功能、权限
  2. 启用设置 流水线执行策略:授予对项目链接到此安全策略项目作为安全策略来源的 CI/CD 配置的访问权限。
  3. 在策略项目中为策略 CI/CD 配置创建一个文件。

    # policy-ci.yml
    
    policy-job:
      script: ...
    
  4. 在要实施策略的群组或项目中,创建一个流水线执行策略并指定安全策略项目的 CI/CD 配置文件。

    pipeline_execution_policy:
    - name: My pipeline execution policy
      description: Enforces CI/CD jobs
      enabled: true
      pipeline_config_strategy: inject_policy
      content:
        include:
        - project: my-group/my-security-policy-project
          file: policy-ci.yml
    

流水线配置策略

流水线配置策略定义了与项目流水线合并策略配置的方法。流水线执行策略在隔离的流水线中执行定义在 .gitlab-ci.yml 文件中的作业,这些作业合并到目标项目的流水线中。

inject_policy

{{< history >}}

  • 引入于极狐GitLab 17.9。

{{< /history >}}

此策略将自定义 CI/CD 配置添加到现有项目流水线中,而不会完全替换项目的原始 CI/CD 配置。它适合在当前流水线上添加或扩展额外步骤,例如添加新的安全扫描、合规检查或自定义脚本。

与已弃用的 inject_ci 策略不同,inject_policy 允许您将自定义策略阶段注入到流水线中,使您能够更细粒度地控制在 CI/CD 工作流中应用策略规则的位置。

如果启用了多个策略,此策略会注入每个策略的所有作业。

当您使用此策略时,项目 CI/CD 配置无法覆盖策略流水线中定义的任何行为,因为每个流水线都有一个隔离的 YAML 配置。

对于没有 .gitlab-ci.yml 文件的项目,此策略会隐式创建 .gitlab-ci.yml 文件。执行的流水线仅包含流水线执行策略中定义的作业。

{{< alert type=”note” >}}

当流水线执行策略使用工作流规则来阻止策略作业运行时,只有项目的 CI/CD 作业会运行。如果项目使用工作流规则来阻止项目 CI/CD 作业运行,则只有流水线执行策略作业会运行。

{{< /alert >}}

阶段注入

策略流水线的阶段遵循通常的 CI/CD 配置。 通过在自定义阶段之前和之后提供阶段定义来确定自定义策略阶段注入到项目流水线中的顺序。

项目和策略流水线阶段表示为一个有向无环图(DAG),其中节点是阶段,边表示依赖关系。当您合并流水线时,单个 DAG 被合并为一个更大的 DAG。之后进行拓扑排序,确定所有流水线的阶段的执行顺序。此排序确保所有依赖关系在最终顺序中得到尊重。 如果存在冲突的依赖关系,则流水线无法运行。要修复依赖关系,请确保项目和策略使用的阶段对齐。

如果策略流水线配置中未显式定义阶段,则流水线使用默认阶段 stages: [build, test, deploy]。如果包含这些阶段,但以不同顺序列出,流水线将失败并显示 Cyclic dependencies detected when enforcing policies 错误。

以下示例展示了此行为。所有示例均假设以下项目 CI/CD 配置:

# .gitlab-ci.yml
stages: [build, test, deploy]

project-build-job:
  stage: build
  script: ...

project-test-job:
  stage: test
  script: ...

project-deploy-job:
  stage: deploy
  script: ...
示例 1
# policy-ci.yml
stages: [test, policy-stage, deploy]

policy-job:
  stage: policy-stage
  script: ...

在此示例中,policy-stage 阶段:

  • 必须在 test 阶段之后注入(如果存在)。
  • 必须在 deploy 阶段之前注入(如果存在)。

结果:流水线包含以下阶段:[build, test, policy-stage, deploy]

特殊情况:

  • 如果 .gitlab-ci.yml 将阶段指定为 [build, deploy, test],则流水线会因 Cyclic dependencies detected when enforcing policies 错误而失败,因为约束无法满足。要修复失败,请调整项目配置以使阶段与策略对齐。
  • 如果 .gitlab-ci.yml 指定阶段为 [build],结果流水线具有以下阶段:[build, policy-stage]
示例 2
# policy-ci.yml
stages: [policy-stage, deploy]

policy-job:
  stage: policy-stage
  script: ...

在此示例中,policy-stage 阶段:

  • 必须在 deploy 阶段之前注入(如果存在)。

结果:流水线包含以下阶段:[build, test, policy-stage, deploy]

特殊情况:

  • 如果 .gitlab-ci.yml 将阶段指定为 [build, deploy, test],则结果流水线阶段为:[build, policy-stage, deploy, test]
  • 如果项目流水线中没有 deploy 阶段,则 policy-stage 阶段被注入到流水线的末尾,紧接在 .pipeline-policy-post 之前。
示例 3
# policy-ci.yml
stages: [test, policy-stage]

policy-job:
  stage: policy-stage
  script: ...

在此示例中,policy-stage 阶段:

  • 必须在 test 阶段之后注入(如果存在)。

结果:流水线包含以下阶段:[build, test, deploy, policy-stage]

特殊情况:

  • 如果项目流水线中没有 test 阶段,则 policy-stage 阶段被注入到流水线的末尾,紧接在 .pipeline-policy-post 之前。
示例 4
# policy-ci.yml
stages: [policy-stage]

policy-job:
  stage: policy-stage
  script: ...

在此示例中,policy-stage 阶段没有约束。

结果:流水线包含以下阶段:[build, test, deploy, policy-stage]

示例 5
# policy-ci.yml
stages: [check, lint, test, policy-stage, deploy, verify, publish]

policy-job:
  stage: policy-stage
  script: ...

在此示例中,policy-stage 阶段:

  • 必须在阶段 checklinttest 之后注入(如果存在)。
  • 必须在阶段 deployverifypublish 之前注入(如果存在)。

结果:流水线包含以下阶段:[build, test, policy-stage, deploy]

特殊情况:

  • 如果 .gitlab-ci.yml 指定阶段为 [check, publish],结果流水线具有以下阶段:[check, policy-stage, publish]

inject_ci(已弃用)

{{< alert type=”warning” >}}

此功能在极狐GitLab 17.9 中已弃用。请改用 inject_policy,因为它支持自定义策略阶段的实施。

{{< /alert >}}

此策略将自定义 CI/CD 配置添加到现有项目流水线中,而不会完全替换项目的原始 CI/CD 配置。它适合在当前流水线上添加或扩展额外步骤,例如添加新的安全扫描、合规检查或自定义脚本。

启用了多个策略时,所有作业都以加法方式注入。

当您使用此策略时,项目 CI/CD 配置无法覆盖策略流水线中定义的任何行为,因为每个流水线都有一个隔离的 YAML 配置。

对于没有 .gitlab-ci.yml 文件的项目,此策略会隐式创建 .gitlab-ci.yml 文件。这允许仅包含在流水线执行策略中定义的作业的流水线执行。

{{< alert type=”note” >}}

当流水线执行策略使用工作流规则来阻止策略作业运行时,只有项目的 CI/CD 作业会运行。如果项目使用工作流规则来阻止项目 CI/CD 作业运行,则只有流水线执行策略作业会运行。

{{< /alert >}}

override_project_ci

{{< history >}}

  • 更新的工作流规则处理引入于极狐GitLab 17.8,使用名为 policies_always_override_project_ci 的功能标志。默认启用。
  • 更新的工作流规则处理在极狐GitLab 17.10 中 GA。功能标志 policies_always_override_project_ci 已删除。

{{< /history >}}

此策略用流水线执行策略定义的新配置替换项目的现有 CI/CD 配置。此策略非常适合需要标准化或替换整个流水线时,例如在高度监管的行业中实施组织范围内的 CI/CD 标准或合规要求。要覆盖流水线配置,请定义 CI/CD 作业并且不要使用 include:project

该策略优先于使用 inject_ciinject_policy 策略的其他策略。如果应用了 override_project_ci 策略,则项目 CI/CD 配置被忽略。然而,不会覆盖其他安全策略配置。

或者,您可以将项目的 CI/CD 配置与项目的 .gitlab-ci.yml 合并,而不是覆盖它。要合并配置,请使用 include:project。此策略允许用户在流水线执行策略配置中包含项目 CI/CD 配置,使用户可以自定义策略作业。例如,他们可以将策略和项目 CI/CD 配置合并为一个 YAML 文件,以覆盖 before_script 配置或定义必需的变量,例如 CS_IMAGE,以定义容器扫描的所需路径。这里有一个 简短演示 展示此行为。 下图说明了在结果流水线中选择在项目和策略级别定义的变量:

%%{init: { "fontFamily": "GitLab Sans" }}%% graph TB classDef yaml text-align:left ActualPolicyYAML["<pre> variables: MY_VAR: 'policy' policy-job: stage: test </pre>"] class ActualPolicyYAML yaml ActualProjectYAML["<pre> variables: MY_VAR: 'project' project-job: stage: test </pre>"] class ActualProjectYAML yaml PolicyVariablesYAML["<pre> variables: MY_VAR: 'policy' </pre>"] class PolicyVariablesYAML yaml ProjectVariablesYAML["<pre> variables: MY_VAR: 'project' </pre>"] class ProjectVariablesYAML yaml ResultingPolicyVariablesYAML["<pre> variables: MY_VAR: 'policy' </pre>"] class ResultingPolicyVariablesYAML yaml ResultingProjectVariablesYAML["<pre> variables: MY_VAR: 'project' </pre>"] class ResultingProjectVariablesYAML yaml PolicyCiYAML(Policy CI YAML) --> ActualPolicyYAML ProjectCiYAML(<code>.gitlab-ci.yml</code>) --> ActualProjectYAML subgraph "Policy Pipeline" subgraph "Test stage" subgraph "<code>policy-job</code>" PolicyVariablesYAML end end end subgraph "Project Pipeline" subgraph "Test stage" subgraph "<code>project-job</code>" ProjectVariablesYAML end end end ActualPolicyYAML -- "Used as source" --> PolicyVariablesYAML ActualProjectYAML -- "Used as source" --> ProjectVariablesYAML subgraph "Resulting Pipeline" subgraph "Test stage" subgraph "<code>policy-job</code> " ResultingPolicyVariablesYAML end subgraph "<code>project-job</code> " ResultingProjectVariablesYAML end end end PolicyVariablesYAML -- "Inject <code>policy-job</code> if Test Stage exists" --> ResultingPolicyVariablesYAML ProjectVariablesYAML -- "Basis of the resulting pipeline" --> ResultingProjectVariablesYAML

{{< alert type=”note” >}}

流水线执行策略中的工作流规则覆盖项目的原始 CI/CD 配置。 通过在策略中定义工作流规则,您可以设置在所有链接项目中强制执行的规则,例如阻止使用分支流水线。

{{< /alert >}}

在流水线执行策略配置中包含项目的 CI/CD 配置

当您使用 override_project_ci 策略时,可以将项目配置包含到流水线执行策略配置中:

include:
  - project: $CI_PROJECT_PATH
    ref: $CI_COMMIT_SHA
    file: $CI_CONFIG_PATH
    rules:
      - exists:
          paths:
            - '$CI_CONFIG_PATH'
          project: '$CI_PROJECT_PATH'
          ref: '$CI_COMMIT_SHA'

compliance_job:
 ...

CI/CD 变量

{{< alert type=”warning” >}}

不要在变量中存储敏感信息或凭证,因为它们作为明文策略配置的一部分存储在 Git 仓库中。

{{< /alert >}}

流水线执行作业在隔离中执行。在另一个策略或项目的 .gitlab-ci.yml 文件中定义的变量在流水线执行策略中不可用,无法从外部覆盖。

可以使用群组或项目设置与流水线执行策略共享变量,这遵循标准的 CI/CD 变量优先级 规则。然而,当使用流水线执行策略时,优先级规则更复杂,因为它们可能会根据流水线执行策略的策略而有所不同:

  • inject_policy 策略:如果变量在流水线执行策略中定义,作业始终使用此值。如果变量未在流水线执行策略中定义,作业应用来自群组或项目设置的值。
  • inject_ci 策略:如果变量在流水线执行策略中定义,作业始终使用此值。如果变量未在流水线执行策略中定义,作业应用来自群组或项目设置的值。
  • override_project_ci 策略:结果流水线中的所有作业都被视为策略作业。在策略中定义的变量(包括包含的文件中的变量)优先于项目和群组变量。这意味着来自包含项目的 CI/CD 配置文件中的作业的变量优先于项目和群组设置中定义的变量。

有关流水线执行策略中的变量的更多详细信息,请参阅 流水线执行策略中的变量优先级

您可以在 UI 中定义项目或群组变量

流水线执行策略中的变量优先级

当您使用流水线执行策略,尤其是使用 override_project_ci 策略时,在多个地方定义的变量值的优先级可能与标准极狐GitLab CI/CD 流水线不同。这些是一些需要理解的重要点:

  • 使用 override_project_ci 时,结果流水线中的所有作业都被视为策略作业,包括来自包含项目的 CI/CD 配置的作业。
  • 在策略流水线中定义的变量(对于整个实例或对于作业)优先于项目或群组设置中定义的变量。
  • 此行为适用于所有作业,包括从项目的 CI/CD 配置文件(.gitlab-ci.yml)中包含的作业。

示例

如果项目的 CI/CD 配置中的变量与包含的 .gitlab-ci.yml 文件中定义的作业变量具有相同名称,则在使用 override_project_ci 时,作业变量优先。

在项目的 CI/CD 设置中定义了 MY_VAR 变量:

  • 键:MY_VAR
  • 值:项目配置变量值

在包含项目的 .gitlab-ci.yml 中定义了相同变量:

project-job:
  variables:
    MY_VAR: "项目作业变量值"
  script:
    - echo $MY_VAR  # 这将输出 "项目作业变量值"

在这种情况下,作业变量值 项目作业变量值 优先。

使用 [skip ci] 的行为

默认情况下,为了防止常规流水线触发,用户可以在受保护分支上提交带有 [skip ci] 的提交信息。然而,策略定义的作业始终会触发,因为策略忽略了 [skip ci] 指令。这防止开发人员跳过策略中定义的作业的执行,确保始终执行关键的安全和合规检查。

有关 [skip ci] 行为的更灵活控制,请参阅 skip_ci 类型 部分。

与扫描执行策略的交互

使用 override_project_ci 策略的流水线执行策略可能会影响 扫描执行策略 的行为。

如果所有这些条件都为真,则扫描执行策略可能会被覆盖:

  • 项目配置了扫描执行策略
  • 项目配置了流水线执行策略
  • 流水线执行策略使用 override_project_ci 策略。

扫描执行策略被忽略,因为 override_project_ci 策略删除了为项目定义的所有 CI/CD 配置,包括策略。

为了确保同时应用流水线执行策略和扫描执行策略:

  • 考虑使用不同的流水线执行策略,例如 inject_policy
  • 如果必须使用 override_project_ci,请在流水线执行策略中包含所需的扫描器模板,以保持所需的安全扫描。

示例

这些示例展示了您可以使用流水线执行策略实现的目标。

流水线执行策略

您可以在存储在 安全策略项目 中的 .gitlab/security-policies/policy.yml 文件中使用以下示例:

---
pipeline_execution_policy:
- name: My pipeline execution policy
  description: Enforces CI/CD jobs
  enabled: true
  pipeline_config_strategy: override_project_ci
  content:
    include:
    - project: my-group/pipeline-execution-ci-project
      file: policy-ci.yml
      ref: main # optional
  policy_scope:
    projects:
      including:
      - id: 361

基于项目变量自定义强制执行的作业

您可以基于项目变量的存在来自定义强制执行的作业。在此示例中,CS_IMAGE 的值在策略中定义为 alpine:latest。然而,如果项目也定义了 PROJECT_CS_IMAGE 的值,则使用该值。CI/CD 变量必须是预定义的项目变量,而不是在项目的 .gitlab-ci.yml 文件中定义。

variables:
  CS_ANALYZER_IMAGE: "$CI_TEMPLATE_REGISTRY_HOST/security-products/container-scanning:7"
  CS_IMAGE: alpine:latest

policy::container-security:
  stage: .pipeline-policy-pre
  rules:
    - if: $PROJECT_CS_IMAGE
      variables:
        CS_IMAGE: $PROJECT_CS_IMAGE
    - when: always
  script:
    - echo "CS_ANALYZER_IMAGE:$CS_ANALYZER_IMAGE"
    - echo "CS_IMAGE:$CS_IMAGE"

使用项目配置中的 before_script 自定义安全扫描器的行为

要在项目的 .gitlab-ci.yml 中自定义策略强制执行的安全作业的行为,可以覆盖 before_script。 为此,请在策略中使用 override_project_ci 策略并包含项目的 CI/CD 配置。流水线执行策略配置示例:

# policy.yml
type: pipeline_execution_policy
name: Secret detection
description: >-
  This policy enforces secret detection and allows projects to override the
  behavior of the scanner.
enabled: true
pipeline_config_strategy: override_project_ci
content:
  include:
    - project: gitlab-org/pipeline-execution-policies/compliance-project
      file: secret-detection.yml
# secret-detection.yml
include:
  - project: $CI_PROJECT_PATH
    ref: $CI_COMMIT_SHA
    file: $CI_CONFIG_PATH
  - template: Jobs/Secret-Detection.gitlab-ci.yml

在项目的 .gitlab-ci.yml 中,可以为扫描器定义 before_script

include:
  - template: Jobs/Secret-Detection.gitlab-ci.yml

secret_detection:
  before_script:
    - echo "Before secret detection"

通过使用 override_project_ci 并包含项目的配置,允许 YAML 配置合并。

在流水线执行策略中使用群组或项目变量

您可以在流水线执行策略中使用群组或项目变量。

使用项目变量 PROJECT_VAR="I'm a project",以下流水线执行策略作业结果为:I'm a project

pipeline execution policy job:
    stage: .pipeline-policy-pre
    script:
    - echo "$PROJECT_VAR"

使用流水线执行策略实施变量的值

在流水线执行策略中定义的变量值覆盖具有相同名称的群组或策略变量的值。 在此示例中,项目变量 PROJECT_VAR 的值被覆盖,作业结果为:I'm a pipeline execution policy

variables:
  PROJECT_VAR: "I'm a pipeline execution policy"

pipeline execution policy job:
    stage: .pipeline-policy-pre
    script:
    - echo "$PROJECT_VAR"

使用安全策略范围的示例 policy.yml

在此示例中,安全策略的 policy_scope

  • 包括应用了 ID 为 9 的合规框架的任何项目。
  • 排除 ID 为 456 的项目。
pipeline_execution_policy:
- name: Pipeline execution policy
  description: ''
  enabled: true
  pipeline_config_strategy: inject_policy
  content:
    include:
    - project: my-group/pipeline-execution-ci-project
      file: policy-ci.yml
  policy_scope:
    compliance_frameworks:
    - id: 9
    projects:
      excluding:
      - id: 456

在流水线执行策略中配置 ci_skip

在以下示例中,流水线执行策略被强制执行,并且除了 ID 为 75 的用户外,skip CI 被禁止。

pipeline_execution_policy:
  - name: My pipeline execution policy with ci.skip exceptions
    description: 'Enforces CI/CD jobs'
    enabled: true
    pipeline_config_strategy: inject_policy
    content:
      include:
        - project: group-a/project1
          file: README.md
    skip_ci:
      allowed: false
      allowlist:
        users:
          - id: 75