GitHub Actions のワークフローで Go 1.11 Modules のキャッシュを扱う
GitHub Actions で Golang の vet と test を実行したいと思います。
( ※実際には Go 1.10 からは go test
の前に go vet
が実行されますが、2つ以上のコマンドを実行したい場合を想定しています。)
ワークフローを以下のように定義しました。
workflow "vet and test" { on = "push" resolves = [ "vet", "test" ] } action "vet" { uses = "docker://golang:1.11" runs = "go" args = ["vet", "./..."] } action "test" { uses = "docker://golang:1.11" runs = "go" args = ["test", "./..."] }
GitHub Actions では /github/workspace
がワークスペースとなります。
また、使用している golang の公式Dockerイメージでは $GOPATH
は /go
に設定されます。
Go 1.11 では $GOPATH
の外では Modules (vgo)が利用されるので、 go vet
および go test
のそれぞれで依存モジュールのダウンロードを行いました。
同じモジュールを二度もダウンロードする必要はありません。一度だけダウンロードするようにしてみましょう。
Modules のキャッシュは $GOPATH/pkg/mod/cache
以下に配置されるため、そのままでは GitHub Actions のアクション間でキャッシュを共有することはできません。
ですが、少し工夫をすることでこれを使い回すことができます。
vendor ディレクトリを利用する方法 (失敗)
go mod vendor
は依存するモジュールをダウンロードして vendorディレクトリ に配置してくれます。
GO111MODULE=on
の状態で vendorディレクトリ を作成し、次のアクションでは GO111MODULE=off
にすることで、 vendorディレクトリを利用することができます。
が、 GO111MODULE=off
にした場合、( インポートを github.com
から始めていると )自身のパッケージが解決できず、 失敗してしまいます。
無理やりならできるかもしれませんが、vendor は使わない方法にしました。
ワークスペース以下に $GOPATH を設定する方法
ワークスペース以下に作られたファイルやディレクトリは、次のアクションに引き継がれます。
これを利用し、 $GOPATH
をワークスペース以下に設定することで Module のキャッシュも渡してやることができます。
環境変数は action
の env
で設定することができます。
出来上がったワークフローは以下の通りです。
workflow "vet and test" { on = "push" resolves = [ "vet", "test" ] } action "download" { uses = "docker://golang:latest" env = { GOPATH = "/github/workspace/.go" } runs = "go" args = ["mod", "download"] } action "vet" { uses = "docker://golang:latest" needs = ["download"] env = { GOPATH = "/github/workspace/.go" } runs = "go" args = ["vet", "./..."] } action "test" { uses = "docker://golang:latest" needs = ["download"] env = { GOPATH = "/github/workspace/.go" } runs = "go" args = ["test", "./..."] }
実行した場合の test のログは以下のようになりました。
ダウンロードのログは出ていませんね。
### STARTED test 21:31:58Z Already have image (with digest): gcr.io/github-actions-images/action-runner:latest ? github.com/duck8823/duci [no test files] ok github.com/duck8823/duci/application 0.016s ? github.com/duck8823/duci/application/cmd [no test files] ok github.com/duck8823/duci/application/context 0.008s ok github.com/duck8823/duci/application/semaphore 0.010s ? github.com/duck8823/duci/application/service/docker [no test files] ? github.com/duck8823/duci/application/service/docker/mock_docker [no test files] ok github.com/duck8823/duci/application/service/git 0.045s ? github.com/duck8823/duci/application/service/git/mock_git [no test files] ok github.com/duck8823/duci/application/service/github 0.006s ? github.com/duck8823/duci/application/service/github/mock_g ...
今回のケースでは、並列でダウンロードする場合もそんなに実行時間が変わるような変更はしていません。
ですが、ダウンロードは少なくして負荷をあまりかけないようにしたいですね。