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

GitLab CI/CD 模板开发指南(已弃用)

随着 CI/CD 目录 的引入, GitLab 不再接受对代码库的新 CI/CD 模板的贡献。相反, 我们鼓励团队成员为目录创建 CI/CD 组件。 这一转变增强了我们共享 CI/CD 资源的模块化和可维护性, 并避免了贡献新 CI/CD 模板的复杂性。 如果您需要更新现有模板,还必须更新匹配的 CI/CD 组件。 如果尚无与 CI/CD 模板匹配的组件,请考虑创建匹配的组件。 这确保了模板和组件功能保持同步,符合我们的新开发实践。

本文档介绍如何开发 GitLab CI/CD 模板

CI/CD 模板的要求

在提交包含新 CI/CD 模板或更新模板的合并请求之前,您必须:

  • 将模板放在正确的目录中。
  • 遵循CI/CD 模板编写指南
  • 按照 *.gitlab-ci.yml 格式命名模板。
  • 使用有效的 .gitlab-ci.yml 语法。使用CI/CD 语法检查工具验证其有效性。
  • 添加模板指标
  • 如果合并请求引入了面向用户的变更,请包含更新日志
  • 遵循模板审查流程
  • (可选但强烈推荐)在审查者可以访问的示例 GitLab 项目中测试模板。审查者可能无法创建模板所需的数据或配置, 因此示例项目有助于审查者确保模板的正确性。在提交合并请求进行审查之前, 示例项目的流水线应该成功运行。

模板目录

所有模板文件都保存在 lib/gitlab/ci/templates 中。将通用模板保存在此目录中, 但某些模板类型有为其保留的特定目录。在新文件 UI 中选择模板的能力 由其所在的目录决定:

子目录 可在 UI 中选择 模板类型
/* (根目录) 通用模板。
/AWS/* 与云部署相关的模板(AWS)。
/Jobs/* 与 Auto DevOps 相关的模板。
/Pages/* 使用静态站点生成器与 GitLab Pages 配合使用的示例模板。
/Security/* 与安全扫描器相关的模板。
/Terraform/* 与基础设施即代码相关的模板(Terraform)。
/Verify/* 与测试功能相关的模板。
/Workflows/* 使用 workflow: 关键字的示例模板。

模板编写指南

使用以下指南确保您的模板提交符合标准:

模板类型

模板有两种不同的类型,影响模板的编写和使用方式。模板中的样式应匹配这两种类型之一:

管道模板提供端到端的 CI/CD 工作流,匹配项目的结构、语言等。它通常应该在没有其他 .gitlab-ci.yml 文件的项目中单独使用。

编写管道模板时:

  • 将任何全局关键词(如 imagebefore_script) 放在模板顶部的 default 部分。
  • 代码注释中明确说明模板是否设计为与现有 .gitlab-ci.yml 文件中的 includes 关键词一起使用。

作业模板提供特定的作业,可以添加到现有的 CI/CD 工作流中以完成特定任务。 它通常应该通过使用 includes 关键词添加到现有的 .gitlab-ci.yml 文件中。 您也可以将内容复制并粘贴到现有的 .gitlab-ci.yml 文件中。

配置作业模板,使用户能够以很少或无需修改的方式将其添加到当前流水线中。 必须配置以减少与其他流水线配置冲突的风险。

编写作业模板时:

  • 不要使用全局default关键词。 当根 .gitlab-ci.yml 包含模板时,全局或默认关键词可能会被覆盖并导致意外行为。 如果作业模板需要特定的阶段,请在代码注释中说明用户必须手动将阶段添加到主 .gitlab-ci.yml 配置中。
  • 代码注释中明确说明模板设计为与 includes 关键词一起使用, 或复制到现有配置中。
  • 考虑使用版本控制模板的最新和稳定版本,以避免向后兼容性问题。 此类模板的维护更复杂,因为使用 includes 导入的模板变更可能会破坏使用该模板的所有项目的流水线。

编写模板时还需注意的其他要点:

模板设计要点 管道模板 作业模板
可以使用全局关键词,包括 stages
可以定义作业。
可以在新文件 UI 中选择
可以使用 include 包含其他作业模板
可以使用 include 包含其他管道模板

语法指南

为了使模板更易于理解,模板应使用清晰的语法风格,格式一致。

每个作业的 before_scriptscriptafter_script 关键词使用 ShellCheck 进行检查, 并应尽可能遵循Shell 脚本标准和风格指南

ShellCheck 假设脚本设计为使用 Bash 运行。 对于使用与 Bash ShellCheck 规则不兼容的 shell 脚本的模板,可以从 ShellCheck 检查中排除。 要排除脚本,请将其添加到 scripts/lint_templates_bash.rbEXCLUDED_TEMPLATES 列表中。

不要硬编码默认分支

使用 $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH 代替硬编码的 main 分支,永远不要使用 master

job:
  rules:
    if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  script:
    echo "example job"

使用 rules 而不是 onlyexcept

尽可能避免使用 onlyexcept。 Only 和 except 不再继续开发,rules 现在是首选语法:

job2:
  script:
    - echo
  rules:
    - if: $CI_COMMIT_BRANCH

拆分长命令

如果命令很长,或有很多命令行标志(如 -o--option):

  • 将其拆分为多行命令,以便更容易查看命令的每个部分。
  • 尽可能使用标志的长名称。

例如,使用短 CLI 标志的长命令如 docker run --e SOURCE_CODE="$PWD" -v "$PWD":/code -v /var/run/docker.sock:/var/run/docker.sock "$CODE_QUALITY_IMAGE" /code

job1:
  script:
    - docker run
        --env SOURCE_CODE="$PWD"
        --volume "$PWD":/code
        --volume /var/run/docker.sock:/var/run/docker.sock
        "$CODE_QUALITY_IMAGE" /code

您也可以使用 |> YAML 运算符来拆分多行命令

使用注释解释模板

您可以从新文件菜单访问模板内容,这可能是用户唯一看到模板信息的地方。 直接在模板中清楚地记录模板的行为非常重要。

以下指南涵盖了所有模板提交中预期的基本注释。 如果认为注释可以帮助用户或模板审查者,请根据需要添加额外注释。

解释需求和期望

在文件顶部的 # 注释中提供如何使用模板的详细信息。 这包括:

  • 仓库/项目要求。
  • 预期行为。
  • 使用模板前用户必须编辑的任何位置。
  • 模板应该通过复制粘贴到配置文件中使用, 还是通过在现有流水线中使用 include 关键词使用。
  • 任何必须保存在项目 CI/CD 设置中的变量。
# 使用此模板发布使用 ABC 服务器的应用程序。
# 您可以将此模板复制并粘贴到新的 `.gitlab-ci.yml` 文件中。
# 您不应使用 `include:` 关键词将此模板添加到现有的 `.gitlab-ci.yml` 文件中。
#
# 要求:
# - 一个 ABC 项目,内容保存在 /content 中,测试在 /test 中
# - 一个名为 ABC-PASSWORD 的 CI/CD 变量,保存在项目 CI/CD 设置中。该值
#   应该是用于部署到 ABC 服务器的密码。
# - 配置为在端口 12345 上监听的 ABC 服务器。
#
# 您必须更改第 123 行的 URL 以指向您的 ABC 服务器和端口。
#
# 更多信息,请参见 https://gitlab.com/example/abcserver/README.md

job1:
  ...

解释变量如何影响模板行为

如果模板使用变量,请在变量首次定义的 # 注释中解释它们。 当变量明显清晰时,可以跳过注释:

variables:                        # 这里最好有注释,例如:
  TEST_CODE_PATH: <path/to/code>  # 更新此变量,使其指向您的 Ruby 规范的相对路径

job1:
  variables:
    ERROR_MESSAGE: "The $TEST_CODE_PATH path is invalid"  # (此处无需注释,已经很清楚)
  script:
    - echo ${ERROR_MESSAGE}

非局部变量使用全大写命名

如果您期望变量通过 CI/CD 设置或 variables 关键词提供, 该变量必须使用全大写命名,单词之间用下划线 (_) 分隔。

.with_login:
  before_script:
    # SECRET_TOKEN 应该通过项目设置提供
    - echo "$SECRET_TOKEN" | docker login -u my-user --password-stdin my-registry

对于在某个 script 关键词中本地定义的变量,可以选择使用小写命名:

job1:
  script:
    - response="$(curl "https://example.com/json")"
    - message="$(echo "$response" | jq -r .message)"
    - 'echo "Server responded with: $message"'

向后兼容性

模板可能使用 include:template: 关键词动态包含。 如果您对现有模板进行更改,必须确保它不会破坏现有项目中的 CI/CD。

例如,更改模板中的作业名称可能会破坏现有项目中的流水线。 在此示例中,名为 Performance.gitlab-ci.yml 的模板包含以下内容:

performance:
  image: registry.gitlab.com/gitlab-org/verify-tools/performance:v0.1.0
  script: ./performance-test $TARGET_URL

用户通过向 performance 作业传递参数来包含此模板。 这可以通过在他们的 .gitlab-ci.yml 中指定 CI/CD 变量 TARGET_URL 来完成:

include:
  template: Performance.gitlab-ci.yml

performance:
  variables:
    TARGET_URL: https://awesome-app.com

如果模板中的作业名称 performance 被重命名为 browser-performance, 用户的 .gitlab-ci.yml 会立即导致语法错误,因为包含的模板中不再有名为 performance 的作业。 因此,用户必须修复他们的 .gitlab-ci.yml,这可能影响他们的工作流程。

阅读版本控制部分,了解如何安全地引入破坏性变更。

版本控制

为了在不影响依赖当前模板的现有项目的情况下引入破坏性变更, 请使用稳定最新版本控制。

稳定模板通常只在主要版本发布中接收破坏性变更,而最新模板可以在任何版本中接收破坏性变更。 在主要版本里程碑中,最新模板成为新的稳定模板(最新模板可能被删除)。

添加最新模板是安全的,但会带来维护负担:

  • GitLab 必须在下一个 GitLab 主要版本中选择一个 DRI,用最新模板的内容覆盖稳定模板。 DRI 负责支持遇到变更问题的用户。
  • 当我们进行新的非破坏性变更时,稳定和最新模板都必须尽可能匹配更新。
  • 最新模板可能会比计划存在更长时间,因为许多用户可能直接依赖其持续存在。

在添加新的最新模板之前,看看是否可以将变更应用到稳定模板,即使它是破坏性的。 如果模板仅用于复制粘贴使用,则可能直接更改稳定版本。 在次要里程碑中更改带有破坏性变更的稳定模板之前,请确保:

稳定版本

稳定的 CI/CD 模板是仅在主要版本里程碑中引入破坏性变更的模板。 将模板的稳定版本命名为 <template-name>.gitlab-ci.yml, 例如 Jobs/Deploy.gitlab-ci.yml

您可以通过复制最新模板来创建新的稳定模板, 该模板在 GitLab 的主要版本发布(如 15.0)中可用。所有破坏性变更都必须在 按版本弃用和移除页面上宣布。

您可以在次要 GitLab 版本(如 15.1)中更改稳定模板版本,如果:

最新版本

标记为 latest 的模板可以在任何版本中更新,即使带有破坏性变更。 如果模板被认为是最新版本,请在模板名称后添加 .latest, 例如 Jobs/Deploy.latest.gitlab-ci.yml

当您引入破坏性变更时, 必须测试并记录升级路径。 通常,我们不应将最新模板作为最佳选项推广,因为它可能会让用户遇到意外问题。

如果 latest 模板尚不存在,您可以复制稳定模板

如何包含较旧的稳定模板

用户可能希望使用未包含在当前 GitLab 包中的较旧稳定模板。 例如,GitLab 15.0 和 GitLab 16.0 中的稳定模板可能差异很大, 以至于用户即使在升级到 GitLab 16.0 后仍希望继续使用 GitLab 15.0 模板。

您可以在模板或文档中添加说明,解释如何使用 include:remote 包含较旧的模板版本。 如果其他模板使用 include: template 包含,它们可以与 include: remote 结合使用:

# 要使用 v13 稳定模板(未包含在 v14 中),使用 `include:remote:` 关键字从远程模板仓库获取特定模板。
# 如果从 GitLab 官方项目获取,请使用以下 URL 格式:
# https://gitlab.com/gitlab-org/gitlab/-/raw/<version>/lib/gitlab/ci/templates/<template-name>
include:
  - template: Auto-DevOps.gitlab-ci.yml
  - remote: https://gitlab.com/gitlab-org/gitlab/-/raw/v13.0.1-ee/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml

进一步阅读

有一个开放问题关于 在 GitLab CI/CD 模板中引入版本控制概念。您可以查看该问题以跟踪进展。

测试

每个 CI/CD 模板都必须经过测试,确保可以安全发布。

手动质量保证

在最小演示项目中测试模板总是好的做法。 为此,请遵循以下步骤:

  1. https://gitlab.com 上创建一个公共示例项目。
  2. 向项目添加一个包含建议模板的 .gitlab-ci.yml
  3. 运行流水线并确保所有情况都正常运行(合并请求流水线、计划任务等)。
  4. 在添加新模板的合并请求描述中链接到该项目。

这对审查者确保模板可以安全合并很有用。

确保新模板可以在 UI 中选择

位于某些目录下的模板也可以在新文件 UI中选择。 当您将模板添加到这些目录之一时,确保它正确显示在下拉列表中:

CI/CD 模板选择

编写 RSpec 测试

您应该编写 RSpec 测试以确保流水线作业正确生成:

  1. spec/lib/gitlab/ci/templates/<template-category>/<template-name>_spec.rb 添加测试文件
  2. 通过 Ci::CreatePipelineService 测试流水线作业是否正确创建

验证破坏性变更

当您对最新模板引入破坏性变更时,您必须:

  1. 测试从稳定模板的升级路径。
  2. 验证用户遇到的错误类型。
  3. 将其记录为故障排除指南。

稳定模板在主要版本 GitLab 发布中更新时, 这些信息对用户很重要。

添加指标

每个 CI/CD 模板还必须定义指标以跟踪其使用情况。CI/CD 模板月度使用报告 可以在 Sisense(仅限 GitLab 团队成员) 中找到。 选择模板以查看该单个图表。

为新模板添加指标定义:

  1. 安装并启动 GitLab GDK

  2. 在您的 GDK 中的 gitlab 目录中,检出包含新模板的分支。

  3. 将新模板事件名称添加到每周和每月 CI/CD 模板总数指标中:

  4. 使用与上面相同的事件名称作为最后一个参数,运行以下命令 添加新指标定义

bundle exec rails generate gitlab:usage_metric_definition:redis_hll ci_templates <template_metric_event_name>

输出应如下所示:

$ bundle exec rails generate gitlab:usage_metric_definition:redis_hll ci_templates p_ci_templates_my_template_name
      create  config/metrics/counts_7d/20220120073740_p_ci_templates_my_template_name_weekly.yml
      create  config/metrics/counts_28d/20220120073746_p_ci_templates_my_template_name_monthly.yml
  1. 编辑两个新生成的文件,如下所示:
  • name:performance_indicator_type::删除(不需要)。

  • introduced_by_url::添加模板的 MR URL。

  • data_source::设置为 redis_hll

  • description:添加此指标计数内容的简短描述,例如:Count of pipelines using the latest Auto Deploy template

  • product_*:根据指标字典指南 设置为部分、阶段、组和功能类别。 如果不确定这些关键词的用法,可以在合并请求中寻求帮助。

  • 在每个文件末尾添加以下内容:

    options:
      events:
        - p_ci_templates_my_template_name
  1. 提交并推送更改。

例如,这是 5 Minute Production App 模板的指标配置文件:

安全性

模板可能包含恶意代码。例如,包含 export shell 命令的作业模板 可能会意外地在作业日志中暴露秘密项目 CI/CD 变量。 如果您不确定是否安全,必须要求安全专家进行交叉验证。

贡献 CI/CD 模板合并请求

创建 CI/CD 模板 MR 并标记为 ci::templates 后,DangerBot 会建议一位审查者和一位维护者来审查您的代码。当您的合并请求准备好审查时, 提及审查者并请他们审查您的 CI/CD 模板更改。 详细信息请参见添加了 CI/CD 模板 MR 的 DangerBot 任务的合并请求。