CI/CD 组件示例
- 版本: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: '定义构建阶段' rust_version: default: latest description: '指定 Rust 版本,使用 https://hub.docker.com/_/rust/tags 中的值,默认为 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: # 包含位于当前项目当前 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: '定义测试阶段' rust_version: default: latest description: '指定 Rust 版本,使用 https://hub.docker.com/_/rust/tags 中的值,默认为 latest' --- "test-$[[ inputs.rust_version ]]": stage: $[[ inputs.stage ]] image: rust:$[[ inputs.rust_version ]] script: - cargo test --verbose -
通过包含
test组件模板来在管道中测试额外的作业:include: # 包含位于当前项目当前 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: '如果设置为 `true`,则配置复杂的缓存行为'
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: ... # 运行一些高级工具这种模式通过将 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 来实现任意数量的条件。
例如,使用 3 个不同的选项来配置复杂的缓存行为:
spec:
inputs:
cache_mode:
description: 定义此组件使用的缓存模式
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: ... # 运行一些高级工具在此示例中,cache_mode 输入提供了 default、aggressive 和 relaxed 选项,
每个选项对应一个不同的隐藏作业。
通过使用 extends: '.my-component:cache_mode:$[[ inputs.cache_mode ]]' 扩展组件作业,
作业会根据所选选项动态继承正确的缓存配置。
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对于更渐进的方法,一次迁移一个作业。
从 build 作业开始,然后重复 format 和 test 作业的步骤。
CI/CD 模板迁移涉及以下步骤:
-
分析 CI/CD 作业和依赖关系,并定义迁移操作:
image配置是全局的,需要移到作业定义中。format作业在一个作业中运行多个go命令。go test命令应该移到单独的作业中以提高管道效率。compile作业运行go build,应该重命名为build。
-
定义优化策略以提高管道效率。
stage作业属性应该是可配置的,以允许不同的 CI/CD 管道使用者。image键使用硬编码的镜像标签latest。添加golang_version作为输入, 默认值为latest,以实现更灵活和可重用的管道。该输入必须匹配 Docker Hub 镜像标签值。compile作业将二进制文件构建到硬编码的目标目录mybinaries, 可以通过动态 input 和默认值mybinaries来增强。
-
为新组件创建模板 目录结构, 基于每个作业一个模板。
- 模板名称应遵循
go命令,例如format.yml、build.yml和test.yml。 - 创建新项目,初始化 Git 仓库,添加/提交所有更改,设置远程源并推送。 修改你的 CI/CD 组件项目路径的 URL。
- 按照 编写组件 的指导创建其他文件:
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。 -
使用类似的模式来动态设置 Go 镜像版本,访问
inputs.golang_version。 -
将阶段分配给
inputs.stage值。 -
从
inputs.binary_directory创建二进制目录,并将其作为参数添加到go build。 -
将 artifacts 路径定义为
inputs.binary_directory。spec: inputs: stage: default: 'build' description: '定义构建阶段' golang_version: default: 'latest' description: 'Go 镜像版本标签' binary_directory: default: 'mybinaries' description: '创建的二进制文件输出目录' --- "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: '定义格式化阶段' golang_version: default: 'latest' description: 'Golang 镜像版本标签' --- "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: '定义测试阶段' golang_version: default: 'latest' description: 'Golang 镜像版本标签' --- "test-$[[ inputs.golang_version ]]": image: golang:$[[ inputs.golang_version ]] stage: $[[ inputs.stage ]] script: - go test -race $(go list ./... | grep -v /vendor/)
-
-
为了测试组件,修改
.gitlab-ci.yml配置文件, 并添加 tests。-
为
build作业指定不同的golang_version值作为输入。 -
修改你的 CI/CD 组件路径的 URL。
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.mod和main.go的 Go 项目。-
初始化 Go 模块。修改你的 CI/CD 组件路径的 URL。
go mod init example.gitlab.com/components/golang -
创建一个包含主函数的
main.go文件,例如打印Hello, CI/CD component。 你可以使用代码注释通过 GitLab Duo Code Suggestions 生成 Go 代码。// 指定包,导入所需的包 // 创建主函数 // 在主函数内打印 "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 历史记录以了解更多信息。