GitHub Enterprise の Actions で依存関係を S3 にキャッシュする
Thursday, May 05, 2022 11:35:00 AM
GitHub の Actions で npm などの依存関係パッケージをキャッシュするのは、公式ドキュメント 依存関係をキャッシュしてワークフローのスピードを上げる にも書いてあるように、 CIを高速化するのに重要です。
公式 Example だと以下のとおりです。
name: Caching with npm
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cache node modules
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm install
- name: Build
run: npm build
- name: Test
run: npm test
actions/cache
を利用すれば問題なく動くのですが、Enterprise 版の場合は runs-on
にセルフホストランナーを利用するので、キャッシュがホストランナーのディスクに依存してしまいます。
これだとホストランナーのディスク管理とか大変になるので、少し管理で楽をしたいな、と思ったところ S3 にキャッシュできるものがあり、現在もこれを利用しています。
actions-s3-cache
actions-s3-cache は名前のとおり依存関係のキャッシュをS3に保持してくれます。 これならディスク容量を気にすることもないし、管理が楽になりますね。
公式 Example だと、こんな感じです。
steps:
- uses: actions/checkout@v2
- uses: shonansurvivors/actions-s3-cache@v1.0.1
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: us-east-1
with:
s3-bucket: your-s3-bucket-name # required
cache-key: npm-v1-${{ hashFiles('laravel/package-lock.json') }} # required ('.zip' is unnecessary)
paths: node_modules # required
command: npm ci # required
zip-option: -ryq # optional (default: -ryq)
unzip-option: -n # optional (default: -n)
working-directory: laravel # optional (default: ./)
僕らの運用では
- S3バケットは複数リポジトリで共有
- キー名にリポジトリ名を入れる
みたいな決め事を作ったので、こんな感じにしてみました。
- uses: actions/checkout@v2
- id: get-repository-name
run: |
IFS=/
REPO=${{ github.repository }}
set -- ${REPO}
echo "::set-output name=name::$2"
- uses: shonansurvivors/actions-s3-cache@v1.0.1
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: ap-northeast-1
with:
s3-bucket: ci-actions-cache
cache-key: ${{steps.get-repository-name.outputs.name}}-cache-${{ hashFiles('package-lock.json') }}
paths: node_modules
command: npm ci
get-repository-name
でリポジトリ名を抜き出してきて、 cache-key
で使っています。
cache-key
に一致するものがあれば、S3からダウンロードしてzipを展開、一致するものがなければ command
を実行して paths
にあるファイルを zip アーカイブして S3 に保持といったことをやってくれるので、便利ですね。
あとは S3 のバケットにファイルの有効期限を設定しておくようにすれば、古いキャッシュがいつまでも残ることもなく、とても便利です。