概要
本記事では前回モノレポ化したリポジトリに対して、GitHub ActionsでCIを実行するチップスを解説します。
前提
- 対象とするリポジトリmonorepoは5つのフォルダ(システム)からなるモノレポ構成
- hoge1-be
- hoge1-fe
- hoge2-be
- hoge2-fe
- database
- 作業ブランチはpushed_branch
特定のフォルダに変更があればworkflowを実行する
イベントトリガーのpushにファイルパスのパターンを設定できます。
以下の場合は hoge1-be
か hoge2-be
のどちらかに変更があるpushがされた場合にworkflowが実行されます。
on:
push:
paths:
- hoge1-be
- hoge2-be
モノレポではバックエンドやフロントエンドのリポジトリが混在している場合があります。
バックエンドの変更をpushしたときに、都度フロント用のCIを実行する必要はあまりないと思います。
git checkout
モノレポでは単純にgit checkoutすると全てのフォルダがcheckoutされてしまいます。
こういった場合に有効なのがgit sparse-checkoutです。
しかし、GitHub Actionsでよく使われるactions/checkout@v3ではsparse-checkoutに対応していません。
そこで、以下のようなsparse-checkoutを実行します。
--no-checkout
をつけることでファイルの実体をcheckoutせずにcloneが可能です。
checkoutしたいフォルダに対して git sparse-checkout add
を実行します。
git clone -b pushed_branch --filter=blob:none --no-checkout --depth 1 --sparse https://github.com/account/monorepo.git .
git sparse-checkout add hoge1-be
git sparse-checkout add hoge2-be
git checkout
実際には pushed_branch
がpushされた任意のブランチ名になるので、ブランチ名を取得するステップを追加します。
また、ルートに存在するファイルが必要な場合は git sparse-checkout init --cone
を追加します。
- name: Set branch name
id: vars
run: echo ::set-output name=pushed_branch::${GITHUB_REF#refs/*/}
- name: Git checkout
run: |
git clone -b ${{ steps.vars.outputs.pushed_branch }} --filter=blob:none --no-checkout --depth 2 --sparse https://${GITHUB_ACTOR}:${{secrets.GITHUB_TOKEN}}@github.com/${GITHUB_REPOSITORY}.git .
git sparse-checkout init --cone
git sparse-checkout add hoge1-be
git sparse-checkout add hoge2-be
git checkout
変更したファイルにのみlintを実行する
git cloneの際に --depth 2
としておけば前回との差分が取得できます。
これをlinterのパラメーターに引き渡すことで特定のファイルのみに対してlintを実行できます。
<some-linter> `git diff HEAD~ HEAD --name-only --diff-filter=AMRT | tr '\n' ' '`
パッケージなどをキャッシュする
モノレポとは直接関係ないですが、設置に時間がかかるパッケージなどはキャッシュすると実行時間を短縮できます。
これにはactions/cache@v2を使います。
以下はyarnを利用しているフロントエンドでのキャッシュを設定します。
プロジェクトのnode_modules、globalのキャッシュをpathに指定し、yarn.lockのハッシュをキーとします。
yarn install
などの実行前にこのステップを追加することで保存済みのキャッシュを復元します。
キャッシュの保存はjobの最後に自動で実行されます。
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache
with:
path: |
hoge1-fe/node_modules
${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-hoge1-fe-yarn-${{ hashFiles('**/yarn.lock') }}
まとめ
以上、モノレポでGitHub Actionsをいい感じにやるチップスを説明しました。
workflowのトリガーでフォルダの指定とgit sparse-checkoutで対象ファイルを絞ることが設定できれば、あとは一般的なCIと変わりません。