こんにちは!

松田です!
寒暖差についていけておりませんでしたが、いよいよ風邪をひきました。

本投稿について

CodeシリーズのCI/CDパイプラインにおいて、
複数のレポジトリから単一のビルド成果物を得たい(コンテナイメージなど)場合、ビルド環境からどうやってそれぞれのレポジトリにアクセスすれば良いか
についてまとめます。

結論だけ知りたい人は、末尾の結論だけご参照ください!

経緯

先日、AWS Codeシリーズを利用して、CI/CDパイプラインの設計/実装を行いました。
そのパイプラインにて、2つのレポジトリからそれぞれでビルド処理などを行い、1つのコンテナイメージにする必要がありました。

雑ですが、以下の図がやりたいことのイメージです。

1つのレポジトリからビルドなどを行って、それを1つのコンテナイメージにして、ECRにプッシュして…..というパイプラインは今までいくつも作ってきました。
イメージの元になるレポジトリが2つというパイプライン構成は、今回が初めてでした。

ひとまず、以下のようなステージ、アクション構成にしました。

SourceステージとBuildステージをそれぞれ作成して、Sourceステージには各CodeCommitレポジトリごとにSourceアクションを定義し、Buildステージは1つのBuildアクションのみを設けてその中で各レポジトリのビルドやdocker buildなどを行います。
そしてbuildspec.ymlを作成していたところ、「あれ?それぞれのレポジトリのファイルってどのパスにあるんだ?」という疑問が生まれました。

結論から申し上げますが、ビルド環境の環境変数を利用すれば良いです。
ドキュメント(ユーザーガイド)に記載されています。しかしドキュメントをきちんと読む前に、独自に確認してしまいました。
その確認の過程についても記載いたします。

パイプライン構成(詳細)

もう少しだけパイプライン構成について補足します。

パイプライン全体のステージとアクション構成は以下の通りです。(本記事ではAWSリソースに対する操作はマネジメントコンソールから行っています)

Sourceステージのアクションは2つあり、それぞれ別のCodeCommitレポジトリに紐づいている形です。

1つ目のレポジトリはバックエンドのコードを管理するレポジトリです。
ここでは出力アーティファクトを「backend」と定義しています。

2つ目のレポジトリはフロントエンドのコードを管理するレポジトリです。
ここでは出力アーティファクトを「frontend」と定義しています。

Buildアクションでは入力アーティファクトを「backend」と「frontend」としています。
これによりビルド環境からSourceアクションで指定した各レポジトリにアクセス可能になります。
またPrimarySourceというパラメータがあり、これを「backend」としています。

確認してみた

パイプラインを実装したのでbuildspec.ymlを作成していましたが、「あれ?ビルド環境のカレントディレクトリってどこになるんだ?」や「それぞれのレポジトリのパスってどこだ?」という疑問が出てきました。
そこでbuildspec.ymlに調査用コマンドを埋め込み、実行して確認しました。

まず、シンプルに現在のカレントディレクトリを確認しました。

- pwd
- ls

pwdコマンドの実行結果は以下の通りでした。

[Container] 2024/10/18 04:00:19.174681 Running command pwd
/codebuild/output/src1981/src/s3/00

s3ディレクトリ内の最初の通し番のディレクトリがカレントディレクトリになっているようです。
lsコマンドで中身を確認しましたが、backendのレポジトリでした。カレントディレクトリはbackendレポジトリのルートのようです。
おそらくBuildアクションのPrimarySourceに指定した入力アーティファクトに紐づいていると思われます。

次に以下のコマンドを実行しました。

- cd ..
- ls -lR
.s3:
total 0
drwxr-xr-x 3 root root 137 Oct 18 03:59 00
drwxr-xr-x 4 root root 309 Oct 18 03:59 01

s3ディレクトリ配下には00と01の2つのディレクトリがあるようです。
そして00はbackendのディレクトリで、01はfrontendのディレクトリであることが確認できました。

確認できたことをまとめると

  • カレントディレクトリはPrimarySourceに指定したアーティファクトに紐づく
  • Buildアクションで指定した入力アーティファクトは/codebuild/output/src1981/src/s3/配下に00からはじまるディレクトリとして置かれていく

「/codebuild/output/src1981/src/s3/00」と「/codebuild/output/src1981/src/s3/01」がbackendとfrontendのレポジトリに該当するパスになるため、このパスを直接利用すればいいのか?と考えましたが、src1981という一意じゃなさそうな値が含まれているパスを直接利用するのは困難だと思いました。
相対パスを指定するのもイマイチだなと思い、ここでようやくドキュメントをちゃんと読むことにしました。

ドキュメントを読んだ

One of your input sources must be designated the PrimarySource. This source is the directory where CodeBuild looks for and runs your buildspec file. The keyword PrimarySource is used to specify the primary source in the configuration section of the CodeBuild stage in the JSON file.

https://docs.aws.amazon.com/codebuild/latest/userguide/sample-codepipeline.html#sample-pipeline-multi-input-output
PrimarySourceで指定するソースはbuildspec fileを配置するソースとのことです。このことから、ビルド環境のカレントディレクトリはこのソースのルートになるで間違いないと考えられます。

CODEBUILD_SRC_DIR
The directory path that CodeBuild uses for the build (for example, /tmp/src123456789/src).
For secondary sources, the environment variable for the secondary source directory path is CODEBUILD_SRC_DIR_(sourceIdentifier), where (sourceIdentifier) is the source identifier you create. For more information, see Multiple input sources and output artifacts sample.

https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html
CODEBUILD_SRC_DIRという環境変数に、ソースのディレクトリパスが定義されている。そして2つ目以降のソースのディレクトリパスはCODEBUILD_SRC_DIR_(入力アーティファクト名)という環境変数に定義される。
とのことです。

試しにbuildspec.ymlにてenvコマンドを仕込んで確認してみました。

[Container] 2024/10/18 04:35:53.474956 Running command env | grep CODEBUILD_SRC
CODEBUILD_SRC_DIR=/codebuild/output/src3799/src/s3/00
CODEBUILD_SRC_DIR_frontend=/codebuild/output/src3799/src/s3/00

ありますね!
そのため、この変数を利用してそれぞれのレポジトリにアクセスすれば良さそうです!
(srcXXXXの通し番号はやはり一意ではなく、ビルドの実行ごとに採番されるようです)

結論

  • ビルド環境においてソース(レポジトリ)のパスは環境変数CODEBUILD_SRC_DIRもしくはCODEBUILD_SRC_DIR_(入力アーティファクト名)に定義されている
  • 最初からオフィシャルなドキュメントを読もう

今年の目標はドキュメントドリブンの徹底です。以上です。