workflow_dispatchはGitHub Actionsを手動で起動するための機能ですが、ここでは
inputs
パラメーターを指定して実行時に指定できるようになっています。
そこではデフォルトの値を指定できますが、それらの値をpush
などのイベント時にも使いたい、という話。
workflow_dispatch
GitHub Actionsではpush
、pull_request
のレポジトリの変更時やschedule.cron
といった定期的な時刻を
トリガーとしてジョブを実行できます。
workflow_dispatch
もトリガーの1つで、これをon
の中で指定するとWorkflowのページにRun workflow
ボタンが設置され
手動で実行できるようになります。
手動で実行するだけなら最後のpush
イベントの時に実行されたworkflowを再実行すれば大概の事は
事足りると思いますが、workflow_dispatch
では入力パラメーターを指定して実行できる点が特有の機能になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
みたいな感じのworkflowを用意すればRun workflow
ボタンの中にvar1
に対して入力欄や
var2
に対してチェックボックスが出来て値を変更できるようになります。
それらの値は各ステップの中で条件判定に使ったり直接値を使ったりすることが出来るようになります。
inputsの値をpushイベントなどで使う
workflowで
1 2 3 4 5 6 7 |
|
みたいな感じでon
のトリガーとしてpush
やpull_request
など他のトリガーと一緒に定義することは可能で
ジョブを共有できます。
ただし、inputs
に関する値はworkflow_dispatch
でトリガーがかかった場合しか使えず、
その他の場合は参照しても値が入っていません。
default
で指定したものも入っていません。
なのでworkflowの中で必ずこれらの値を使いたいと言う場合には、別途初期値を設定しておく必要があります。
簡単には環境変数として入れてしまう方法があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
こんな感じでglobalなenv
としてinputs
を使った変数を定義します。
inputs
側のdefaultの値を知る術が無いので上のように二箇所で同じ初期値を設定する感じになって
ちょっと面倒な感じにはなってしまいます。
逆にenv
を最初に定義してinputs
に入れられれば最初に定義するだけで済みそうなものですが、
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
みたいにすると Unrecognized named-value: 'env'. Located at...
といったworkflowの構文エラーが出て実行されません。
というわけで2度書きせざるを得ない状態です。
上の書き方で、
GitHub Actionsの中のコンテクストでは、||
がorですが、
以下のようにするとinputs.var1
が空のとき、否定判定になって後ろのstring variable
が
入ります。
1
|
|
ここで文字列を使う場合はダブルクォートは使えずに必ずシングルクォートで囲う必要があります。
また、booleanとしてtrue
、false
が使えますが、
これらはクォート無しで書けるものの、env
自体が文字列としての扱いにしかならないので
上の場合、env boolean check
は必ず通ってしまいます。
(true
かfalse
という文字列として空文字ではない、として判定されるため。)
if
文などにenv
で直接渡したい場合にはif
の方で
1 2 3 |
|
のように文字列として'true'
と比較する必要があります。
trigger workflowを別に作ってdispatchする
workflow_dispatch
を設定しておくとWebインターフェースから手動で行う以外にも
API経由で実行することもできます。
なので他のレポジトリのworkflowを動かすことも出来たりします。
これを使って同じレポジトリの中でworkflow_dispatch
用のworkflowと他のpush
とか用のものを作って、
push
用の方からworkflow_dispatch
用のworkflowを実行してやるということが考えられます。
追記: 2023/02/27
ただし、dispatchするにはブランチかタグの指定しかできず、pull requestで作られる最終的なmergeの状態は
渡すことが出来ないためtest.yml側でon.pull_request
を指定することは出来ません
1。
なのでpull requestもチェックしたい場合はやはり上のように同じファイル内で変数を再定義する必要があります。
追記ここまで
とりあえず上のworkflowで、workflow_dispatch
以外のトリガー部分は削除します。
また、env
を消してinputs
を直接使うようにしておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
これを.github/workflows/dispatch.ymlとして導入したとします。
別の.github/workflows/test.ymlとかのファイルを以下のような内容で作ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
まず、APIでdispatchするためにトークンが必要ですが、
同じレポジトリであればAction実行時に用意される$
($GITHUB_TOKEN
)が使えます。
permissions
としてactions: write
を加えておくことで他のworkflowを実行する権限が付けられます。
直接APIのURLを叩いても良いですが、それようのactionがMarketplaceにあるのでそれを使います。
上のwith
で渡される引数のところで、workflow_file_name
を
workflow_dispatch
が書かれたworkflowのファイル名を指定します。
これでpush
時にこのtest.ymlが実行され、その中でdispatch.ymlも実行されます。
上のように書くと、dispatch.ymlが終わるとそのstepも終わって次に行くようになっています。
testの方のページからもdispatchの方のジョブページに簡単に飛べるようにGITHUB_STEP_SUMMARY
に書き出してジョブの概要欄に見えるようにもしておきます。
この情報はログの中にもありますが、いちいち開かずともすぐに見に行けるように。
最後はdispatchの方のジョブが失敗したらtestの方も失敗のステータスになるようにチェックを入れます。
trigger-workflow-and-waitではpropagate_failure
という引数があってこれをtrue
にすれば
dispatchが失敗したらstep自体も失敗になるようにもできます。
上の例ではジョブ概要にリンクを書き出したいので最初のstepでは失敗しても継続して最後で再度チェックするようなことをしています。
この辺が冗長だと思えば
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
とするだけでも良いかと。
まとめ
push
などをworkflow_dispatch
と同じファイルに書く場合に比べ、
別のトリガー用ファイルを用意した場合:
- Pros
- デフォルト値を各部分は
inputs
のところだけで統一できる。 - envの設定をそっくり落とせる
- inputsの値を直接使えるので、booleanの値を
if
などでそのままbooleanとして評価できる。
- デフォルト値を各部分は
- Cons
- ジョブが2つ起動される。
- 特にプライベートレポジトリだと実行時間が最大倍になる(dispatch.yml側もシングルタスクの場合)ので余計なコストがかかる可能性がある。
- ジョブの詳細ログがtestの方では見れずdispatchの方にいって確認する必要がある。
- ジョブが2つ起動される。
といった感じ。
シンプルなのはenv
を使った最初の方かな、と思いますし、
特にプライベートレポジトリで使う場合には必ずそっちを使ったほうが良いです。
一方で別ファイルを用意すると、デフォルト値を一箇所に集約できるので、 もし大量のinputsの値を扱うような場合にはこっちの方が良いかとは思います。
もしかしたらもっと上手い方法があるかもしれませんが、もしあれば教えてもらえるとうれしいです。
GitHub Actionsは今でも結構頻繁にアップデートがありますし、一方でドキュメントの更新は結構滞ってる感もあって 隠し機能的になってる部分もあるので、なにかできるかもしれませんし、 そのうちしれっとアップデートしてもっと簡単に出来る方法が追加されるかもしれません。
-
convictional/trigger-workflow-and-wait のREADMEとかを見るとrefにThe reference of the workflow run. The reference can be a branch, tag, or a commit SHA. が指定できるように書いてありますが、 GitHubのCreate a workflow dispatch event の方には The git reference for the workflow. The reference can be a branch or tag name.となっていて、 実際にPRのSHA(
$
)を指定するとNo ref found for: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
みたいなエラーが出ます。 ↩