公開:2024年7月30日

1分で読めます

モノレポ用のGitLab CI/CDパイプラインを簡単に構築する方法

単一のリポジトリで複数のアプリケーションをホストするモノレポ用に、GitLab CI/CDパイプラインを作成する方法についてご紹介します。

モノレポを使用すると、単一のリポジトリで複数のアプリケーションのコードをホストできます。GitLabでこれを実現しようとすると、プロジェクト内の各ディレクトリに異なるアプリケーションのソースコードを配置することになります。この方法だとコードの保存場所をバージョン管理できるものの、GitLabのCI/CDパイプライン機能を最大限に活用するのは困難でした。しかしながら、新たな方法が登場しました!

モノレポにおけるCI/CDの理想的な実例

通常、リポジトリには複数のアプリケーションのコードが格納されているため、複数のパイプライン設定が必要となります。たとえば、.NETアプリケーションとSpringアプリケーションがあるプロジェクトの場合、アプリケーションごとに異なるビルドジョブとテストジョブを実施している可能性があります。この場合、パイプラインを完全に切り離し、特定のアプリケーションのソースコードの変更が発生した場合のみ、各パイプラインを実行するのが理想的です。

このようなプロセスを技術的に実現するには、特定のディレクトリの変更に基づいて特定のYAMLファイルをインクルードする、プロジェクトレベルのパイプライン設定ファイル.gitlab-ci.ymlを用意します。.gitlab-ci.ymlパイプラインは、コードに加えられた変更に基づき、適切なパイプラインをトリガーするコントロールプレーンとして機能します。

従来のアプローチ

GitLab 16.4より前のバージョンでは、プロジェクト内のディレクトリまたはファイルへの変更に基づいてYAMLファイルをインクルードすることはできませんでした。ただし、回避策を使えばこの機能を実現することは可能でした。

これからご紹介するモノレポプロジェクトの例では、異なるアプリケーション用に2つのディレクトリがあるとします。それぞれJavaアプリ用のjavaディレクトリとPythonアプリ用のpythonディレクトリがあります。それぞれのディレクトリには、各アプリをビルドするためのアプリケーション固有のYAMLファイルが含まれています。シンプルにプロジェクトのパイプラインファイルに両アプリケーションのパイプラインファイルをインクルードし、それらのファイルで直接ロジック処理を行います。

.gitlab-ci.yml

stages:
  - build
  - test
  - deploy

top-level-job:
  stage: build
  script:
    - echo "Hello world..."

include:
  - local: '/java/j.gitlab-ci.yml'
  - local: '/python/py.gitlab-ci.yml'

アプリケーション固有の各パイプラインファイルで「.java-common」もしくは「.python-common」という名前の非表示ジョブを作成します。これらのジョブは対応するアプリのディレクトリに変更が加えられた場合にのみ実行されます。デフォルトでは非表示ジョブは実行されず、通常は特定のジョブ設定を再利用するために使用されます。各パイプラインは、非表示ジョブを拡張して変更がないか監視するファイルを定めたルールを継承してから、パイプラインジョブを開始します。

j.gitlab-ci.yml

stages:
  - build
  - test
  - deploy

.java-common:
  rules:
    - changes:
      - '../java/*'

java-build-job:
  extends: .java-common
  stage: build
  script:
    - echo "Javaのビルド"

java-test-job:
  extends: .java-common
  stage: test
  script:
    - echo "Javaのテスト"

py.gitlab-ci.yml

stages:
  - build
  - test
  - deploy

.python-common:
  rules:
    - changes:
      - '../python/*'

python-build-job:
  extends: .python-common
  stage: build
  script:
    - echo "Pythonのビルド"

python-test-job:
  extends: .python-common
  stage: test
  script:
    - echo "Pythonのテスト"

この方法にはいくつかのデメリットがあります。たとえば、確実にルールに準拠するために、YAMLファイル内の他のジョブ用にそれぞれジョブを拡張しなければならないため、多くの冗長なコードが発生し、ヒューマンエラーが起きやすくなります。さらに拡張されたジョブでは重複するキーは持てないため、各ジョブにおいて独自のrulesロジックを定義できません。定義しようとした場合、キーの競合が発生し、キーの値はマージされません

結果として、java/が更新されると、j.gitlab-ci.ymlジョブを含むパイプラインが実行され、python/が更新されると、py.gitlab-ci.ymlジョブを含むパイプラインが実行されます。

新たなアプローチ:パイプラインファイルを条件付きでインクルードする

GitLab 16.4では、パイプライン向けにrules:changesを含むincludeが導入されました。それまではincluderules:ifを使用することはできたものの、rules:changesは使用できませんでした。これは非常に強力なアップデートです。これにより、プロジェクトのパイプライン設定でincludeキーワードを使用するだけで、モノレポのルールを定義できるようになりました。

新たな.gitlab-ci.yml

stages:
  - build
  - test

top-level-job:
  stage: build
  script:
    - echo "Hello world..."

include:
  - local: '/java/j.gitlab-ci.yml'
    rules:
      - changes:
        - 'java/*'
  - local: '/python/py.gitlab-ci.yml'
    rules:
      - changes:
        - 'python/*'

その後、各アプリケーションのYAMLファイルにおいて非表示ジョブを何度も拡張せずに済むため、アプリケーションコードのビルドとテストだけに集中できます。これによって、より柔軟にジョブを定義できるようになり、エンジニアによるコードの書き直し作業が軽減します。

新たなj.gitlab-ci.yml

stages:
  - build
  - test
  - deploy

java-build-job:
  stage: build
  script:
    - echo "Javaのビルド"

java-test-job:
  stage: test
  script:
    - echo "Javaのテスト"

新たなpy.gitlab-ci.yml

stages:
  - build
  - test
  - deploy

python-build-job:
  stage: build
  script:
    - echo "Pythonのビルド"

python-test-job:
  stage: test
  script:
    - echo "Pythonのテスト"

上記の設定により、JavaとPythonのディレクトリがそれぞれ変更された場合にのみ、JavaまたはPythonのジョブをインクルードするという同じタスクを実行できます。実装時に考慮すべき点は、changesを使用すると、ジョブが予期せぬタイミングで実行される可能性があるということです。新しいブランチやタグをGitLabにプッシュすると、changesルールは必ず「true」と評価されるため、rules:changesの定義内容にかかわらず、ブランチへの最初のプッシュ時に、含まれるすべてのジョブが実行されます。こういった事態がなるべく起こらないようにするために、まずはフィーチャーブランチを作成してからマージリクエストを開いて開発を始めることをおすすめします。ブランチの作成時に最初にプッシュすることで、すべてのジョブが強制的に実行されるためです。

総括すると、モノレポはGitLabおよびCI/CDと組み合わせて、戦略的に利用できる手法です。新たなrules:changes機能を含むincludeキーワードの登場により、GitLab CIにおいてモノレポを使う際に適用できる優れたベストプラクティスができました。モノレポの利用をお考えの場合は、ぜひGitlab Ultimateの無料トライアルをご利用ください。

CI/CDに関するその他のリソース

ご意見をお寄せください

このブログ記事を楽しんでいただけましたか?ご質問やフィードバックがあればお知らせください。GitLabコミュニティフォーラムで新しいトピックを作成して、ご意見をお聞かせください。

フォーチュン100企業の50%以上がGitLabを信頼

より優れたソフトウェアをより速く提供

インテリジェントなDevSecOpsプラットフォームで

チームの可能性を広げましょう。