Help us learn about your current experience with the documentation. Take the survey.

CI/CD 组件

  • 层级(Tier): 免费版、高级版、旗舰版
  • 提供方式(Offering): GitLab.com、GitLab 自托管、GitLab 专用

CI/CD 组件是一个可复用的单一流水线配置单元。使用组件可以创建更大流水线的一小部分,甚至组合成一个完整的流水线配置。

组件可以通过输入参数进行配置,以实现更动态的行为。

CI/CD 组件与其他通过 include 关键字添加的配置类型类似,但具有以下优势:

  • 组件可以在CI/CD 目录中列出。
  • 组件可以按特定版本发布和使用。
  • 多个组件可以在同一个项目中定义并一起版本化。

除了创建自己的组件外,你还可以在CI/CD 目录中搜索已发布的、具备所需功能的组件。

有关介绍和实际操作示例,请参见 利用可复用的 CI/CD 组件实现高效的 DevSecOps 工作流

常见问题和额外支持,请参阅博客文章 FAQ: GitLab CI/CD 目录

组件项目

组件项目是一个 GitLab 项目,其仓库中包含一个或多个组件。项目中的所有组件会一起版本化,每个项目最多有 30 个组件。

如果某个组件需要与其他组件不同的版本控制,则应将其移动到一个专用的组件项目中。

创建组件项目

要创建组件项目,你必须:

  1. 创建新项目,并包含一个 README.md 文件:

    • 确保描述能清晰介绍该组件。
    • 可选。项目创建后,你可以添加项目头像

    发布到CI/CD 目录的组件会在显示组件项目的摘要时使用描述和头像。

  2. 为每个组件添加一个 YAML 配置文件,遵循所需的目录结构。 例如:

    spec:
      inputs:
        stage:
          default: test
    ---
    component-job:
      script: echo job 1
      stage: $[[ inputs.stage ]]

你可以立即使用该组件,但可能需要考虑将该组件发布到CI/CD 目录

目录结构

仓库必须包含:

  • 一个 README.md Markdown 文件,用于记录仓库中所有组件的详细信息。
  • 一个顶级的 templates/ 目录,其中包含所有组件配置。在该目录下:
    • 对于简单组件,对每个组件使用单个以 .yml 结尾的文件,例如 templates/secret-detection.yml
    • 对于复杂组件,为每个组件创建一个包含 template.yml 的子目录,例如 templates/secret-detection/template.yml。只有 template.yml 文件会被使用该组件的其他项目使用。这些目录中的其他文件不会随组件一起发布,但可用于测试或构建容器镜像等用途。

可选地,每个组件也可以有自己的 README.md 文件,提供更详细的信息,并可从顶级的 README.md 文件中链接。这有助于更好地概述你的组件项目和如何使用它。

你还应做到:

例如:

  • 如果项目包含单个组件,目录结构应类似:

    ├── templates/
    │   └── my-component.yml
    ├── LICENSE.md
    ├── README.md
    └── .gitlab-ci.yml
  • 如果项目包含多个组件,则目录结构应类似:

    ├── templates/
    │   ├── my-simple-component.yml
    │   └── my-complex-component/
    │       ├── template.yml
    │       ├── Dockerfile
    │       └── test.sh
    ├── LICENSE.md
    ├── README.md
    └── .gitlab-ci.yml

    在此示例中:

    • my-simple-component 组件的配置在一个单独文件中定义。
    • my-complex-component 组件的配置包含在一个目录的多个文件中。

使用组件

先决条件:

如果你是包含当前组或项目的父组的成员:

  • 你必须拥有由项目父组可见性级别设定的最低角色。例如,若父项目设置为 Private,你必须至少具备 Reporter 角色。

要将组件添加到项目的 CI/CD 配置中,请使用 include: component 关键字。组件引用格式为 <完全限定域名>/<项目路径>/<组件名>@<特定版本>,例如:

include:
  - component: $CI_SERVER_FQDN/my-org/security-components/secret-detection@1.0.0
    inputs:
      stage: build

在此示例中:

  • $CI_SERVER_FQDN 是对应 GitLab 主机完全限定域名(FQDN)的 预定义变量。你只能引用与你项目在同一 GitLab 实例中的组件。
  • my-org/security-components 是包含组件的项目完整路径。
  • secret-detection 是组件名称,定义为单个文件 templates/secret-detection.yml 或包含 template.yml 的目录 templates/secret-detection/
  • 1.0.0 是组件的 版本

管道配置和组件配置并非独立处理。当管道启动时,任何被包含的组件配置会 合并 到管道配置中。如果你的管道和组件都包含同名的配置项,它们可能会产生意外交互。

例如,两个同名的作业会合并为一个作业。同样,组件使用 extends 引用与你管道中作业同名的配置时,可能会扩展错误的配置。确保你的管道和组件没有共享同名的配置项,除非你有意 覆盖 组件的配置。

要在 GitLab 自托管实例上使用 GitLab.com 组件,你必须 镜像该组件项目

如果组件需要使用令牌、密码或其他敏感数据才能运行,务必审计组件的源代码,验证数据仅用于执行你预期且授权的操作。你还应使用具有完成操作所需最小权限、访问范围或作用域的令牌和密钥。

组件版本

按优先级从高到低排列,组件版本可以是:

  • 提交SHA,例如 e3262fdd0914fa823210cdb79a8c421e2cef79d8
  • 标签,例如:1.0.0。如果存在同名的标签和提交SHA,则提交SHA的优先级高于标签。发布到CI/CD目录的组件应使用语义化版本进行标记。
  • 分支名称,例如 main。如果存在同名分支和标签,则标签的优先级高于分支。
  • ~latest,它始终指向CI/CD目录中发布的最新语义化版本。仅当你希望始终使用绝对最新的版本(可能包含破坏性变更)时才使用~latest~latest不包括预发布版,例如 1.0.1-rc,这些版本不被视为生产就绪。

你可以使用组件支持的任何版本,但建议使用已发布到CI/CD目录的版本。通过提交SHA或分支名称引用的版本可能未在CI/CD目录中发布,但可用于测试。

语义化版本范围

引用CI/CD目录中的组件时,你可以使用特殊格式指定范围内最新的语义化版本

这种方法对组件的使用者和作者都有显著优势:

  • 对于用户来说,使用版本范围是一种绝佳的方式,可以自动接收次要或补丁更新,而不会因重大版本变更带来破坏性风险。这确保了你的流水线能及时获取最新的错误修复和安全补丁,同时保持稳定性。
  • 对于组件作者而言,使用版本范围允许发布重大版本,而无需担心立即破坏现有流水线。指定了版本范围的用户会继续使用最新的兼容次要或补丁版本,让他们有足够时间按自己的节奏更新流水线。

若要指定最新发布版本:

  • 次要版本:在引用中使用主版本号和次要版本号,但不包括补丁版本号。例如,使用 1.1 来使用以 1.1 开头的最新版本,包括 1.1.01.1.9,但不包括 1.2.0
  • 主要版本:在引用中仅使用主版本号。例如,使用 1 来使用以 1. 开头的最新版本,如 1.0.01.9.9,但不包括 2.0.0
  • 所有版本:使用 ~latest 来使用最新发布的版本。

例如,一个组件按以下顺序发布:

  1. 1.0.0
  2. 1.1.0
  3. 2.0.0
  4. 1.1.1
  5. 1.2.0
  6. 2.1.0
  7. 2.0.1

在此示例中,引用该组件时:

  • 1 会使用 1.2.0 版本。
  • 1.1 会使用 1.1.1 版本。
  • ~latest 会使用 2.1.0 版本。

引用版本范围时永远不会获取预发布版。若要获取预发布版,需指定完整版本,例如 1.0.1-rc

编写组件

本节介绍创建高质量组件项目的一些最佳实践。

管理依赖项

虽然组件可以依次使用其他组件,但请务必仔细选择依赖项。管理依赖项时,你应该:

  • 将依赖项数量保持在最低限度。少量重复通常比依赖更好。
  • 尽可能在本地依赖。例如,使用 include:local 是确保多个文件使用相同Git SHA的好方法。
  • 当依赖其他项目的组件时,将其版本固定为目录中的发布版本,而不是使用像 ~latest 或Git引用这样的动态目标版本。使用发布版本或Git SHA可保证你始终获取相同的修订版,并且你的组件使用者获得一致的行为。
  • 通过将依赖项固定到较新版本定期更新它们。然后发布带有更新依赖项的新组件版本。
  • 评估依赖项的权限,并使用需要最少权限的依赖项。例如,如果你需要构建镜像,考虑使用 Buildah 而不是Docker,这样就不需要具有特权Docker守护进程的Runner。

编写清晰的 README.md

每个组件项目都应有清晰且全面的文档。要编写一个好的 README.md 文件:

  • 文档应从项目内组件所提供能力的摘要开始。
  • 如果项目包含多个组件,请使用表格目录 帮助用户快速跳转到特定组件的详细信息。
  • 添加一个 ## 组件 部分,并为项目中的每个组件添加子章节,例如 ### 组件 A
  • 在每个组件章节中:
    • 添加该组件功能的描述。
    • 添加至少一个展示如何使用的 YAML 示例。
    • 如果组件使用输入(inputs),请添加一个表格,显示所有输入的名称、描述、类型和默认值。
    • 如果组件使用任何变量或密钥(secrets),也应记录它们。
  • 如果欢迎贡献,建议添加一个 ## 贡献 部分。

如果一个组件需要更多说明,请在组件目录下的 Markdown 文件中添加额外文档,并从主 README.md 文件中链接到它。例如:

README.md    # 包含指向具体 docs.md 的链接
templates/
├── component-1/
│   ├── template.yml
│   └── docs.md
└── component-2/
    ├── template.yml
    └── docs.md

有关组件 README.md 的示例,请参阅 使用 GitLab CI/CD 部署到 AWS 组件的 README.md

测试组件

强烈建议将 CI/CD 组件作为开发工作流程的一部分进行测试,这有助于确保行为一致。

通过在根目录下创建 .gitlab-ci.yml 来测试 CI/CD 管道中的更改(与其他项目一样)。确保测试组件的行为及其潜在副作用。如有需要,可以使用 GitLab API

例如:

include:
  # 从当前项目的当前 SHA 引入位于当前项目内的组件
  - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/my-component@$CI_COMMIT_SHA
    inputs:
      stage: build

stages: [build, test, release]

# 检查是否添加了 `my-component 的组件任务`。

# 此示例作业也可测试引入的组件是否能按预期工作。

# 您可以检查组件生成的数据、使用 GitLab API 端点或第三方工具。
ensure-job-added:
  stage: test
  image: badouralix/curl-jq
  # 将 "my-component 的组件任务" 替换为您组件中的任务名称。
  script:
    - |
      route="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/jobs"
      count=`curl --silent "$route" | jq 'map(select(.name | contains("component job of my-component"))) | length'`
      if [ "$count" != "1" ]; then
        exit 1; else
        echo "组件任务已存在"
      fi

# 如果流水线是为带有语义版本的标签创建的,并且之前所有任务都成功,

# 则创建发布。
create-release:
  stage: release
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  script: echo "正在创建发布 $CI_COMMIT_TAG"
  rules:
    - if: $CI_COMMIT_TAG
  release:
    tag_name: $CI_COMMIT_TAG
    description: "组件仓库 $CI_PROJECT_PATH 的版本 $CI_COMMIT_TAG"

提交并推送更改后,流水线会测试组件,若之前的任务通过,则创建发布。

如果项目是私有的,则需要身份验证。

对样本文件测试组件

在某些情况下,组件需要源文件来交互。例如,构建 Go 源码的组件很可能需要一些 Go 样本来测试;同样,构建 Docker 镜像的组件很可能需要一些样本 Dockerfile 来测试。

您可以将此类样本文件直接包含在组件项目中,以便在组件测试期间使用。

您可以了解更多信息:测试组件的示例

避免硬编码实例或项目特定的值

使用另一个组件时,请使用 $CI_SERVER_FQDN 而不是您的实例的完全限定域名(如 gitlab.com)。

在组件中访问 GitLab API 时,请使用 $CI_API_V4_URL 而不是您实例的完整 URL 和路径(如 https://gitlab.com/api/v4)。

这些预定义变量 确保您的组件在其他实例上也能正常工作,例如在使用GitLab.com 组件于 GitLab 自托管实例 时。

不要假设API资源总是公开的

确保组件及其测试管道也在GitLab Self-Managed上工作
虽然GitLab.com上的公共项目的某些API资源可以通过未认证请求访问,但在GitLab Self-Managed实例中,组件项目可能被镜像为私有或内部项目。
重要的是,访问令牌可以可选地通过输入或变量提供,以对GitLab Self-Managed实例上的请求进行身份验证。

避免使用全局关键字

避免在组件中使用全局关键字
在组件中使用这些关键字会影响管道中的所有作业,包括直接在主.gitlab-ci.yml或在其他包含的组件中定义的作业。

作为替代方案:

  • 将配置直接添加到每个作业中,即使这会在组件配置中造成一些重复。
  • 在组件中使用extends关键字,但使用唯一名称,减少组件合并到配置时命名冲突的风险。

例如,避免使用default全局关键字:

# 不推荐
default:
  image: ruby:3.0

rspec-1:
  script: bundle exec rspec dir1/

rspec-2:
  script: bundle exec rspec dir2/

相反,您可以:

  • 将配置显式添加到每个作业中:

    rspec-1:
      image: ruby:3.0
      script: bundle exec rspec dir1/
    
    rspec-2:
      image: ruby:3.0
      script: bundle exec rspec dir2/
  • 使用extends复用配置:

    .rspec-image:
      image: ruby:3.0
    
    rspec-1:
      extends:
        - .rspec-image
      script: bundle exec rspec dir1/
    
    rspec-2:
      extends:
        - .rspec-image
      script: bundle exec rspec dir2/

用输入替换硬编码值

避免在CI/CD组件中使用硬编码值。硬编码值可能会迫使组件用户需要查看组件的内部细节并调整其管道以与组件配合使用。

一个常见的问题是stage关键字的硬编码值。如果组件作业的stage被硬编码,则使用该组件的所有管道必须要么定义完全相同的stage,要么覆盖配置。

首选方法是使用input关键字进行动态组件配置。组件用户可以指定他们需要的确切值。

例如,创建一个具有可由用户定义的stage配置的组件:

  • 在组件配置中:

    spec:
      inputs:
        stage:
          default: test
    ---
    unit-test:
      stage: $[[ inputs.stage ]]
      script: echo 单元测试
    
    integration-test:
      stage: $[[ inputs.stage ]]
      script: echo 集成测试
  • 在使用组件的项目中:

    stages: [verify, release]
    
    include:
      - component: $CI_SERVER_FQDN/myorg/ruby/test@1.0.0
        inputs:
          stage: verify

用输入定义作业名称

stage关键字的值类似,您应避免在CI/CD组件中对作业名称进行硬编码。当您的组件用户可以自定义作业名称时,他们可以防止与现有管道中的名称发生冲突。用户还可以通过使用不同的名称来多次包含组件,并使用不同的输入选项。

使用inputs允许您的组件用户定义特定的作业名称或作业名称的前缀。例如:

spec:
  inputs:
    job-prefix:
      description: "定义作业名称的前缀"
    job-name:
      description: "或者,定义作业的名称"
    job-stage:
      default: test
---

"$[[ inputs.job-prefix ]]-scan-website":
  stage: $[[ inputs.job-stage ]]
  script:
    - scan-website-1

"$[[ inputs.job-name ]]":
  stage: $[[ inputs.job-stage ]]
  script:
    - scan-website-2

用输入替换自定义CI/CD变量

在使用组件中的CI/CD变量时,评估是否应改用inputs关键字。当inputs是更好的解决方案时,避免要求用户定义自定义变量来配置组件。

输入在组件的spec部分显式定义,比变量有更好的验证。例如,如果必需的输入未传递给组件,GitLab会返回管道错误。相比之下,如果变量未定义,其值为空,且不会报错。

例如,使用inputs而非变量来配置扫描仪的输出格式:

  • 在组件配置中:

    spec:
      inputs:
        scanner-output:
          default: json
    ---
    my-scanner:
      script: my-scan --output $[[ inputs.scanner-output ]]
  • 在使用该组件的项目中:

    include:
      - component: $CI_SERVER_FQDN/path/to/project/my-scanner@1.0.0
        inputs:
          scanner-output: yaml

在其他情况下,CI/CD变量可能仍被优先考虑。例如:

CI/CD目录

  • 层级:免费版、高级版、旗舰版
  • 提供方式:GitLab.com、GitLab自托管、GitLab专用

CI/CD目录 是包含已发布CI/CD组件项目的列表,可用于扩展你的CI/CD工作流。

任何人都可以创建组件项目并将其添加到CI/CD目录,或贡献现有项目以改进可用组件。

点击演示请参见CI/CD目录Beta产品之旅

查看CI/CD目录

若要访问CI/CD目录并查看可用的已发布组件:

  1. 在左侧边栏选择搜索或前往
  2. 选择探索
  3. 选择CI/CD目录

或者,如果你已在项目的管道编辑器中,可以选择CI/CD目录

CI/CD目录中组件的可见性遵循组件源项目的可见性设置。源项目设置为以下类型的组件:

  • 私有的仅对源组件项目中至少分配了Guest角色的用户可见。要使用组件,你必须至少拥有Reporter角色。
  • 内部的仅对登录到GitLab实例的用户可见。
  • 公开的对任何有权访问GitLab实例的人可见。

发布组件项目

要在CI/CD目录中发布组件项目,你必须:

  1. 将项目设为目录项目。
  2. 发布新版本。

将组件项目设为目录项目

要让组件项目的已发布版本在CI/CD目录中可见,你必须将该设为目录项目。

前提条件:

  • 你必须是该项目的Owner角色。

要将项目设为目录项目:

  1. 在左侧边栏选择搜索或前往并找到你的项目。
  2. 选择设置 > 常规
  3. 展开可见性、项目功能、权限
  4. 打开CI/CD目录项目开关。

只有在你发布新版本后,该项目才会在目录中变得可查找。

若要通过自动化启用此设置,你可以使用mutationcatalogresourcescreate GraphQL端点。问题463043提议也在REST API中暴露此功能。

发布新版本

CI/CD 组件可以使用而不必在 CI/CD 目录中列出。 但将组件版本发布到目录中,可让其他用户发现它。

先决条件:

  • 你必须至少拥有该项目的维护者角色。
  • 项目必须:
    • 设为目录项目
    • 定义了项目描述
    • 在所发布标签对应的提交 SHA 的根目录下有 README.md 文件。
    • 对于所发布标签对应的提交 SHA,在 templates/ 目录中有至少一个CI/CD 组件
  • 你必须在 CI/CD 作业中使用release 关键字创建发布,而非使用Releases API

要向目录发布组件新版本:

  1. 向项目的 .gitlab-ci.yml 文件中添加一个作业,该作业使用 release 关键字在创建标签时生成新发布。 你应配置标签流水线以测试组件后再执行发布作业。示例如下:

    create-release:
      stage: release
      image: registry.gitlab.com/gitlab-org/release-cli:latest
      script: echo "Creating release $CI_COMMIT_TAG"
      rules:
        - if: $CI_COMMIT_TAG
      release:
        tag_name: $CI_COMMIT_TAG
        description: "Release $CI_COMMIT_TAG of components in $CI_PROJECT_PATH"
  2. 为发布创建一个新标签,这将触发包含负责创建发布的作业的标签流水线。 标签必须遵循语义化版本控制

发布作业成功完成后,发布即被创建,新版本也会发布到 CI/CD 目录中。

语义化版本控制

在对组件进行标记并发布新版本到目录时,你必须使用语义化版本控制。语义化版本控制是传达变更属于重大变更、次要变更、补丁或其他类型变更的标准。

例如,1.0.02.3.41.0.0-alpha 均为有效的语义化版本。

取消发布组件项目

要从目录中移除组件项目,需在项目设置中关闭CI/CD 目录资源切换开关。

此操作会销毁关于组件项目及其在目录中发布的版本的元数据。项目和其仓库仍存在,但在目录中不可见。

若要在目录中重新发布组件项目,需发布新版本

已验证的组件创建者

部分 CI/CD 组件带有图标标识,表明该组件由 GitLab 或实例管理员验证的用户创建和维护:

  • GitLab 维护的( tanuki-verified ):由 GitLab 创建和维护的 GitLab.com 组件。

  • GitLab 合作伙伴( partner-verified ):由独立创建和维护的 GitLab 验证合作伙伴提供的 GitLab.com 组件。

    GitLab 合作伙伴可联系 GitLab 合作伙伴联盟成员,将其 GitLab.com 命名空间标记为 GitLab 验证的。之后,位于该命名空间下的任何 CI/CD 组件都会被标识为 GitLab 合作伙伴组件。合作伙伴联盟成员代表已验证的合作伙伴创建一个内部请求问题(仅限 GitLab 团队成员)

    GitLab 合作伙伴创建的组件按原样提供,无任何形式保证。最终用户对 GitLab 合作伙伴创建的组件的使用风险自担,GitLab 不承担任何赔偿义务或任何类型责任,无论与最终用户对该组件的使用相关与否。最终用户对此类内容的任何使用及相关责任均由内容发布者与最终用户自行承担。

  • 已验证的创建者( check-sm ):由管理员验证的用户创建和维护的组件。

将组件设置为已验证创建者维护

  • 层级:免费版、高级版、旗舰版
  • 提供:GitLab 自托管、GitLab 专用版

GitLab 管理员可将 CI/CD 组件设为由已验证的创建者创建和维护:

  1. 以管理员账户打开实例中的 GraphiQL,例如在:https://gitlab.example.com/-/graphql-explorer

  2. 运行以下查询,将 root-level-group 替换为需验证组件的根命名空间:

    mutation {
      verifiedNamespaceCreate(input: { namespacePath: "root-level-group",
        verificationLevel: VERIFIED_CREATOR_SELF_MANAGED
        }) {
        errors
      }
    }

查询完成后,根命名空间下所有项目内的组件将被验证。 已验证创建者 徽章会显示在 CI/CD 目录中组件名称旁。

若要移除组件的徽章,可使用 UNVERIFIED 作为 verificationLevel 重新执行查询。

将 CI/CD 模板转换为组件

任何通过 include: 语法在项目中使用的现有 CI/CD 模板,均可转换为 CI/CD 组件:

  1. 决定是否将该组件与其他组件一同归入现有组件项目,或创建新组件项目
  2. 在组件项目中根据目录结构创建 YAML 文件。
  3. 将原始模板 YAML 文件的内容复制到新组件的 YAML 文件中。
  4. 重构新组件配置以:
  5. 利用组件仓库中的 .gitlab-ci.yml测试组件变更
  6. 打标签并发布组件

可通过遵循迁移 Go CI/CD 模板至 CI/CD 组件的实际示例了解更多细节。

在 GitLab 自托管中使用 GitLab.com 组件

  • 层级:高级版、旗舰版
  • 提供:GitLab 自托管、GitLab 专用版

全新安装的 GitLab 实例,其 CI/CD 目录初始状态下无已发布的 CI/CD 组件。 要填充实例目录,您可以:

在 GitLab 自托管实例中镜像 GitLab.com 组件的操作如下:

  1. 确保网络出站请求允许访问 gitlab.com
  2. 创建一个组来承载组件项目(推荐组名:components)。
  3. 在新组中创建组件项目的镜像
  4. 为组件项目镜像编写项目描述,因镜像仓库不会自动复制描述。
  5. 将自托管组件项目设为目录资源
  6. 在自托管组件项目中,通过手动运行流水线为标签(通常为最新标签)发布新版本

CI/CD 组件安全最佳实践

对于组件使用者

由于任何人都可以向目录发布组件,因此在使用前应仔细审查这些组件。

使用 GitLab CI/CD 组件需自行承担风险,GitLab 无法保证第三方组件的安全性。

使用第三方 CI/CD 组件时,请考虑以下安全最佳实践:

  • 审查并检查组件源代码:仔细检查代码,确保其中不含恶意内容。
  • 最小化凭证和令牌的访问权限
    • 审查组件的源代码,确保任何凭证或令牌仅用于执行您预期且授权的操作。
    • 使用最小权限范围的访问令牌。
    • 避免使用长期有效的访问令牌或凭证。
    • 审计 CI/CD 组件使用的凭证和令牌的使用情况。
  • 使用固定版本:将 CI/CD 组件固定到特定的提交 SHA(首选)或发行版标签,以确保管道中使用的组件完整性。仅当信任组件维护者时才使用发行版标签。避免使用 latest
  • 安全存储密钥:不要在 CI/CD 配置文件中存储密钥。如果可以使用外部密钥管理解决方案,则避免在项目设置中存储密钥和凭证。
  • 使用临时、隔离的运行器环境:尽可能在临时、隔离的环境中运行组件作业。注意自托管运行器的安全风险
  • 安全处理缓存和制品:除非绝对必要,否则不要将管道中其他作业的缓存或制品传递给 CI/CD 组件作业。
  • 限制 CI_JOB_TOKEN 访问:限制使用 CI/CD 组件的项目中的CI/CD 作业令牌(CI_JOB_TOKEN)的项目访问和权限
  • 审查 CI/CD 组件变更:在更改为使用组件的更新提交 SHA 或发行版标签之前,仔细审查所有 CI/CD 组件配置的变更。
  • 审计自定义容器镜像:仔细审查 CI/CD 组件使用的任何自定义容器镜像,确保其不含恶意内容。

对于组件维护者

为了维护安全可靠的 CI/CD 组件并确保交付给用户的管道配置的完整性,请遵循以下最佳实践:

  • 使用双因素认证(2FA):确保 CI/CD 组件项目的所有维护者和所有者均已启用双因素认证,或强制要求组内所有用户启用双因素认证
  • 使用受保护的分支
    • 为组件项目发布使用受保护的分支
    • 保护默认分支,并通过通配符规则保护所有发行版分支。
    • 要求所有人通过合并请求提交对受保护分支的更改。将受保护分支的允许推送和合并选项设置为 No one
    • 阻止对受保护分支的强制推送。
  • 对所有提交进行签名:对组件项目的所有提交进行签名
  • 不鼓励使用 latest:避免在 README.md 中包含使用 @latest 的示例。
  • 限制依赖来自其他作业的缓存和制品:仅当绝对必要时,才在 CI/CD 组件中使用来自其他作业的缓存和制品。
  • 更新 CI/CD 组件依赖项:定期检查并应用依赖项的更新。
  • 仔细审查变更
    • 在合并到默认或发行版分支之前,仔细审查所有 CI/CD 组件管道配置的变更。
    • 对 CI/CD 组件目录项目的所有面向用户的变更使用合并请求审批

故障排除

content not found 消息

当使用 ~latest 版本限定符引用由目录项目托管的组件时,可能会收到类似以下的错误消息:

This GitLab CI configuration is invalid: Component 'gitlab.com/my-namespace/my-project/my-component@~latest' - content not found

~latest 行为已在 GitLab 16.10 中更新。它现在指的是目录资源的最新语义版本。要解决此问题,请创建新发行版

错误:构建组件错误:Spec 必须是一个有效的 JSON Schema

如果一个组件格式无效,你可能无法创建发布版本,并会收到类似 构建组件错误:Spec 必须是一个有效的 JSON Schema 的错误。

此错误可能是由于空的 spec:inputs 部分导致的。如果你的配置不使用任何输入项,你可以将 spec 部分设为空,例如:

spec:
---

my-component:
  script: echo