My External Storage

Jan 11, 2019 - 5 minute read - Comments - github

GitHub Actionsで特定のブランチのときのみワークフローを実行する #github #actions #ci

2019/01現在Public BataのGitHub ActionsでCircleCIのbranches only相当の処理を出来ないか調査した。

Failed

TL;DR

サンプルブランチは以下。

なお、この記事は2019/01/11時点で最新のGitHub Actionsの情報になる。(2018/12/18リリースのPublic BETA版)

GitHub Actionsとは

ここではGitHub Actionsの詳細は省くが、GitHub Actionsは現在Public BETA版が公開されているGitHub公式のワークフローの自動化サービスだ。

まだ利用できない方は以下のページのSign up for the betaボタンをクリックしておけばいずれリポジトリに「Actions」タブが着くようになる

GitHub Actionsでは、一連の処理のまとまりをWorkflow、各処理はActionと定義している。各Actionはそれぞれで「別の」コンテナを起動して実行される。コンセプトはGCPのCloud Buildに近い。 Workflowの定義は/.github/main.workflowファイルをリポジトリに配置することで設定でき、GitHub上で該当ファイルを開くとGUIエディタからも編集できる。

やりたいこと

CI/CDを設定していると、例えば、masterブランチが更新されたときだけ実行されるデプロイジョブなどを作っていないだろうか。 CircleCIでいうと、branches only相当の処理になる。

これをGitHub Actionsでも設定できるのか調べた。

actions/bin/filterを使う

実は公式ですでに用意されているAction用のコンテナがあるのでそれを使えば簡単に実現できた。

GUIエディタからも選ぶことができる。

Filters for GitHub Actions

今回は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"]
}

work flow

このWorkflowはリポジトリにpushイベントが発生されるたびに実行される。

実行した結果が以下だ。masterブランチのときは最後までWorkflowが実行される。

Succeeded

masterブランチでないときはNeutralというstatusでWorkflowは最後まで実行されなかったので、意図通りブランチ名でWorkflowを制御できた。

Failed

actions/bin/filterで行なっていること

これだけだと寂しいので、actions/bin/filterの中も確認してみた。 リポジトリの中を見るといくつかの簡単なスクリプトが用意されており、READMEに書かれている通りに使えばよい。

スクリプトの中身も非常にシンプルで、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実行時のブランチ名やタグ名が取得できる。

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のイベントにも対応されると嬉しい。

参考

関連記事