GitLab 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 文件的项目中单独使用。
编写管道模板时:
- 将任何全局关键词(如
image或before_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_script、script 和 after_script 关键词使用 ShellCheck 进行检查,
并应尽可能遵循Shell 脚本标准和风格指南。
ShellCheck 假设脚本设计为使用 Bash 运行。
对于使用与 Bash ShellCheck 规则不兼容的 shell 脚本的模板,可以从 ShellCheck 检查中排除。
要排除脚本,请将其添加到 scripts/lint_templates_bash.rb 的 EXCLUDED_TEMPLATES 列表中。
不要硬编码默认分支
使用 $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
代替硬编码的 main 分支,永远不要使用 master:
job:
rules:
if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
echo "example job"使用 rules 而不是 only 或 except
尽可能避免使用 only 或 except。
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 负责支持遇到变更问题的用户。
- 当我们进行新的非破坏性变更时,稳定和最新模板都必须尽可能匹配更新。
- 最新模板可能会比计划存在更长时间,因为许多用户可能直接依赖其持续存在。
在添加新的最新模板之前,看看是否可以将变更应用到稳定模板,即使它是破坏性的。 如果模板仅用于复制粘贴使用,则可能直接更改稳定版本。 在次要里程碑中更改带有破坏性变更的稳定模板之前,请确保:
- 它是一个管道模板,并且有代码注释
说明它不设计为与
includes一起使用。 - CI/CD 模板使用指标不显示任何使用情况。如果指标显示模板使用量为零,
则模板未被主动使用
include。
稳定版本
稳定的 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 模板都必须经过测试,确保可以安全发布。
手动质量保证
在最小演示项目中测试模板总是好的做法。 为此,请遵循以下步骤:
- 在 https://gitlab.com 上创建一个公共示例项目。
- 向项目添加一个包含建议模板的
.gitlab-ci.yml。 - 运行流水线并确保所有情况都正常运行(合并请求流水线、计划任务等)。
- 在添加新模板的合并请求描述中链接到该项目。
这对审查者确保模板可以安全合并很有用。
确保新模板可以在 UI 中选择
位于某些目录下的模板也可以在新文件 UI中选择。 当您将模板添加到这些目录之一时,确保它正确显示在下拉列表中:
编写 RSpec 测试
您应该编写 RSpec 测试以确保流水线作业正确生成:
- 在
spec/lib/gitlab/ci/templates/<template-category>/<template-name>_spec.rb添加测试文件 - 通过
Ci::CreatePipelineService测试流水线作业是否正确创建
验证破坏性变更
当您对最新模板引入破坏性变更时,您必须:
- 测试从稳定模板的升级路径。
- 验证用户遇到的错误类型。
- 将其记录为故障排除指南。
当稳定模板在主要版本 GitLab 发布中更新时, 这些信息对用户很重要。
添加指标
每个 CI/CD 模板还必须定义指标以跟踪其使用情况。CI/CD 模板月度使用报告 可以在 Sisense(仅限 GitLab 团队成员) 中找到。 选择模板以查看该单个图表。
为新模板添加指标定义:
-
安装并启动 GitLab GDK。
-
在您的 GDK 中的
gitlab目录中,检出包含新模板的分支。 -
将新模板事件名称添加到每周和每月 CI/CD 模板总数指标中:
-
使用与上面相同的事件名称作为最后一个参数,运行以下命令 添加新指标定义:
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- 编辑两个新生成的文件,如下所示:
-
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
- 提交并推送更改。
例如,这是 5 Minute Production App 模板的指标配置文件:
- 每周和每月指标定义:
- 指标计数总数:
安全性
模板可能包含恶意代码。例如,包含 export shell 命令的作业模板
可能会意外地在作业日志中暴露秘密项目 CI/CD 变量。
如果您不确定是否安全,必须要求安全专家进行交叉验证。
贡献 CI/CD 模板合并请求
创建 CI/CD 模板 MR 并标记为 ci::templates 后,DangerBot
会建议一位审查者和一位维护者来审查您的代码。当您的合并请求准备好审查时,
提及审查者并请他们审查您的 CI/CD 模板更改。
详细信息请参见添加了
CI/CD 模板 MR 的 DangerBot 任务的合并请求。