コンテンツにスキップ

Pants でリモートキャッシュを使う

Pantsはビルドシステムで、ビルドやテストを高速化する手段の 1 つにリモートキャッシュがあります。本記事では、bazel-remoteを使ってキャッシュを S3 や GCS へ保存する設定手順と、GitHub Actions での実行例を紹介します。

Pants のリモートキャッシュ

Pants はコマンドを実行すると中間生成物を生成します。Pants のリモートキャッシュは、この中間生成物を中央管理のリモート環境に配置してキャッシュします。Bazel のリモートキャッシュと同様の仕組みです。

bazel-remote のコンテナイメージを使う例

bazel-remoteは、S3 や GCS などのストレージにキャッシュを保存できます。Pants 公式の CI でも bazel-remote を使って S3 にキャッシュを保存しており、設定はPants の GitHub Actions ワークフロー定義で確認できます。

buchgr が bazel-remote を Docker イメージとしても配布しているので、GitHub Actions などの CI 環境でも簡単に利用できます。

GitHub Actions での bazel-remote 起動

次の例では、bazel-remote の Docker イメージを GitHub Actions 上で detach mode で実行し、起動したコンテナが Pants のビルドキャッシュをローカルディスクと S3 の両方に保持します。AWS 用のオプションを bazel-remote の実行時に渡していますが、設定用ファイルに記述して実行時に読み込ませることもできます。

(以下に記載されている AWS 認証情報は GitHub で公開されています)

build-support/bin/generate_github_workflows.py
            "run": dedent(
                """\
                mkdir -p ~/bazel-remote
                if [[ -z "${AWS_ACCESS_KEY_ID}" ]]; then
                  CACHE_WRITE=false
                  # If no secret read/write creds, use hard-coded read-only creds, so that
                  # cross-fork PRs can at least read from the cache.
                  # These creds are hard-coded here in this public repo, which makes the bucket
                  # world-readable. But since putting raw AWS tokens in a public repo, even
                  # deliberately, is icky, we base64-them. This will at least help hide from
                  # automated scanners that look for checked in AWS keys.
                  # Not that it would be terrible if we were scanned, since this is public
                  # on purpose, but it's best not to draw attention.
                  AWS_ACCESS_KEY_ID=$(echo 'QUtJQVY2QTZHN1JRVkJJUVM1RUEK' | base64 -d)
                  AWS_SECRET_ACCESS_KEY=$(echo 'd3dOQ1k1eHJJWVVtejZBblV6M0l1endXV0loQWZWcW9GZlVjMDlKRwo=' | base64 -d)
                else
                  CACHE_WRITE=true
                fi
                docker run --detach -u 1001:1000 \
                  -v ~/bazel-remote:/data \
                  -p 9092:9092 \
                  buchgr/bazel-remote-cache:v2.4.1 \
                  --s3.auth_method=access_key \
                  --s3.access_key_id="${AWS_ACCESS_KEY_ID}" \
                  --s3.secret_access_key="${AWS_SECRET_ACCESS_KEY}" \
                  --s3.bucket=cache.pantsbuild.org \
                  --s3.endpoint=s3.us-east-1.amazonaws.com \
                  --max_size 30
                echo "PANTS_REMOTE_STORE_ADDRESS=grpc://localhost:9092" >> "$GITHUB_ENV"
                echo "PANTS_REMOTE_CACHE_READ=true" >> "$GITHUB_ENV"
                echo "PANTS_REMOTE_CACHE_WRITE=${CACHE_WRITE}" >> "$GITHUB_ENV"
                """
            ),
            "env": {
                "AWS_ACCESS_KEY_ID": f"{gha_expr('secrets.AWS_ACCESS_KEY_ID')}",
                "AWS_SECRET_ACCESS_KEY": f"{gha_expr('secrets.AWS_SECRET_ACCESS_KEY')}",
            },

GCS の例

1
2
3
4
mkdir -p ~/bazel-remote
chmod 777 ~/bazel-remote # これしないと、docker run できなかったかった

docker run -u 1000:1000 -v ~/bazel-remote:/data -p 9092:9092 buchgr/bazel-remote-cache --max_size 3 --gcs_proxy.bucket=foo_bar --gcs_proxy.use_default_credentials=true

GCS の場合、--gcs_proxy.use_default_credentials=trueを指定すると GCP のデフォルトの認証情報を使い、--gcs_proxy.json_credentials_file=xxxを指定すると JSON ファイルから認証情報を読み込みます。

--max_size 3のオプションで、キャッシュのサイズを 3 GiB に制限しています。

.pants.rc
1
2
3
4
[GLOBAL]
remote_cache_read = true
remote_cache_write = true
remote_store_address = "grpc://localhost:9092"

10 分かかっていたテストが 2 分になりました。

bazel-remote のバイナリを使う例

バイナリを使う例はdistroless の release.shです。コンテナイメージを使う際に、Google Cloud の Credential の指定がうまくできませんでしたが、バイナリを使うと、同じオプションでうまく認証できました。