GitHub Actionsを使って、PRをmasterへmergeしたらbuildが走ってdeployする、みたいなことをしたかった時にハマった出来事です。 build & deploy周りの話は
【備忘録】Scala で Azure Functions やってみる(deploy編) - 窓を作っては壊していた人のブログ
の件です。
ネタバレ
- PRのmergeと同時に行っていたブランチの削除がtriggerだった
- deletedフラグを監視することでブランチの削除由来のアクションを抑制できる
on pushイベントが2回走ってる!
PRをmasterにmergeしたらon pushイベントがどうしたことか2回走っています。 on pushイベント自体はブランチに関係なくcommitがpushされると走るのでその挙動自体には問題はありません。
問題なのはactions/binに実装されているfilter/branchでmasterを指定しただけだと効果がないということです。 というのも走っているactionsのどちらもmasterブランチに紐付いているからです。
なんとかしてmasterへのmergeだけを取り出せないか、やってみました。
案1. on pushイベントのevent.json内のref要素を見てfilter
on pushイベントは2回発火していましたが、GitHub Actionsでfilterなどをする時などに使うevent.json
の中身は異なっていました。
diffを見ていて気になったのがref
要素が違う、ということでした。
ブランチは両方masterではあるのですが、ref要素を見てみると
// PRにしたブランチ名は custom-filter "ref":"refs/heads/custom-filter" // こっちがmaster "ref":"refs/heads/master"
の様な違いがあります。
であればこの要素を見てfilterかければ良さそうです。 ということでやってみたのが以下のPRです。
Custom filter by yamachu · Pull Request #9 · yamachu/play-actions · GitHub
中身としては actions/bin で使われているfilter系のスクリプトほぼそのままです。 外部からどの要素を使うか流し込めるようになっています。
action "filter head" { uses = "actions/bin/filter@master" runs = "/github/workspace/.github/custom-filter.sh" args = "refs/heads/master" env = { CUSTOM_JQ_FILTER = ".ref" } }
これでon pushが2回走ろうがmasterのみをハンドリングできるようになりました。
案2. on pushイベントのevent.json内のdeleted要素を見てfilter
案1で満足していましたが、結局なぜ2回走っているのかはわかりませんでした。 そんな中
GitHub Actions、on pushをトリガにしてるんですけど、PRをmergeすると同じコミットに対してActionが2回”以上”実行されるんですけど、同じ様な状況の人いますか?または解消方法分かる人いらっしゃいますか?Public Repositoryで動作確認をしています。
— ちゅうこ@mvpsummit (@y_chu5) March 14, 2019
このツイートに対してリプライが飛んできて、どうもブランチを消したタイミングで2個目が走っているとの情報をいただきました。 情報非常に感謝です。 実際にmergeした後にブランチを削除しないと、確かに1つしかon pushイベントは飛んでいないのです。 完全に盲点だった………
え、ドキュメントに書いてあったっけ、と思い公式ドキュメントを見てみると
………あまりそういう風には読み取れ…ないんだけど…自分の英語能力がアレなのかな…みたいになってしまいました。
ともかくそういうものである、ということにして進めていきます。
案1の時と同じ様にmergeのタイミングで取得できたevent.jsonと削除タイミングで取得できたevent.jsonを比較してみます。 すると
// 削除した時 "deleted":true // mergeした時 "deleted":false
ビンゴです、完全に理解した。
ということで書き直してみます。
Update main.workflow by yamachu · Pull Request #10 · yamachu/play-actions · GitHub
action "filter not deleted event" { uses = "actions/bin/filter@master" runs = "/github/workspace/.github/custom-filter.sh" args = "false" env = { CUSTOM_JQ_FILTER = ".deleted" } }
これで正攻法で戦えている気がします。
結局on pushでmaster branchのみを引っ張るには
- filterでbranch masterを行う
- "deleted": falseなものを通す
この2つをWorkflowに入れることで可能になりそうです。
今は外側からどの要素を取得するかみたいなスクリプトを自分で書いて入れていますが
リポジトリを見てみたらPRが上がっているようです。 mergeされるともう少し楽になりそうですね。
良きGitHub Actionsライフを!