GitLab CI/CD - ハンズオンラボ: ルールと変更のマージ
完了までの推定時間: 15 分
はじめに
自動ビルドを正常に実装した後、Tanuki Enterprises のチームは新しい問題を発見しました。コードをコミットするたびにパイプライン全体がトリガーされます。これには本番リリースを作成するリリースジョブも含まれます。これにより:
- 早まったリリース: 開発ブランチの実験的な機能が本番リリースを誤ってトリガーする
- リソースの無駄: 作業中のコードでも、小さなコミットのたびにビルドとテストのジョブが実行される
- 品質ゲートがない: マージリクエストで適切な検証を経ずに、コードが直接 main にマージされる
- パイプラインの混乱: リリースジョブがタグを作成し、それがさらにパイプラインをトリガーして無限ループが発生する
- コンテキストの喪失: どのパイプライン実行がマージリクエストに関連しているかを開発者が簡単に確認できない
目標
このラボでは、CI/CD パイプラインが実行されるタイミングと方法を制御するために、ワークフロールールとマージリクエストパイプラインを実装します。開発ワークフローと本番リリースを区別する方法を学び、コード変更のコンテキストに基づいて適切なタイミングで適切なジョブが実行されるようにします。
タスク A. ワークフロールール
ビルドプロセスが完成したので、コードに変更を加え始めることができます。ほとんどの変更はマージリクエストで行われます。マージリクエストのブランチでコードが変更されると、そのマージリクエストに対してパイプラインを実行するのが理想的です。これにより、すべてのコード変更が本番環境に対応した状態になり、変更を本番環境にマージしやすくなります。パイプラインをセットアップして設定するいくつかの方法を見ていきましょう。
ワークフロールールを使用すると、パイプラインが実行されるタイミングを制御できます。これらのルールにより、CI/CD パイプライン全体の実行フローを制御できます。たとえば、現在の .gitlab-ci.yml ファイルを見てみましょう:
default:
image: golang
stages:
- build
- run
build go:
stage: build
script:
- go build
artifacts:
paths:
- array
run go:
stage: run
script:
- ./array
現在のプロジェクトコードに基づいてリリースを追加する新しいジョブを導入しましょう。
GitLab はプロジェクトのリリースを Deploy > Releases セクションで追跡します。新しいリリースを作成するには Build > Pipeline Editor を選択します。
パイプラインエディターで
releaseジョブをstagesに追加します:stages: - build - run - releaserun goジョブの下に release ステージの新しいジョブを追加します:release go: stage: release script: - echo "Generating the latest Tanuki App release!"リリースジョブには特別な CLI ツールが必要です。必要なツールを含むイメージをリリースジョブに追加します:
release go: stage: release image: registry.gitlab.com/gitlab-org/release-cli:latest script: - echo "Generating the latest Tanuki App release!"リリースを作成するには、リリースの
tag_nameとdescriptionを指定する必要があります。一意のバージョン番号を生成するために、組み込み変数CI_PIPELINE_IIDを使用します。この変数には現在のパイプラインのプロジェクトレベルの ID が含まれます。release jobのscriptの下に release キーワードを追加します:image: registry.gitlab.com/gitlab-org/release-cli:latest script: - echo "Generating the latest Tanuki App release!" release: tag_name: 'v0.$CI_PIPELINE_IID' description: 'The latest release!'ジョブは次のようになります:
release go: stage: release image: registry.gitlab.com/gitlab-org/release-cli:latest script: - echo "Generating the latest Tanuki App release!" release: tag_name: 'v0.$CI_PIPELINE_IID' description: 'The latest release!'リリースジョブが実行されると、リポジトリにタグが作成されます。タグの作成はデフォルトでパイプラインの実行をトリガーします。これにより、パイプラインが完了するたびに新しいタグが作成され、新しいパイプラインがトリガーされるという無限ループが生じます。
無限ループを防ぐために、新しいコミットタグが追加されたときにパイプラインがトリガーされないようにするワークフローを使用できます。
.gitlab-ci.ymlファイルの先頭に次のワークフローを定義します:workflow: rules: - if: $CI_COMMIT_TAG when: never - when: alwaysCommit changes を選択します。
このルールはパイプライン全体に適用されます。
CI_COMMIT_TAGが存在する場合、if 文が true と評価され、パイプラインは実行されません。CI_COMMIT_TAGが存在しない場合、パイプラインが実行されます。特定の
CI_COMMIT_TAGの値を検索して、リリースの場合のみ実行を停止することもできます。この場合、v0.*の形式のタグはリリースの一部なので、この特定のパターンを検索できます。
タスク B. マージリクエストパイプライン
新しいリリースジョブについて考慮すべきもう一つの点は、リリースを作成するジョブが実行されるタイミングです。現在、このジョブはすべてのコミットで実行されます。しかし、理想的には main または default ブランチへのコミットでのみ実行されることを望みます。これを実現するために、マージリクエストパイプラインを実装できます。
マージリクエストパイプラインは、オープンなマージリクエストのあるブランチに変更を加えるたびに実行されます。マージリクエストのフローを制御することで、変更が完全にマージされるまでリリースが実行されないようにできます。
マージリクエストで実行されるジョブを定義するために、ジョブに rules の定義を追加します。追加するルールは CI_PIPELINE_SOURCE が merge_request_event かどうかを確認します。
Build > Pipeline Editor を選択してパイプラインエディターで
.gitlab-ci.ymlファイルを開きます。build goとrun goジョブのscriptの下に次のルールを追加します:rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event'このルールが 2 スペースでインデントされていることを確認してください。
scriptキーワードと同じ位置に揃える必要があります。build および run ジョブは次のようになります:
build go: stage: build script: - go build artifacts: paths: - array rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event' run go: stage: run script: - ./array rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event'これで、build と run ジョブはパイプラインがマージリクエストの一部である場合にのみ実行されます。
次に、ルールを否定することでマージリクエストでリリースジョブが実行されないようにします。
release jobの script の下に次のルールを追加します:rules: - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCHこれが
scriptキーワードと同じレベル(2 スペース)にインデントされていることを確認してください。リリースジョブは次のようになります:
release go: stage: release image: registry.gitlab.com/gitlab-org/release-cli:latest script: - echo "Generating the latest Tanuki App release!" release: tag_name: 'v0.$CI_PIPELINE_IID' description: 'The latest release!' rules: - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCHこれらの変更を加えたら Commit changes を選択して
.gitlab-ci.ymlファイルを更新します。main にコミットすると、Build > Pipelines を選択して実行中のジョブを確認します。コミットが
mainで実行されたため、リリースジョブのみが実行されることに気づくでしょう。他のジョブを実行するためにマージリクエストを作成しましょう。
Code > Branches に移動します。
New Branch を選択します。
任意のブランチ名を入力して Create Branch を選択します。
Code > Merge requests を選択します。
New Merge Request を選択します。
作成したブランチをソースブランチとして選択します。
Compare branches and continue を選択します。
すべてのオプションをデフォルトのままにして Create Merge Request を選択します。
マージリクエストパイプラインをトリガーするには、コードに何らかの変更を加える必要があります。
Code > Open in Web IDE を選択します。
README.mdファイルを選択して、ファイル内の任意の内容を変更します。完了したら、Source Control > Commit and push を選択します。
画面の右下に表示されるポップアップから Go to MR を選択してマージリクエストに戻ります。
Build > Pipelines に移動します。マージリクエストのラベルが付いた新しいパイプラインが表示されます。
それを選択して進捗を確認します。
.gitlab-ci.ymlファイルで指定した build と run の 2 つのジョブが実行されているのが確認できます。Code > Merge Requests を選択してマージリクエストに戻ります。
マージリクエストを選択します。マージリクエストパイプラインというセクションが表示されています。このセクションはマージリクエストパイプラインの進捗を示します。
まとめ
ワークフロールールとマージリクエストパイプラインの導入により、Tanuki Enterprises の CI/CD プロセスがカオスから制御された状態に変わりました。ワークフロールールはリリースタグでパイプラインがトリガーされるのを防ぐことで無限ループの問題を解消し、マージリクエストパイプラインはビルドとテストのジョブがアクティブな開発作業にのみ実行され、main へのすべてのコミットでは実行されないことを保証します。最も重要なのは、リリースジョブが main ブランチでのみ実行されるようになり、フィーチャーブランチからの本番リリースの誤ったトリガーが防止されました。
ラボガイド完了
このラボ演習が完了しました。このコースの他のラボガイドを参照できます。
ご提案について
ラボに変更を加えたい場合は、マージリクエスト経由で変更を送信してください。
