CI/CDコンポーネントの例
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
コンポーネントをテストする
コンポーネントの機能によっては、コンポーネントをテストするために、リポジトリに追加ファイルが必要になる場合があります。たとえば、特定のプログラミング言語でソフトウェアをlint、ビルド、テストするコンポーネントには、実際のソースコードのサンプルが必要です。ソースコードの例、設定ファイルなどを同じリポジトリに配置できます。
たとえば、コード品質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.ymlRustソースコードをビルドするジョブがコンポーネントに含まれていることを確認します。その例として、以下に
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コードに関数とテストを追加し、
cargo testを実行するコンポーネントテンプレートとジョブをtemplates/test.ymlに追加します。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 --verbosetestコンポーネントテンプレートを含めることで、パイプラインで追加のジョブをテストします: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機能を組み合わせることで、2つの条件分岐を持つジョブを構成できます。
たとえば、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このパターンは、ジョブのextendsキーワードにenable_special_caching入力を渡すことによって機能します。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: 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 ]]'でコンポーネントジョブを拡張することにより、ジョブは選択されたオプションに基づいて正しいキャッシュ設定を動的に継承します。
バージョニングされた参照リソースを参照するためにコンポーネントコンテキストを使用します
ジョブの参照、コミットSHAなどのコンポーネントメタデータを参照するには、コンポーネントコンテキストCI/CD式を使用します。1つのユースケースは、コンポーネントでバージョニングされたリソース(Dockerイメージなど)をビルドおよび公開し、コンポーネントが一致するバージョンを使用するようにすることです。
たとえば、次のことができます:
- コンポーネントのバージョンに一致するタグを使用して、コンポーネントのリリースパイプラインで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のDockerイメージを使用します。 - コンポーネントを
@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より段階的なアプローチとして、一度に1つのジョブを移行します。まずbuildジョブから始め、その後formatジョブ、testジョブの順に同じ手順を繰り返します。
CI/CDテンプレートを移行するには、次の手順を実行します:
CI/CDジョブと依存関係を分析し、移行アクションを定義します:
image設定はグローバルであるため、ジョブ定義に移動する必要があります。formatジョブは、1つのジョブで複数のgoコマンドを実行します。パイプラインの効率性を高めるために、go testコマンドは別のジョブに移動する必要があります。compileジョブはgo buildを実行しているため、buildに名前を変更する必要があります。
パイプラインの効率性を向上させるための最適化戦略を定義します。
- さまざまなCI/CDパイプラインの利用者が活用できるように、
stageジョブ属性は設定可能でなければなりません。 imageキーは、ハードコーディングされたイメージタグlatestを使用します。より柔軟で再利用可能なパイプラインにするため、latestをデフォルト値とするgolang_versionを入力として追加します。入力は、Docker Hubのイメージタグの値と一致する必要があります。compileジョブは、バイナリをハードコーディングされたターゲットディレクトリmybinariesにビルドします。これは、mybinariesをデフォルト値とする動的な入力として拡張できます。
- さまざまなCI/CDパイプラインの利用者が活用できるように、
ジョブごとに1つのテンプレートを基にして、新しいコンポーネントのテンプレート用ディレクトリ構造を作成します。
- テンプレートの名前は、
goコマンドに従う必要があります(例:format.yml、build.yml、test.yml)。 - 新しいプロジェクトを作成し、Gitリポジトリを初期化し、すべての変更を追加/コミットし、リモートoriginを設定してプッシュします。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にアクセスして、動的なジョブ名の定義を追加します。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に別の値を指定します。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
CI/CDコンポーネントをテストするためのGoソースコードを追加します。
goコマンドは、ルートディレクトリにgo.modとmain.goを含むGo言語プロジェクトを想定しています。Goモジュールを初期化します。CI/CDコンポーネントのパスに合わせてURLを変更します。
go mod init example.gitlab.com/components/golangたとえば、
Hello, CI/CD componentを出力するmain関数を持つmain.goファイルを作成します。コードコメントを使用して、GitLab Duoコード提案で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コンポーネントをstagingステージ/本番環境に追加します。
GitLabが管理するGoコンポーネントは、Go CI/CDテンプレートからの移行の成功例を示しており、入力とコンポーネントのベストプラクティスによって強化されています。詳細については、Gitの履歴をご覧ください。