向极狐GitLab CI/CD 模板做贡献(已弃用)
本文档解释了如何开发极狐GitLab CI/CD 模板。
CI/CD 模板的要求
在提交包含新的或更新的 CI/CD 模板的合并请求之前,您必须:
- 将模板放置在正确的目录中。
- 遵循CI/CD 模板编写指南。
- 按照 *.gitlab-ci.yml 格式命名模板。
- 使用有效的.gitlab-ci.yml 语法。使用 CI/CD lint 工具 验证其有效性。
- 添加模板指标。
- 如果合并请求引入了用户可见的更改,请包含变更日志。
- 遵循模板审查过程。
- (可选但强烈推荐)在审阅者可以访问的示例极狐GitLab 项目中测试模板。审阅者可能无法创建模板所需的数据或配置,因此示例项目有助于审阅者确保模板正确。示例项目流水线应在提交合并请求进行审查之前成功运行。
模板目录
所有模板文件都保存在 lib/gitlab/ci/templates 中。将通用模板保存在此目录中,但某些模板类型有专门的目录为其保留。选择在新文件 UI 中选择模板的能力由其所在的目录决定:
子目录 | UI 中可选择 | 模板类型 |
---|---|---|
/* (根目录) | 是 | 通用模板。 |
/AWS/* | 否 | 与云部署(AWS)相关的模板。 |
/Jobs/* | 否 | 与自动 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 进行 lint,并应尽可能遵循Shell 脚本标准和样式指南。
ShellCheck 假定脚本设计为使用 Bash 运行。使用与 Bash ShellCheck 规则不兼容的 shell 编写脚本的模板可以从 ShellCheck lint 中排除。要排除脚本,请将其添加到 scripts/lint_templates_bash.rb 中的 EXCLUDED_TEMPLATES 列表中。
不要硬编码默认分支
使用 $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH 而不是硬编码的 main 分支,并且绝不要使用 master:
yamljob: rules: if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH script: echo "example job"
使用 rules 而不是 only 或 except
尽量避免使用 only 或 except。Only 和 except 不再被开发,rules 现在是首选语法:
yamljob2: 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:
yaml1job1: 2 script: 3 - docker run 4 --env SOURCE_CODE="$PWD" 5 --volume "$PWD":/code 6 --volume /var/run/docker.sock:/var/run/docker.sock 7 "$CODE_QUALITY_IMAGE" /code
您还可以使用 | 和 > YAML 运算符来拆分多行命令。
使用注释解释模板
您可以从新文件菜单中访问模板内容,这可能是用户查看模板信息的唯一地方。直接在模板中清楚地记录模板的行为非常重要。
以下指南涵盖了所有模板提交中期望的基本注释。如果您认为注释可以帮助用户或模板审阅者,请根据需要添加附加注释。
解释要求和期望
在文件顶部的 # 注释中提供有关如何使用模板的详细信息。这包括:
- 仓库/项目要求。
- 预期行为。
- 用户在使用模板之前必须编辑的任何地方。
- 模板是否应通过将其复制粘贴到配置文件中使用,或者在现有流水线中使用 include 关键字使用。
- 是否必须在项目的 CI/CD 设置中保存任何变量。
yaml1# 使用此模板发布使用 ABC 服务器的应用程序。 2# 您可以将此模板复制并粘贴到新的 `.gitlab-ci.yml` 文件中。 3# 您不应通过使用 `include:` 关键字将此模板添加到现有 `.gitlab-ci.yml` 文件中。 4# 5# 要求: 6# - 一个 ABC 项目,内容保存在 /content 中,测试保存在 /test 中 7# - 在项目 CI/CD 设置中保存名为 ABC-PASSWORD 的 CI/CD 变量。值应为用于部署到您的 ABC 服务器的密码。 8# - 配置为侦听端口 12345 的 ABC 服务器。 9# 10# 您必须将第 123 行的 URL 更改为指向您的 ABC 服务器和端口。 11# 12# 更多信息,请参阅 https://gitlab.com/example/abcserver/README.md 13 14job1: 15 ...
解释变量如何影响模板行为
如果模板使用变量,请在首次定义它们时在 # 注释中解释它们。当变量显而易见时,可以跳过注释:
yaml1variables: # 这里的注释非常好,例如: 2 TEST_CODE_PATH: <path/to/code> # 使用相对路径更新此变量 3 4job1: 5 variables: 6 ERROR_MESSAGE: "The $TEST_CODE_PATH path is invalid" # (这里不需要注释,因为已经很清楚) 7 script: 8 - echo ${ERROR_MESSAGE}
对非本地变量使用全大写命名
如果您期望通过 CI/CD 设置或通过 variables 关键字提供变量,则该变量必须使用下划线(_)分隔单词的全大写命名。
yaml.with_login: before_script: # SECRET_TOKEN 应通过项目设置提供 - echo "$SECRET_TOKEN" | docker login -u my-user --password-stdin my-registry
可以选择对在 script 关键字之一中本地定义的变量使用小写命名:
yamljob1: 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 的模板,其内容如下:
yamlperformance: 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 来完成:
yaml1include: 2 template: Performance.gitlab-ci.yml 3 4performance: 5 variables: 6 TARGET_URL: https://awesome-app.com
如果模板中的作业名称 performance 被重命名为 browser-performance,用户的 .gitlab-ci.yml 将立即导致 lint 错误,因为包含的模板中不再有名为 performance 的作业。因此,用户必须修复他们的 .gitlab-ci.yml,这可能会打扰他们的工作流程。
请阅读版本控制部分,以安全地引入重大更改。
版本控制
为了在不影响依赖于当前模板的现有项目的情况下引入重大更改,请使用稳定和最新版本控制。
稳定模板通常仅在主要版本发布中接收重大更改,而最新模板可以在任何版本中接收重大更改。在极狐GitLab 的主要版本发布中,最新模板将成为新的稳定模板(并且最新模板可能会被删除)。
添加最新模板是安全的,但会带来维护负担:
- 极狐GitLab 必须选择 DRI 来在极狐GitLab 的下一个主要版本中用最新模板的内容覆盖稳定模板。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 结合使用:
yaml1# 要使用 v13 稳定模板(在 v14 中未包含),请使用 `include:remote:` 关键字从远程模板仓库中获取特定模板。 2# 如果您从极狐GitLab 的官方项目获取,请使用以下 URL 格式: 3# https://gitlab.com/gitlab-org/gitlab/-/raw/<version>/lib/gitlab/ci/templates/<template-name> 4include: 5 - template: Auto-DevOps.gitlab-ci.yml 6 - remote: https://gitlab.com/gitlab-org/gitlab/-/raw/v13.0.1-ee/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
测试
每个 CI/CD 模板都必须经过测试,以确保其安全可发布。
手动 QA
在一个最小的演示项目中测试模板始终是一个好的实践。为此,请执行以下步骤:
- 在 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 模板还必须定义指标以跟踪其使用情况。
要为新模板添加指标定义:
-
安装并启动 极狐GitLab GDK。
-
在 GDK 中的 gitlab 目录中,检出包含新模板的分支。
-
将新模板事件名称添加到每周和每月 CI/CD 模板总计数指标中:
-
使用上面的相同事件名称作为最后一个参数,在以下命令中 添加新的指标定义:
shellbundle exec rails generate gitlab:usage_metric_definition:redis_hll ci_templates <template_metric_event_name>
输出应如下所示:
shell$ 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:添加一个简短的描述,说明此指标的计数内容,例如:使用最新自动部署模板的流水线计数
-
product_*:根据 metrics 字典指南 设置为section, stage, group, 和 feature category。如果您不确定这些关键字的用法,可以在合并请求中寻求帮助。
-
在每个文件的末尾添加以下内容:
yamloptions: events: - p_ci_templates_my_template_name
-
-
提交并推送更改。
例如,这是5 分钟生产应用模板的指标配置文件:
- 每周和每月指标定义:
- 指标计数总计:
安全性
模板可能包含恶意代码。例如,包含作业中 export shell 命令的模板可能会在作业日志中意外泄露机密项目 CI/CD 变量。如果您不确定它是否安全,您必须要求安全专家进行交叉验证。
贡献 CI/CD 模板合并请求
在创建并标记为 ci::templates 的 CI/CD 模板 MR 之后,DangerBot 会建议一位审阅者和一位维护者来审查您的代码。当您的合并请求准备好审阅时,提及审阅者并请他们审查您的 CI/CD 模板更改。