タイトルの通りですが最近は GitHub Actions をいじる機会が多く、リポジトリ間でリリースイベントを伝播してワークフローを実行するなどしたかったので備忘録です。
repository_dispatch を使う
repository_dispatch
は GitHub の外部のイベントを検知するために用意されている機能です。GitHub API に用意されてるエンドポイントからワークフローをトリガーすることができます。https://docs.github.com/en/actions/reference/events-that-trigger-workflows#repository_dispatch
なお、 repository_dispatch
イベントが実行されるのはワークフローが master もしくはデフォルトブランチにあるときのみとなります。
repository_dispatch API 実行によるワークフローのトリガー
repository_dispatch API について
ワークフローが配置されてるリポジトリに対してAPIを実行することでワークフローを実行することができます。
APIの実行の際には認証がかかるのでパーソナルアクセストークンを指定する必要があります。
また、リクエストボディには下記のフィールドの指定が必要となります。
Field | Description |
---|---|
event_type | 文字列を指定します。トリガーされたワークフローにて event payload における action として扱われます |
client_payload | トリガーするイベントに伝播する情報をJSONオブジェクトとして自由に設定できます |
curl で叩くときは以下のような感じになります。
curl -X POST https://api.github.com/repos/:owner/:repo/dispatches \
-H 'Accept: application/vnd.github.everest-preview+json' \
-u $your_user:$your_personal_access_token \
--data '{"event_type": "$your_event", "client_payload": { "customField": "customValue" }}'
APIを叩いてワークフローを実行する
以下はサンプルのワークフローです。on
にrepository_dispatch
を指定します。
※繰り返しとなりますがmasterかデフォルトブランチしかトリガーされません。
name: Repository Dispatch Sample
on: repository_dispatch
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Event Information
run: |
echo "Event is '${{ github.event.action }}'"
echo "Message is '${{ github.event.client_payload.message }}'"
実際にAPIを叩いてみるとワークフローが実行されます。
リポジトリ間でリリースイベントを伝播させるワークフローを作る
repository_dispatch
を使うことでAPIを通じてワークフローを起動できることから、ワークフロー内部でAPIを叩くことができればワークフローからワークフローをトリガーできることがわかります。
これを応用して、リポジトリ間でリリースイベントを伝播するワークフローを構築しました。
リリースイベントの伝播元となるワークフロー
リリースを Publish
するとワークフローが起動し、タグなどのリリース関連の情報をclient_payload
に詰めてAPIを実行します。curlコマンドの-u
オプションに指定するユーザー名およびパーソナルアクセストークンおよびユーザー名はsecrets
から読み込みます。
name: Release
on:
release:
types: published
tags: v*.*.*
jobs:
Release:
runs-on: ubuntu-latest
steps:
- name: Set var of release version
run: |
echo ::set-env name=RELEASE_VERSION::${GITHUB_REF#refs/*/}
- name: Set var of request header
run: |
echo ::set-env name=REQUEST_HEADER::"'"Accept:application/vnd.github.everest-preview+json"'"
- name: Set var of request body
run: |
echo ::set-env name=REQUEST_BODY::'{"event_type": "release", "client_payload": { "repository": "'"$GITHUB_REPOSITORY"'", "tag_name": "'"$RELEASE_VERSION"'", "release_name": "Repository Dispatch Test"}}'
- name: Repository dispatch
run: |
curl -X POST https://api.github.com/repos/:owner/:repo/dispatches \
-H $REQUEST_HEADER \
-u ${{ secrets.PERSONAL_ACCESS_TOKEN }} \
--data "$REQUEST_BODY"
伝播先のワークフロー
受け取ったリリース関連情報を元にリリースを作成します。ワークフローからのリリースの作成にはcreate-releaseを使いました。
name: Create Release
on: repository_dispatch
jobs:
Create_Release:
runs-on: ubuntu-latest
steps:
- name: Event Information
run: |
echo "Event '${{ github.event.action }}' received from '${{ github.event.client_payload.repository }}'"
- name: Create Release
if: github.event.action == 'release'
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.event.client_payload.tag_name }}
release_name: ${{ github.event.client_payload.release_name }}
draft: false
prerelease: false
動作確認
まずは伝播元のリポジトリでリリースを作成します。
リリースが作成されたことを受けてワークフローが起動し、Repository dispatch A
で伝播先のリポジトリに対して repository_dispatch の API を実行しているのがわかります。
伝播先のリポジトリの挙動を確認します。
伝播先でもワークフローの実行とリリースの作成が確認できました。
参考
https://blog.marcnuri.com/triggering-github-actions-across-different-repositories/
https://stackoverflow.com/questions/58177786/get-the-current-pushed-tag-in-github-actions
終わり
おわりです。