2019/01現在Public BataのGitHub ActionsでCircleCIのbranches only
相当の処理を出来ないか調査した。
- GitHub Actions
TL;DR
- 特定のブランチ名のときだけ動くGitHub Actionsを定義したい
- Workflowに対する設定はないが、Actionで設定することができる
- actions/bin/filterを使う
サンプルブランチは以下。
- budougumi0617/actions-filter-branch
なお、この記事は2019/01/11時点で最新のGitHub Actionsの情報になる。(2018/12/18リリースのPublic BETA版)
- Enabling Actions on Public Repositories
GitHub Actionsとは
ここではGitHub Actionsの詳細は省くが、GitHub Actionsは現在Public BETA版が公開されているGitHub公式のワークフローの自動化サービスだ。
- GitHub Actions: みなさんが開発し、GitHubで実行
まだ利用できない方は以下のページのSign up for the beta
ボタンをクリックしておけばいずれリポジトリに「Actions」タブが着くようになる
- GitHub Actions
GitHub Actionsでは、一連の処理のまとまりをWorkflow、各処理はActionと定義している。各Actionはそれぞれで「別の」コンテナを起動して実行される。コンセプトはGCPのCloud Buildに近い。
Workflowの定義は/.github/main.workflow
ファイルをリポジトリに配置することで設定でき、GitHub上で該当ファイルを開くとGUIエディタからも編集できる。
やりたいこと
CI/CDを設定していると、例えば、master
ブランチが更新されたときだけ実行されるデプロイジョブなどを作っていないだろうか。
CircleCIでいうと、branches only
相当の処理になる。
- branches | Configuring CircleCI - CircleCI
これをGitHub Actionsでも設定できるのか調べた。
actions/bin/filterを使う
実は公式ですでに用意されているAction用のコンテナがあるのでそれを使えば簡単に実現できた。
GUIエディタからも選ぶことができる。
今回はmaster
ブランチのときのみ後続のecho
コマンドのActionを実行する簡単なWorkflowを定義してみた。
actions/bin/filter
コンテナで実行するActionを定義し、スクリプトとフィルターしたいブランチ名を引数に設定しておく。
action "Filters for GitHub Actions" {
uses = "actions/bin/filter@master"
args = "branch master"
}
なお、任意のshell
コマンドを実行するActionはGUIエディタからすぐ選べないので、自分でactions/bin/sh@master
を選んで定義する。
Workflow全体は以下のようになる。
workflow "filter branch" {
on = "push"
resolves = ["Shell"]
}
action "Filters for GitHub Actions" {
uses = "actions/bin/filter@master"
args = "branch master"
}
action "Shell" {
uses = "actions/bin/sh@master"
needs = ["Filters for GitHub Actions"]
args = ["echo success"]
}
このWorkflowはリポジトリにpushイベントが発生されるたびに実行される。
実行した結果が以下だ。master
ブランチのときは最後までWorkflowが実行される。
master
ブランチでないときはNeutral
というstatusでWorkflowは最後まで実行されなかったので、意図通りブランチ名でWorkflowを制御できた。
actions/bin/filterで行なっていること
これだけだと寂しいので、actions/bin/filter
の中も確認してみた。
リポジトリの中を見るといくつかの簡単なスクリプトが用意されており、READMEに書かれている通りに使えばよい。
- https://github.com/actions/bin/blob/master/filter/README.md
- https://github.com/actions/bin/tree/master/filter/bin
- action
- branch
- label
- ref
- tag
- user
スクリプトの中身も非常にシンプルで、branch
スクリプトは単にref
スクリプトへのエイリアスだ。ref
スクリプト自身も簡単なcase文が書かれているだけだった。
#!/bin/sh
set -e
pattern=$1
case "$GITHUB_REF" in
"")
echo "\$GITHUB_REF is not set"
exit 1
;;
$pattern)
echo "$GITHUB_REF matches $pattern"
exit 0
;;
*)
echo "$GITHUB_REF does not match $pattern"
exit 78
esac
$GITHUB_REF
はWorkflow実行毎に設定されている環境変数で、Workflow実行時のブランチ名やタグ名が取得できる。
- Environment variables | GitHub Actions
GITHUB_REF
The branch or tag ref that triggered the workflow. For example, refs/heads/feature-branch-1. If neither a branch or tag is available for the event type, the variable will not exist.
終わりに
今回はTwitterで@teitei_kさんと話題に上がったので他の確認よりまず先にやってみた。$GITHUB_REF
が取れるところまでは知っていたので、スクリプトを自作しようと思ったがすでに公式で提供済みのものがあった。
Beta版だからなのかそういう設計思想のなのか(おろらく後者だが)、GitHub ActionsではCircleCIなどほどとリッチなYAMLのような設定を書けない。 ただ、複雑な設定を書き始めると属人化しはじめたりするし、YAML地獄になったりしがちだ。私がGoのシンプルなところが好きなせいなのもあるかもしれないが、このActionとして小さく設定する今の塩梅が好きだ。実行ステータスを表示できるバッジなどが早くほしいのと、publicリポジトリはまだpush通知をトリガーにしかできないので、PRのイベントにも対応されると嬉しい。
参考
- budougumi0617/actions-filter-branch
- GitHub Actions: みなさんが開発し、GitHubで実行
- GitHub Actions
- actions/bin
- Environment variables | GitHub Actions