背景
任意のタイミング、ブランチでworkflowを実行したい
push時にも同じworkflowを実行したい
repository_dispatch
GitHubActionsを使って任意のタイミングでworkflowを実行するためにはrepository_dispatch
eventを指定すればよい
Events that trigger workflows - GitHub Help
event_typeによる実行対象のフィルタリング
ヘルプを見るとtypes
指定はできなそうに見えるがAPIをたたくときにevent_type
を指定すればよしなにフィルタリングしてくれるよう
- workflow.yml
on: repository_dispatch: types: [hoge]
- curl
curl -X POST -H -H "Authorization: token $TOKEN" -H "Accept: application/vnd.github.everest-preview+json" --data '{"event_type": "hoge"}' https://api.github.com/repos/:user/:repo/dispatches
上記であればevent_type
にhoge
以外を指定した場合はworkflowが実行されない
なので複数のworkflowファイルにそれぞれrepository_dispatch
を指定してもテストのときはこっちのyml、デプロイのときはこっちのymlといった具合に使い分けができる
特定のブランチでworkflowを実行したい
これだけだと常にworkflowの実行はmaster
ブランチなので特定ブランチで何かさせたいときに対応できない
フォーラムにも同様のスレッドが立ってたりしていた
How to trigger repository_dispatch event for non-d... - GitHub Community Forum
client_payloadを用いてjson payloadを渡す
Repositories | GitHub Developer Guide
repository dispatch eventのAPIはevent_type
のほかにclient_payload
で任意のjsonを渡すことができる
この中身にブランチを指定してあげればあとはGitHubActions側でよしなにできる
ちなみにこのclient_payload
jsonを渡さないと駄目らしい
--data '{"event_type": "hoge", "client_payload": "aaa"}'
{ "message": "Invalid request.\n\nFor 'properties/client_payload', \"aaa\" is not an object.", "documentation_url": "https://developer.github.com/v3" }
pushとrepository_dispatchのevent内容の違い
任意のタイミングでも実行したいが、通常(push)時にはpushされたブランチで実行したいので分岐をさせる必要がある
差分を確認するためにevnetの内容を確認する
- 確認用設定
name: sample on: [push, repository_dispatch] jobs: test: runs-on: ubuntu-latest steps: - run: cat $GITHUB_EVENT_PATH
- push時のevent
{ "after": ".....", "base_ref": null, "before": ".....", "commits": [
- dispatch apiをcurlでたたいたときの
--data
の中身
--data '{"event_type": "hoge", "client_payload": {"ref": "feature/branch-a"}}'
- repository_dispatch時のevent
{ "action": "hoge", "branch": "master", "client_payload": { "ref": "feature/branch-a" }, "repository": {
中身が全然違う
ということで今回はclient_payload
があるかで分岐すればよさそう
特定のブランチをcheckoutする
actions/checkout: Action for checking out a repo
checkout時に特定のブランチを指定したい場合はREADMEにあるとおり
steps: - uses: actions/checkout@master with: ref: branch
で切り替えることができる
branchはdispatchイベントで受け取ったjsonから取得すればOK
ドキュメントは下記
GitHub Actions のコンテキストおよび式の構文 - GitHub ヘルプ
- workflow.yml
on: push: repository_dispatch: types: [hoge] jobs: hoge: runs-on: ubuntu-latest name: hoge steps: - uses: actions/checkout@master - if: github.event.client_payload uses: actions/checkout@master with: ref: ${{ github.event.client_payload.ref }}
github.event.client_payload
があればrepository_dispatch
イベント経由と判断しclient_payload.ref
の値を使うようにする
当たり前だが存在しないブランチをrefに指定してPOSTするとエラーとなる
このケースだとAPI実行時は次のような感じで実行できるようになる
curl -X POST -H "Authorization: token $TOKEN" -H "Accept: application/vnd.github.everest-preview+json" --data '{"event_type": "hoge", "client_payload": {"ref": "feature/branch-a"}}' https://api.github.com/repos/:user/:repo/dispatches
pushイベントのときは分岐を通らないのでpushされたブランチで実行される
まとめ
特定のブランチをチェックアウトしてからworkflowを実行できるようになった
やったことの流れ
- Actions: on.repository_dispatchで任意のworkflowをAPI経由で実行可能にする
- API: event_typeで実行対象のworkflowを指定する
- API: event_payloadで任意のjsonを渡す
- Actions: client_payloadのjsonを元に特定ブランチをcheckoutする
- Actions: checkoutしたブランチでworkflowを実行する
若干無理やり実現しているため次の点で微妙なところが残ってしまった
- Jobごとに分岐を入れてcheckoutする必要が出てしまう
- Actions上では
master
で実行している扱いになってしまう
ただ、応用すれば「特定のブランチで確認用の環境立ち上げる」みたいなこともできそう
GitHubActions楽しい