gitlab高级功能之CI/CD组件 - 原理介绍(一)
文章目录
- 1. 介绍
- 2. 组件存储库
- 3. 创建组件存储库
- 3.1 目录结构
- 4. 发布组件
- 5. 在 CI/CD 配置中使用组件
- 5.1 避免使用全局关键字
- 5.2 用输入替换硬编码值
- 5.3 用输入替换自定义 CI/CD 变量
- 6. 将 CI/CD 模板转换为组件
参考文档:https://docs.gitlab.com/ee/ci/components/
1. 介绍
引入16.0,16.6正式使用
- CI/CD 组件是可重用的单管道配置单元,使用它们来组成整个管道配置或较大管道的一小部分;
- CI/CD组件可以选择接受输入参数;
- CI/CD 组件与使用 include 关键字添加的其他类型的配置类似,但具有以下几个优点:
- 组件可以以特定版本发布和使用;
- 多个组件可以组合在同一个项目中并使用单个标签发布;
- 组件可以在 CI/CD 目录中找到。
2. 组件存储库
- 组件存储库是一个 GitLab 项目,其中包含托管一个或多个管道组件的存储库。项目中的所有组件都进行版本控制并一起发布。
- 如果某个组件需要与其他组件不同的版本控制,则应将该组件迁移到其自己的组件存储库。
- 一个组件存储库最多可以有 10 个组件。
3. 创建组件存储库
创建一个组件仓库,你必须:
-
创建一个项目并且有RADME.md文件
-
为每个组件添加yaml配置文件,并按照如下的目录结构。
如:``` spec: inputs: stage: default: test --- component-job: script: echo job 1 stage: $[[ inputs.stage ]] ```
3.1 目录结构
- 组件存储库可以托管一个或多个组件,并且必须遵循强制文件结构。
- 组件配置可以通过以下目录结构保存,包含:
- 组件存储库顶层的模板目录,所有组件配置文件都应保存在该目录下;
- 以 .yml 结尾的文件包含组件配置,每个组件一个文件;
- Markdown README.md 文件解释了存储库中所有组件的详细信息。
示例1: 如果项目包含单个组件和用于测试该组件的管道,则文件结构应类似于:
├── templates/
│ └── secret-detection.yml
├── README.md
└── .gitlab-ci.yml
该示例组件可以通过类似于以下的路径引用: gitlab.com/my-namespace/my-project/secret-detection@<version>
,其中:
- gitlab.com 项目访问的域名
- my-namespace 项目的所在群组
- my-project 项目的名称
引用的路径中应排除模板目录
和配置文件的后缀
。
示例2: 如果项目包含多个组件,则文件结构应类似于:
├── README.md
├── .gitlab-ci.yml
└── templates/
├── all-scans.yml
└── secret-detection.yml
该示例组件将通过以下路径引用:
gitlab.com/my-namespace/my-project/all-scans@<version>
gitlab.com/my-namespace/my-project/secret-detection@<version>
示例3: 如果您想将多个相关文件捆绑在一起,您还可以将组件定义为目录。在这种情况下,GitLab 期望存在 template.yml 文件:
├── README.md
├── .gitlab-ci.yml
└── templates/
└── dast
├── docs.md
├── Dockerfile
└── template.yml
在此示例中,可以使用 gitlab.com/my-namespace/my-project/dast@<version>
引用该组件。
4. 发布组件
要为 CI/CD 组件创建版本,请在 CI/CD 管道中使用 release 关键字。
例如:
create-release:
stage: deploy
image: registry.gitlab.com/gitlab-org/release-cli:latest
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+/
script: echo "Creating release $CI_COMMIT_TAG"
release:
tag_name: $CI_COMMIT_TAG
description: "Release $CI_COMMIT_TAG of components repository $CI_PROJECT_PATH"
在此示例中,作业仅针对格式为 v + 版本号的标签运行。如果之前的所有作业均成功,则将创建版本。
与组件测试示例一样,您可以将组件设置为在新标签的所有测试通过管道后自动发布。
组件存储库的所有已发布版本都显示在 CI/CD 目录中,为用户提供有关正式版本的信息。
通过使用提交 SHA 或引用,组件可以在不被释放的情况下使用。但是,~latest version 关键字只能与已发布的标签一起使用。
~latest 关键字始终返回最新版本,而不是具有最新语义版本的版本。例如,如果您首先发布 v2.0.0,然后发布 v1.5.1 等补丁修复,则 ~latest 将返回 v1.5.1 版本。
5. 在 CI/CD 配置中使用组件
你可以使用 include: component 关键字将组件添加到 CI/CD 配置中。例如:
include:
- component: gitlab.example.com/my-namespace/my-project@1.0
inputs:
stage: build
该组件由唯一地址标识,格式为 /@,其中:
<fully-qualified-domain-name>
与 GitLab 主机匹配;<component-path>
是组件项目的完整路径和组件YAML文件所在的目录;<specific-version>
是组件的版本,按照优先级最高的顺序,版本可以是:- 分支名称,例如 main;
- 提交 SHA,例如 e3262fdd0914fa823210cdb79a8c421e2cef79d8;
- 一个标签,例如:1.0。如果标签和分支存在同名,则标签优先于分支。如果标签和提交 SHA 存在同名,则提交 SHA 优先于标签。
- ~latest,这是一个特殊版本,始终指向最新发布的标签。仅当组件已发布时才可用。
例如,对于位于 gitlab.com 上的 gitlab-org/dast 的组件存储库,路径:
gitlab.com/gitlab-org/dast@main
的目标是主分支根目录中的 template.yml 。gitlab.com/gitlab-org/dast@e3262fdd0914fa823210cdb79a8c421e2cef79d8
针对指定提交 SHA 的目标文件相同。gitlab.com/gitlab-org/dast@1.0
针对 1.0 标签的相同文件。gitlab.com/gitlab-org/dast@~latest
针对最新版本的相同文件。gitlab.com/gitlab-org/dast/api-scan@main
针对主分支的不同文件,即组件存储库中 /api-scan 目录中的 template.yml 。
5.1 避免使用全局关键字
避免在组件中使用全局关键字。在组件中使用这些关键字会影响管道中的所有作业,包括直接在主 .gitlab-ci.yml 或其他包含的组件中定义的作业。
作为全局关键字的替代方案,可以:
- 将配置直接添加到每个作业中,即使它会在组件配置中产生一些重复。
- 在组件中使用 extends 关键字。
例如,不建议使用default关键字:
# Not recommended
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/
- 使用extend来重用配置:
.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/
5.2 用输入替换硬编码值
避免在 CI/CD 组件中硬编码值。硬编码值可能会迫使组件用户需要检查组件的内部细节并调整其管道以与组件配合使用。
stage 是具有有问题的硬编码值的常见关键字。如果组件作业的阶段设置为特定值,则使用该组件的管道必须定义完全相同的阶段。此外,如果组件用户想要使用不同的阶段,他们必须覆盖配置。
首选方法是使用输入关键字。组件用户可以指定他们需要的确切值。
例如:
- 在组件配置中:
spec:
inputs:
stage:
default: test
---
unit-test:
stage: $[[ inputs.stage ]]
script: echo unit tests
integration-test:
stage: $[[ inputs.stage ]]
script: echo integration tests
- 在项目中使用该组件:
include:
- component: gitlab.com/gitlab-org/ruby-test@1.0
inputs:
stage: verify
stages: [verify, deploy]
5.3 用输入替换自定义 CI/CD 变量
在组件中使用 CI/CD 变量时,请评估是否应改用 input 关键字。避免要求用户定义自定义变量来更改组件的行为。您应该尝试使用输入进行任何组件自定义.
输入在组件的规范中明确定义,并且比变量得到更好的验证。例如,如果所需的输入未传递给组件,GitLab 将返回管道错误。相反,如果变量未定义,则其值为空,并且不会出现错误。
例如,使用输入而不是变量来让用户更改扫描仪的输出格式:
- 在组件配置中:
spec:
inputs:
scanner-output:
default: json
---
my-scanner:
script: my-scan --output $[[ inputs.scanner-output ]]
- 在项目中使用该组件:
include:
- component: gitlab.example.com/my-scanner@1.0
inputs:
scanner-output: yaml
在其他情况下,CI/CD 变量仍然是首选,包括:
- 使用预定义变量自动配置组件以匹配用户的项目。
- 要求将令牌或其他敏感值存储为项目设置中的屏蔽或受保护变量。
6. 将 CI/CD 模板转换为组件
您通过使用 include: 语法在项目中使用的任何现有 CI/CD 模板都可以转换为 CI/CD 组件:
- 决定是否希望该组件成为现有组件存储库的一部分并与其他组件分组,或者创建并设置新的组件存储库。
- 根据预期的目录结构在组件存储库中创建 YAML 文件。
- 将原始模板 YAML 文件的内容复制到新组件 YAML 文件中。
- 将新组件的配置重构为:
- 遵循组件的最佳实践。
- 改进配置,例如启用合并请求管道或提高其效率。
- 利用组件存储库中的 .gitlab-ci.yml 来测试对组件的更改。
- 标记并释放组件。