目的
workflow_dispatch
でジョブが発火するときの条件や挙動を理解する。
結論
workflow_dispatch
でジョブが発火するには、そのワークフローファイルがデフォルトブランチにマージされている必要がある。
ただし、発火の条件が「ワークフローファイルがデフォルトブランチにマージされている」というだけで、実際に、使用するブランチは指定することができる。
説明
(0)
もちろん、ターミナルから、GitHub API にリクエストを飛ばすことができるが、今回は、PRにpushしたときに発火するワークフロー(.github/workflows/trigger_dispatch.yml
)から、dispatch したいワークフロー(.github/workflows/target-workflow.yml
)を発火させることにする。
(1)
試しに、下記のファイルを作成して、PRを新しく作る。
※ 下記では、ブランチ名は20241016-github-api-dispatch-pra-fourth
となっていますが、PRのブランチ名に変更してください
そうすると、PR 作成と同時に、dispatch する側のワークフロー(.github/workflows/trigger_dispatch.yml
)が発火する。
しかし、dispatch される側のワークフロー(.github/workflows/target-workflow.yml
)は、デフォルトブランチにマージされていないので、dispatch に失敗する。
name: Target Workflow
on:
workflow_dispatch:
jobs:
run:
runs-on: ubuntu-latest
steps:
- name: Run some task
run: echo "Target workflow triggered! CCCCCCCCCC_246856"
name: Trigger Dispatch
on:
pull_request:
branches:
- develop
jobs:
trigger-workflow-dispatch-by-shell-script:
runs-on: ubuntu-latest
steps:
- name: Trigger another workflow via shell script
run: |
curl -L --fail-with-body \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ github.repository }}/actions/workflows/target-workflow.yml/dispatches \
-d '{"ref":"20241016-github-api-dispatch-pra-fourth"}'
shell: bash
(2)
先ほどのPRをマージする。
そして、新しくブランチを切って、README.txt
を変更するなりして無理やり差分を作って、新しくPRを作成してみる。
※ ワークフローファイル(.github/workflows/trigger_dispatch.yml
)のブランチ名を、新しく作成したPRのブランチ名に変更してください。
そうすると、PR 作成と同時に、dispatch する側のワークフロー(.github/workflows/trigger_dispatch.yml
)が発火する。
先ほどは、dispatch される側のワークフロー(.github/workflows/target-workflow.yml
)のdispatchは失敗したが、今度は成功する。ワークフローファイル(.github/workflows/target-workflow.yml
)がデフォルトブランチにマージされているからである。
(3)
次に、例えば、echo "Target workflow triggered! CCCCCCCCCC_246856"
の部分を、echo "Target workflow triggered! AAAAAAAAAA_565677"
のような文字列に変更して、このPRにpushする。
dispatch されたジョブのログを見に行くと、文字列の変更が適用されていることがわかる。
(4)
まとめると、workflow_dispatch
は特定のブランチに存在するジョブを発火させることができるが、そのジョブ自体は、デフォルトブランチにマージされている必要があるということである。
ついで
github-script
アクション
dispatch する側のワークフロー(.github/workflows/trigger_dispatch.yml
)は、github-script
を使って下記のように書くこともできる。
name: Trigger Dispatch
on:
pull_request:
branches:
- develop
jobs:
trigger-workflow-dispatch:
runs-on: ubuntu-latest
steps:
- name: Trigger another workflow
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const workflow_id = 'target-workflow.yml';
const ref = '20241016-github-api-dispatch-pra-fourth';
await github.rest.actions.createWorkflowDispatch({
owner: owner,
repo: repo,
workflow_id: workflow_id,
ref: ref
});
curl の --fail-with-body
curl は通常、404 が返ってきたとしても、exit 0
で終了するので、ワークフローが正常終了してしまう。
このオプションによって、404 が返ってきたときに、レスポンスメッセージを表示させつつ、exit 0
以外で終了することが可能になる。
--fail
オプションは、exit 0
以外で終了するが、レスポンスメッセージが表示されないので、--fail-with-body
オプションがよい。
${{ github.repository }}
curl のリクエスト先のURLにおいて、${{ github.repository }}
は、{レポジトリのオーナー}/{レポジトリ名}
となっているので、${{ github.repository_owner }}/${{ github.repository }}
とする必要がない。
shell: bash
ワークフローで、shell: bash
を明示的に指定すると、下記のようにシェルスクリプトの起動時オプションが変化する。
※ 今回はshell: bash
を使っているが、該当箇所は curl 特有のエラーの話なので、使っても使わなくてもどちらでも変わらない。
# `shell: bash`がない場合
$ bash -e {0}
# `shell: bash`がある場合
$ bash --noprofile --norc -e -o pipefail {0}
-
--noprofile
: 起動時に、~/.profile
を読み込まない -
--norc
: 起動時に、~/.bashrc
を読み込まない -
-e
: エラーが起きたら強制終了 -
-o pipefail
: パイプエラーを捕捉する。通常、パイプでつながれた場合、最後のコマンドのみによって、exit 0
(成功)かそれ以外かを決定するが、このオプションによって、パイプの途中でもエラーが起きれば、非ゼロ(exit 0
以外)で終了する。 -
{0}
: ここに実行されるメインのシェルスクリプトが来る。
参考