GitHub Actions で Go言語の lint と test を実行する
はじめに
黒澤です。皆さんは GitHub Actions のベータに当選しましたでしょうか。 私は11月の頭ぐらいに当選していたのですが、当時は private リポジトリ限定で使える仕様だったため使うのを諦めていた勢です。
ですが先日ついに public リポジトリにも解禁されていたので軽く使い方を書いていこうと思います。
Enabling Actions on Public Repositories | GitHub Developer Guide
ベータ権の申し込みとかそんなの知らない!って人はこちらのページからエントリーできます。
GitHub Actions とは
2018年10月の GitHub Universe というイベントで発表された GitHub の新機能です。 ワークフローをコードで書き、GitHub のイベントと連動して自動で実行することができます。
例えば、GitHub に push が行われたら Docker image をビルドしてデプロイする、みたいなワークフローを GitHub Actions で実現できます。
ワークフローの具体例は公式ブログや GitHub Universe の Live 等に事例がいっぱい乗っているのでそちらも参考になります。
GitHub Actions で Go言語の lint を test を実行する
今回はその GitHub Actions を使って Go言語の lint と test を実行します。 今までなら外部の CI サービスを使って実現していたことが GitHub Actions を使うことで GitHub で完結できるようになりました。便利!
今回の実現するワークフローのディレクトリ構成は以下のようになっています。
$ tree -a . ├── .github │ ├── actions │ │ └── golang │ │ ├── Dockerfile │ │ └── entrypoint.sh │ └── main.workflow ├── go.mod ├── main.go └── main_test.go
.workflow
ファイル
GitHub Actions では .github/main.workflow
ファイルにワークフローを定義していきます。
workflow "Golang workflow" { on = "push" resolves = ["Test"] } action "GolangCI-Lint" { uses = "./.github/actions/golang" args = "lint" } action "Test" { needs = ["GolangCI-Lint"] uses = "./.github/actions/golang" args = "test" }
上のファイルをビジュアル化したものがこちら
なんとなく雰囲気は伝わったでしょうか。 それぞれ解説をしていきます。
ワークフローの定義です。
workflow "Golang workflow" { on = "push" resolves = ["Test"] }
on
でワークフローがキックされるイベントを指定します。この場合は push イベントに反応してワークフローがキックされます。 サポートされているイベント一覧はこちらのドキュメントを参照してください。resolves
にワークフローの終点のアクションを指定します。それぞれのアクションに依存関係を定義することができ、依存しているワークフローを含めてまとめて実行されます。
次に、アクションの定義です。
action "GolangCI-Lint" { uses = "./.github/actions/golang" args = "lint" } action "Test" { needs = ["GolangCI-Lint"] uses = "./.github/actions/golang" args = "test" }
GitHub Actions は Docker コンテナ内で実行されます。実行に使われる Docker image は DockerHub などで公開されているものや、リポジトリ内にある Dockerfile から作成したものを使用することができます。 今回は Dockerfile から image を作成します。
uses
に Dockerfile が置いてあるディレクトリを指定します。DockerHub の image を使う時などは指定方法が変わります。ドキュメントはこちらneeds
には依存関係を指定します。 actionTest
は actionGolangCI-Lint
に依存していることがわかります。args
に引数をしていします。今回は lint と test で共通の Docker image を使用しており、引数で制御を行なっています。
ここまでが .workflow
の解説です。
Dockerfile & entrypoint.sh
今回使用する Dockerfile と ENTRYPOINT のシェルスクリプトです。
FROM golang:1.11.4 LABEL "name"="Golang workflow" \ "maintainer"="Dai Kurosawa <hogehoge@example.com>" \ "com.github.actions.icon"="code" \ "com.github.actions.color"="green-dark" \ "com.github.actions.name"="golang workflow" \ "com.github.actions.description"="This is an Action to run go and golangci-lint commands." ENV LINT_VERSION="v1.12.5" COPY entrypoint.sh /entrypoint.sh RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin ${LINT_VERSION} \ && chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]
#!/bin/bash APP_DIR="/go/src/github.com/${GITHUB_REPOSITORY}/" mkdir -p ${APP_DIR} && cp -r ./ ${APP_DIR} && cd ${APP_DIR} export GO111MODULE=on go mod tidy go mod verify if [[ "$1" == "lint" ]]; then echo "#######################" echo "# Running GolangCI-Lint" golangci-lint --version golangci-lint run --enable-all --disable gochecknoglobals --disable gochecknoinits fi if [[ "$1" == "test" ]]; then echo "#######################" echo "# Running Test" go test ./... -race fi
今回は GolangCI-Lint という lint を使用します。 この lint を使用するとさまざな Go言語の lint をまとめて実行してくれます。 GolangCI については以前ブログを書いたのでこちらもご覧ください。
こちらのファイルについては特に解説することもないのですが一点だけ、
APP_DIR="/go/src/github.com/${GITHUB_REPOSITORY}/" mkdir -p ${APP_DIR} && cp -r ./ ${APP_DIR} && cd ${APP_DIR}
ここの処理で GOPATH
配下にソースを突っ込んでいます。
今回の例では Modules を使用して依存関係を解決しているので GOPATH
に縛られることもないのですが、使用しない場合などは GOPATH
配下にソースを移動させてあげましょう。
Go言語を使用したワークフローを作成する場合はテンプレート的に書いておくのもアリかもしれません。
今回の例とは違うパターンで dep などを使用して依存関係を解決する際は Docker iamge に含めておくことも忘れずに。
実行する
ファイルを用意できたら GitHub に push してあげるとワークフローが実行されます。 ベータに当選している人なら Actions ってタブが見えていると思います。
失敗した場合はこのような感じ。
Log
をクリックするとアクション中に標準出力に吐き出されたログやメッセージを確認できます。失敗した原因を確認する際もここから見ます。
中は標準出力に吐き出されたものがそのままずらっと並んでいるだけなので、テストを失敗した部分だけ見たい場合などは見づらいかもしれません。そこは実行する側で見やすくしてあげるなどの工夫が必要っぽいです。
PR 画面から見るとこんな感じ。
おわりに
GitHub Actions、いかがでしたでしょうか。
今回は CI っぽく使って見ましたが、ワークフローを自動化するものなので他にも色々なことが実現できます。 公式ドキュメントに色々書いてあるので見てみると良いかもしれません。
GitHub Actions | GitHub Developer Guide
GitHub Actions はまだベータで、今後もっと使いやすくなっていくと思うので期待ですね!