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みたいなエラーが出ます。 ↩

