追記(2019-09-23):
⚠️ この記事の GitHub Actions は HCL 記法を使う古い方法です。現在は YAML 記法に変わりました。参考にしないで下さい。


このブログの CI には割高なので、CircleCI あたりに乗り換える予定です。

[2019-01-27-1] で書いたばかりですが、舌の根も乾かぬうちに GitHub Actions に移行してみました。

料金はさておき、たまたまクラスメソッドさんの記事 を見て移行出来そうだったことと、GitHub Actions は一度素振りしてみたかったからです。

GitHub Actions とは

CircleCI の Workflows と非常に良く似た機能で、Pipeline を組んで CI を実行することが出来ます。

現在はまだベータです。https://github.com/features/actions からリクエストすれば使えます。複数 Action 同時実行とか凝ったことはできないようです。時間がかかりすぎる Action も避けたほうが良いかも。

Action は自分で作ることも出来ますし、以下のような公開 Action を使うことも出来るようです。

日本語記事: GitHub Actions: みなさんが開発し、GitHubで実行 - The GitHub Blog - Japan

Heroku CI よりもハマりどころはありますが、作り方はとてもシンプルです。

  1. .github/main.workflow を作り、workflow と action を定義する
  2. 各 action に紐付いた Dockerfile を作る、または参照する

今回の実装

ファイル構成と実装はこんな感じです。

main.workflow は Terraform ユーザーには馴染みのある HCL で書きます。

今回は on = “push” なので、git push をトリガーにして、hadolint と shellcheck という自作の Action が動きます。

それぞれ .github/hadolint と .github/shellcheck 以下の Dockerfile を使う Action で、引数をそれぞれ指定しています。

resolves = [“hadolint”, “shellcheck”] という書き方だと並列に動きそうですが、現在は 1 Action ずつしか動かないようです。

GitHub 上での見え方

今回は on = “push” なので、以下のように Pullrequest の Checks タブから参照できます。

Pullrequest Checks

リポジトリの Actions タブからは、可視化された main.workflow を見られます。右側の “View main.workflow” から Visual editor に遷移することも出来ます。

Repository Actions

所感1

on には “push” 以外にも結構な数の Event name を指定できる ようです。“issues” と “pull_request” は実際に確認しました。

on = “issues” で Issue を作った時のコンテナ内の環境変数の例です。

GITHUB_ACTION=Hello World
GITHUB_ACTOR=masutaka
GITHUB_EVENT_NAME=issues
GITHUB_EVENT_PATH=/github/workflow/event.json
GITHUB_REF=refs/heads/master
GITHUB_REPOSITORY=masutaka/masutaka.net
GITHUB_SHA=d628d46a126e2e4900af10a067c4be80cf574cbb
GITHUB_WORKFLOW=New workflow
GITHUB_WORKSPACE=/github/workspace
HOME=/github/home
HOSTNAME=9be975ed25f0
MY_NAME=Mona
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/github/workspace

/github/workflow/event.json の中身は整形すると 160 行ほどで、先頭に “action”: “opened” と書いてありました。

{
  "action": "opened",
  "issue": {
    "assignee": null,
    "assignees": [],
    "author_association": "OWNER",
(snip)

これで on = “issues” の種類を判別できるようです。前述のリンクによると、“edited” や “deleted” など、全部で 14 種類あります。

Issue や Pullrequest を作ったら、GitHub Project に自動追加なんてことができそうですね。

所感2

各 Action は Dockerfile と entrypoint.sh をセットで作るのが良いと思いました。

実は今回の shellcheck はこれでも動きます。

action "shellcheck" {
  uses = "docker://koalaman/shellcheck:v0.6.0"
  args = ["script/*", ".github/**/entrypoint.sh"]
}

でも、自分でログをコントロールすることが出来ないので、CI の結果としては不親切になることがあります。entrypoint.sh を与えて、多少なりともログを出したほうが良いと思います。デバッグもしやすいですし。今回は sh の -x で簡素に出しました。

ちなみに hadolintshellcheck もベースの Docker Image に scratch を使っているため、echo コマンドさえありません。

hadolint に至っては docker run で -i を与えて、標準入力から渡す必要があるため、GitHub Actions では公式の Docker Image を使うことは出来ませんでした。

$ docker run –rm -i hadolint/hadolint:v1.15.0 hadolint - < Dockerfile

所感3

Dockerfile に以下の LABEL を付けると、Actions に icon や color が付いたりします。前述の図では紫マイクのアイコンがそれです。

  • com.github.actions.name
  • com.github.actions.description
  • com.github.actions.icon
  • com.github.actions.color

参考: GitHub Actions > Creating a Docker container > LABEL

でも不安定なのか、いくら設定しても変わらなかったり、気がつくと変わっていたり、よく分かりませんでした。GA になれば安定するのかな。

所感4

GitHub Actions が失敗しても特に通知はないので、実装が必要かも。

Slack でよければ以下が使えそうですが、私は Pushover を愛用しているので…。

CircleCI に移行しようかしら…(白目)