rcmdnk's blog
Last update

Break Our Fall

GitHub Actionsで依存関係のあるレポジトリ間で、 他のレポジトリのworkflowを動かして結果を見てみたい時、 直接他のレポジトリのworkflowにtriggerをかけて動かしてみる方法について。

Create a workflow dispatch event

GitHub ActionsのAPIにdispatchesというものがあり、これを使って workflowを送り出してやることが出来ます。

GitHub Actionsのページからボタンを使って実行できるようになるものですが、 この設定が入ったworkflowがあるとAPI経由で実行することも出来るようになります。

Create a workflow dispatch event

というわけで、workflowに適切なTokenを渡した上でこのAPIを叩いて上げれば他のレポジトリのworkflowを実行できます。

追記: 2023/02/27

workflow_dispatch 以外にrepository_dispatch というトリガーもあります。

こちらもAPI経由で実行することが可能です(APIは別)。

Create a repository dispatch event

repository_dispatchとworkflow_dispatchの主な違いは

  • repository_dispatch
    • 手動実行できない
    • ブランチはデフォルトブランチに限る
  • workflow_dispatch
    • 手動実行が出来るようになる
    • ブランチ(もしくはタグ)はrefで指定可能

追記ここまで

Tokenの取得

レポジトリのActionsへの書き込みの権限がほしいわけですが、 最近レポジトリ単位で細かく権限が設定できる fine-grained personal access tokens というものが使えるようになったのでそれを使ってみます。

Introducing fine-grained personal access tokens for GitHub The GitHub Blog

まだ現時点でもベータ版になっていますが古いものと並行して使えるようになっています。

Fine-grained Personal Access Tokensのページへ行き 1 Generate new tokenボタンを押して新しいtokenを発行。

この際、Fine-grainedの方だとアプリを使った追加認証などが求められるようになっています。 (古い方のものでは要求されない。)

また、古いほうだとNo expirationが選べましたがFien-grainedの方では最大で1年までの期限付きしか選べなくなっています。

大きな違いは

  • Public Repositories (read-only)
  • All repositories
  • Only select repositories

というものから選べて、Tokenを適用するレポジトリの範囲を決める事ができます。 Only Selectでは1つのTokenで最大50個のレポジトリを選ぶ事が出来ます。

単に公開されている情報をAPI経由で取得したくてrate limitを上げたいだけの場合などは Public Repositories (read-only)にしてpermissionを何も付けずに Tokenを取得すればOKです。

ここでOnly select repositoriesを選んで今回workflowを他からAPIで呼び出したいレポジトリを選んでおきます。

その下でPermissionsの項目で必要なものをNo accessRead-onlyRead and write の中から選べるようになっているので 一番上のActionsRead and writeにします。

これを選択するとMetadataRead-onlymandatoryとして自動的に有効になります。

今回はこれら以外はすべてNo accessのままで、Generate tokenしてTokenを取得します。

Tokenの登録

取得したTokenをトリガーを発行したい元のレポジトリのActions secretsに登録します。 Settingsのページの左の欄の中のSecrets and variablesを開いてActionsのページを開くと Actions secrets and variablesの管理ページに行くのでNew repository secretボタンから先程取得したTokenを設定します。

変数名は適当にトリガーをかける先のレポジトリ名とか使ってREPO_DEST_TOKENとか。

この名前にGITHUB_というプレフィックスをつけようとすると駄目だと怒られるので別の名前に。

Workflow IDの取得

このステップは後の Trigger Workflow and Wait Actionを使う場合にはスキップして大丈夫です。

Workflowを呼ぶためにIDが必要になります。このIDはAPIを使って

https://api.github.com/repos/rcmdnk/python-action/actions/workflows

みたいなURLを開くと

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "total_count": 1,
  "workflows": [
    {
      "id": 46140101,
      "node_id": "W_kwDOIz9uZ84CwArF",
      "name": "test",
      "path": ".github/workflows/test.yml",
      "state": "active",
      "created_at": "2023-01-22T09:57:49.000Z",
      "updated_at": "2023-01-22T09:57:49.000Z",
      "url": "https://api.github.com/repos/rcmdnk/python-action/actions/workflows/46140101",
      "html_url": "https://github.com/rcmdnk/python-action/blob/main/.github/workflows/test.yml",
      "badge_url": "https://github.com/rcmdnk/python-action/workflows/test/badge.svg"
    }
  ]
}

といった感じの情報が得られるのでこのidになります。

APIを使ったworkflowの実行

ここまで来たらあとは

workflowの中で${{ secrets.REPO_DEST_TOKEN}}を使って

1
2
3
4
5
curl -H "Accept: application/vnd.github+json" \
     -H "Authorization: Bearer ${{ secrets.REPO_DEST_TOKEN}}" \
     -H "X-GitHub-Api-Version: 2022-11-28" \
     https://api.github.com/repos/rcmdnk/repo_dest/actions/workflows/test.yml/dispatches   \
     -d '{"ref": "main"}'

のようにAPIを叩いて上げれば実行出来ます。

rcmdnk/repo_destはdispatchしたいworkflowのあるレポジトリ、 test.yml.github/workflowsにあるworkflowの設定ファイル名です。 (拡張子も含める。)

Create a workflow dispatch event

Trigger Workflow and Wait Actionを使う

IDを取得したりcurlとかで色々書くのがちょっと面倒ですが、 このようなことを行うためのActionがMarketplaceに公開されているのでそれを使うと簡単に設定できます。

Trigger Workflow and Wait · Actions · GitHub Marketplace

workflowの中で以下の様なstepを追加するだけ

1
2
3
4
5
6
7
  - uses: convictional/[email protected]
    with:
      owner: rcmdnk
      repo: repo_dest
      github_token: ${{ secrets.PYTHON_ACTION_TEST_TOKEN }}
      workflow_file_name: test.yml
      propagate_failure: true

ownerにレポジトリのユーザー名、repoにレポジトリ名を与え、 workflow_file_nameでworkflowのファイル名を指定してあげればworkflow idも勝手に取得してくれます。

あとは先程取得したTokenをgithub_tokenに渡してあげるだけ。

propagete_failureは実行したworkflowのの成否をこのstepの成否として使いたい場合にtrueに設定します。 もし失敗してもこちらのworkflow側では失敗として扱わない場合は必要ありません。

他には

  • ref: ブランチ名など。デフォルトはmain
  • client_payload: workflow_dispatchinputsを保つ場合はここにjson形式で値を渡せます
    • "{\"option_a\": \"abc\", "{\"option_b\": \"xyz\"}"みたいな感じで。
  • wait_interval: ジョブの結果を確認する頻度。デフォルトは10秒間隔。
  • github_user: Tokenの所有者のユーザー名
    • これはworkflowの結果を取得する際に使われるもので通常使う事はないです。
    • workflowを実行する際にトリガーをかけたユーザー名を変更できると思って区別できる名前を付けたらtokenの所有者と別名となって結果の取得が延々と出来ない状態になってしまいました。

などのオプションがります。

実行すると

1
2
Sleeping for 10 seconds
Getting workflow runs using query: event=workflow_dispatch&created=>=XXXX-XX-XXTXX:XX:XX+00:00&actor=&per_page=100

みたいなログが結果が出るまで出続けて、結果が出ると

1
2
The workflow id is [XXXXXXXXXX].
The workflow logs can be found at https://github.com/rcmdnk/repo_dest/actions/runs/XXXXXXXXXX

みたいな感じでジョブのURLも出してくれます。

この辺の結果の確認まで自動で行ってくれるのが嬉しいところです。

Ref:

Sponsored Links
  1. SettingsDeveloper settingsPersonal access tokensの中にあるFine grained tokens (beta)を選択

Sponsored Links

« GitHub Actionsを手動実行するworkflow_dispatch GitHub Actionsで行ったtestのcoverageの結果をジョブの概要として出力する »

}