やりたいこと
以下のようなモノレポの構成のリポジトリがありました。
.
├── package.json
└── packages
├── a
│ └── package.json
└── b
└── package.json
😥 自動テストしたいよ〜
😥 修正があったパッケージだけ自動テストしたいよ〜
👼 できるよ
😥 ?!
ということで、簡単にできる方法があるのでご紹介します 🎉
サンプルコードは以下になります。
やること一覧
- workspace を設定する
- ワークフローを作る
- GitHub Actions を実行する
workspace を設定する
npm workspace 機能を使うことで、単一のルートパッケージから複数のパッケージを workspace として管理することができます。
既存のパッケージは package.json に以下の設定を追加すれば大丈夫です。
"name": "",
...
"private": true,
"workspaces": [
"packages/a",
"packages/b"
],
...
新しく作る場合は以下のようにパッケージを作成します。
$ npm init -w packages/c
ワークフローを作る
完成形はこちら。
get-changed-workspaces-action を使って変更された workspace を検出しています。
name: Monorepo Test Actions Sample
on: [pull_request]
jobs:
get-changed-workspaces:
runs-on: ubuntu-latest
outputs:
packages: ${{ steps.changed-packages.outputs.packages }}
empty: ${{ steps.changed-packages.outputs.empty }}
steps:
- name: Check out repository code
uses: actions/checkout@v3
- name: Find changed workspaces
uses: AlexShukel/get-changed-workspaces-action@v2.0.0
id: changed-packages
test-jest:
name: Test with Jest
# get-changed-workspaces が正常に完了した時、このジョブは実行されます
needs: [get-changed-workspaces]
# workspace に変更がなければこのジョブをスキップします
if: ${{ !fromJson(needs.get-changed-workspaces.outputs.empty) }}
runs-on: ubuntu-latest
strategy:
matrix:
# 変更された packages をマトリックスに渡す
package: ${{ fromJson(needs.get-changed-workspaces.outputs.packages) }}
steps:
- uses: actions/checkout@v3
- name: Test
run: npm run test
working-directory: ${{ matrix.package.path }}
重要な箇所をかいつまんで説明します。
変更された workspaces を検出する
以下で変更された workspaces を検出しています。
get-changed-workspaces-action の詳細は こちら で確認することができます。
- name: Find changed workspaces
uses: AlexShukel/get-changed-workspaces-action@v2.0.0
id: changed-packages
test-jest に検出した情報を渡します。
outputs:
packages: ${{ steps.changed-packages.outputs.packages }}
empty: ${{ steps.changed-packages.outputs.empty }}
変更された workspaces でテストを実行する
test-jest を実行するには get-changed-workspaces が正常に完了している必要があるので needs を設定します。
needs: [get-changed-workspaces]
workspace に変更がなければ test-jest をスキップします。
if: ${{ !fromJson(needs.get-changed-workspaces.outputs.empty) }}
変更された workspaces をマトリックスに渡します。
マトリックスの詳細については こちら を参照ください。
strategy:
matrix:
# 変更された packages をマトリックスに渡す
package: ${{ fromJson(needs.get-changed-workspaces.outputs.packages) }}
変更された workspaces に移動して npm run test
を実行します。
matrix.package.path には /home/runner/work/${リポジトリ名}/${リポジトリ名}/packages/a
のような値が入っています。
- name: Test
run: npm run test
working-directory: ${{ matrix.package.path }}
これでワークフローは完成です 🙌
GitHub Actions を実行する
プルリクエストを作ってテストが実行されているか確認しましょう!
感想
意外と簡単にできましたね 🤗
テストだけじゃなくてデプロイにも使えるので good です 👍
参考