适用层级:Free、Premium、Ultimate。
提供方式:GitLab.com、GitLab Self-Managed、GitLab Dedicated。
测试组件
根据组件的功能,测试组件可能需要在仓库中添加其他文件。例如,一个针对特定编程语言执行代码检查、构建和测试的组件,需要实际的源代码示例。源代码示例、配置文件等都可以放在同一个仓库中。
例如,Code Quality CI/CD 组件提供了多个用于测试的代码示例。
示例:测试 Rust 语言的 CI/CD 组件
根据组件的功能,测试组件可能需要在仓库中添加其他文件。
为简便起见,下面的 Rust 编程语言“hello world”示例使用 cargo 工具链:
- 进入 CI/CD 组件的根目录。
- 使用
cargo init命令初始化一个新的 Rust 项目。cargo init此命令会创建所有必需的项目文件,包括
src/main.rs中的“hello world”示例。完成这一步,就可以在组件作业中通过cargo build构建 Rust 源代码。tree . ├── Cargo.toml ├── LICENSE.md ├── README.md ├── src │ └── main.rs └── templates └── build.yml - 确保组件有一个构建 Rust 源代码的作业,例如将其放在
templates/build.yml中:spec: inputs: stage: default: build description: 'Defines the build stage' rust_version: default: latest description: 'Specify the Rust version, use values from https://hub.docker.com/_/rust/tags Defaults to latest' --- "build-$[[ inputs.rust_version ]]": stage: $[[ inputs.stage ]] image: rust:$[[ inputs.rust_version ]] script: - cargo build --verbose在此示例中:
stage和rust_version输入的值可以修改,不必使用默认值。CI/CD 作业名称以build-为前缀,并根据rust_version输入动态生成。命令cargo build --verbose会编译 Rust 源代码。
- 在项目的
.gitlab-ci.yml配置文件中测试组件的build模板:include: # include the component located in the current project from the current SHA - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/build@$CI_COMMIT_SHA inputs: stage: build stages: [build, test, release] - 如需运行测试及实现更多功能,请在 Rust 代码中添加其他函数和测试,并在
templates/test.yml中添加执行cargo test的组件模板与作业。spec: inputs: stage: default: test description: 'Defines the test stage' rust_version: default: latest description: 'Specify the Rust version, use values from https://hub.docker.com/_/rust/tags Defaults to latest' --- "test-$[[ inputs.rust_version ]]": stage: $[[ inputs.stage ]] image: rust:$[[ inputs.rust_version ]] script: - cargo test --verbose - 通过引入
test组件模板,在流水线中测试新增作业:include: # include the component located in the current project from the current SHA - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/build@$CI_COMMIT_SHA inputs: stage: build - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/test@$CI_COMMIT_SHA inputs: stage: test stages: [build, test, release]
CI/CD 组件模式
本节提供在 CI/CD 组件中实现常见模式的实用示例。
使用布尔输入按条件配置作业
结合 boolean 类型的输入和 extends 功能,可以构建具有两个条件分支的作业。
例如,使用 boolean 输入配置复杂的缓存行为:
spec:
inputs:
enable_special_caching:
description: 'If set to `true` configures a complex caching behavior'
type: boolean
---
.my-component:enable_special_caching:false:
extends: null
.my-component:enable_special_caching:true:
cache:
policy: pull-push
key: $CI_COMMIT_SHA
paths: [...]
my-job:
extends: '.my-component:enable_special_caching:$[[ inputs.enable_special_caching ]]'
script: ... # run some fancy tooling
此模式把 enable_special_caching 输入传给作业的 extends 关键字。根据 enable_special_caching 是 true 还是 false,从预定义的隐藏作业(.my-component:enable_special_caching:true 或 .my-component:enable_special_caching:false)中选择相应配置。
使用 options 按条件配置作业
可以使用多个选项构建作业,实现类似 if 和 elseif 条件分支的行为。将 extends 与 string 类型及多个 options 结合使用,即可处理任意数量的条件。
例如,通过三个不同的选项配置复杂的缓存行为:
spec:
inputs:
cache_mode:
description: Defines the caching mode to use for this component
type: string
options:
- default
- aggressive
- relaxed
---
.my-component:cache_mode:default:
extends: null
.my-component:cache_mode:aggressive:
cache:
policy: push
key: $CI_COMMIT_SHA
paths: ['*/**']
.my-component:cache_mode:relaxed:
cache:
policy: pull-push
key: $CI_COMMIT_BRANCH
paths: ['bin/*']
my-job:
extends: '.my-component:cache_mode:$[[ inputs.cache_mode ]]'
script: ... # run some fancy tooling
在此示例中,cache_mode 输入提供 default、aggressive 和 relaxed 选项,每个选项对应一个不同的隐藏作业。通过 extends: '.my-component:cache_mode:$[[ inputs.cache_mode ]]' 扩展组件作业后,作业会根据所选选项动态继承正确的缓存配置。
使用组件上下文引用带版本的资源
- 在 GitLab 18.6 中引入,当时为 Beta 功能,使用名为
ci_component_context_interpolation的功能标志,默认启用。 - 在 GitLab 18.7 中正式可用,移除了功能标志
ci_component_context_interpolation。
使用组件上下文的 CI/CD 表达式引用组件元数据,例如版本和提交 SHA。一种用途是随组件一起构建和发布带版本的资源(例如 Docker 镜像),并确保组件使用匹配的版本。
例如,你可以:
- 在组件的发布流水线中构建 Docker 镜像,并使用与组件版本一致的标签。
- 让组件引用同一个镜像版本。
组件项目的发布流水线(.gitlab-ci.yml):
build-image:
stage: build
image: docker:latest
script:
- docker build -t $CI_REGISTRY_IMAGE/my-tool:$CI_COMMIT_TAG .
- docker push $CI_REGISTRY_IMAGE/my-tool:$CI_COMMIT_TAG
create-release:
stage: release
image: registry.gitlab.com/gitlab-org/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"
组件模板(templates/my-component/template.yml):
spec:
component: [version, reference]
inputs:
stage:
default: test
---
run-tool:
stage: $[[ inputs.stage ]]
image: $CI_REGISTRY_IMAGE/my-tool:$[[ component.version ]]
script:
- echo "Running tool version $[[ component.version ]]"
- echo "Component was included using reference: $[[ component.reference ]]"
- my-tool --version
在此示例中:
- 如果通过
@1.0.0引入组件,作业会使用镜像my-tool:1.0.0。 - 如果通过
@1.0引入,它会解析为最新的1.0.x版本,例如1.0.3,因此会使用my-tool:1.0.3。 - 如果通过
@~latest引入,它会使用最新的已发布版本。 component.reference字段显示你指定的确切引用,例如1.0、~latest或某个 SHA。可以将此引用用于日志记录或调试。
CI/CD 组件迁移示例
本节通过实用示例,展示如何把 CI/CD 模板与流水线配置迁移为可复用的 CI/CD 组件。
CI/CD 组件迁移示例:Go
软件开发生命周期的完整流水线可以由多个作业和阶段组成。面向编程语言的 CI/CD 模板可能会在一个模板文件中提供多个作业。作为练习,下面将迁移这个 Go CI/CD 模板。
default:
image: golang:latest
stages:
- test
- build
- deploy
format:
stage: test
script:
- go fmt $(go list ./... | grep -v /vendor/)
- go vet $(go list ./... | grep -v /vendor/)
- go test -race $(go list ./... | grep -v /vendor/)
compile:
stage: build
script:
- mkdir -p mybinaries
- go build -o mybinaries ./...
artifacts:
paths:
- mybinaries
CI/CD 模板迁移包含以下步骤:
- 分析 CI/CD 作业及依赖关系,并确定迁移操作:
image配置是全局的,需要移入作业定义。format作业在同一个作业中运行多条go命令。应把go test命令移入独立作业,以提高流水线效率。compile作业运行go build,应将其重命名为build。
- 确定优化策略,提高流水线效率。
- 作业属性
stage应当可以配置,以适应不同的 CI/CD 流水线使用方。 image键使用了硬编码的镜像标签latest。添加以latest为默认值的golang_version输入,使流水线更加灵活且易于复用。输入值必须与 Docker Hub 镜像的标签值匹配。compile作业将二进制文件构建到硬编码的目标目录mybinaries。可以改用动态输入并保留默认值mybinaries,以改进这一点。
- 作业属性
- 为新组件创建模板目录结构,每个作业对应一个模板。
- 模板名称应与
go命令相对应,例如format.yml、build.yml和test.yml。 - 创建新项目,初始化 Git 仓库,添加并提交全部更改,设置远程 origin,然后推送。请把 URL 修改为你的 CI/CD 组件项目路径。
- 按照编写组件的指南创建其他文件:
README.md、LICENSE.md、.gitlab-ci.yml、.gitignore。以下 shell 命令用于初始化 Go 组件结构:
git init mkdir templates touch templates/{format,build,test}.yml touch README.md LICENSE.md .gitlab-ci.yml .gitignore git add -A git commit -avm "Initial component structure" git remote add origin https://gitlab.example.com/components/golang.git git push - 模板名称应与
- 把 CI/CD 作业创建为模板,先从
build作业开始。- 在
spec部分定义以下输入:stage、golang_version和binary_directory。 - 添加访问
inputs.golang_version的动态作业名称定义。 - 使用类似模式,通过访问
inputs.golang_version动态指定 Go 镜像版本。 - 将阶段设为
inputs.stage的值。 - 根据
inputs.binary_directory创建二进制文件目录,并将其作为参数传给go build。 - 将制品路径定义为
inputs.binary_directory。
spec: inputs: stage: default: 'build' description: 'Defines the build stage' golang_version: default: 'latest' description: 'Go image version tag' binary_directory: default: 'mybinaries' description: 'Output directory for created binary artifacts' --- "build-$[[ inputs.golang_version ]]": image: golang:$[[ inputs.golang_version ]] stage: $[[ inputs.stage ]] script: - mkdir -p $[[ inputs.binary_directory ]] - go build -o $[[ inputs.binary_directory ]] ./... artifacts: paths: - $[[ inputs.binary_directory ]]format作业模板遵循相同模式,但只需要stage和golang_version输入。
spec: inputs: stage: default: 'format' description: 'Defines the format stage' golang_version: default: 'latest' description: 'Golang image version tag' --- "format-$[[ inputs.golang_version ]]": image: golang:$[[ inputs.golang_version ]] stage: $[[ inputs.stage ]] script: - go fmt $(go list ./... | grep -v /vendor/) - go vet $(go list ./... | grep -v /vendor/)test作业模板遵循相同模式,但只需要stage和golang_version输入。
spec: inputs: stage: default: 'test' description: 'Defines the format stage' golang_version: default: 'latest' description: 'Golang image version tag' --- "test-$[[ inputs.golang_version ]]": image: golang:$[[ inputs.golang_version ]] stage: $[[ inputs.stage ]] script: - go test -race $(go list ./... | grep -v /vendor/) - 在
- 要测试组件,请修改
.gitlab-ci.yml配置文件,并添加测试。- 为
build作业的golang_version输入指定一个不同的值。 - 把 URL 修改为你的 CI/CD 组件路径。
stages: [format, build, test] include: - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/format@$CI_COMMIT_SHA - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/build@$CI_COMMIT_SHA - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/build@$CI_COMMIT_SHA inputs: golang_version: "1.21" - component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/test@$CI_COMMIT_SHA inputs: golang_version: latest - 为
- 添加 Go 源代码以测试 CI/CD 组件。
go命令要求 Go 项目的根目录包含go.mod和main.go。- 初始化 Go 模块。把 URL 修改为你的 CI/CD 组件路径。
go mod init example.gitlab.com/components/golang- 创建包含 main 函数的
main.go文件,例如打印Hello, CI/CD component。可以使用代码注释,让 GitLab Duo Code Suggestions 生成 Go 代码。
// Specify the package, import required packages // Create a main function // Inside the main function, print "Hello, CI/CD Component" package main import "fmt" func main() { fmt.Println("Hello, CI/CD Component") }- 目录树应如下所示:
tree . ├── LICENSE.md ├── README.md ├── go.mod ├── main.go └── templates ├── build.yml ├── format.yml └── test.yml
按照将 CI/CD 模板转换为组件一节中的其余步骤完成迁移:
- 提交并推送更改,验证 CI/CD 流水线的结果。
- 按照编写组件的指南更新
README.md和LICENSE.md文件。 - 发布组件并在 CI/CD 目录中验证它。
- 将 CI/CD 组件加入预发布或生产环境。
GitLab 维护的 Go 组件展示了从 Go CI/CD 模板成功迁移的示例,并结合输入参数和组件最佳实践进行了增强。可以查看 Git 历史了解更多信息。











暂无评论内容