設定ファイル
-
version: 2
でCircleCI 2.0の設定と明示する
- build用のdocker imageはcircleciが用意しているものを使用する
基本的な流れは以下
- キーからキャッシュを復元
- もしvendorがなければ
dep ensure
を実行 - depもなければインストール
- dep自体とvendor以下をキャッシュに保存
- go build
#.circlci/config.yml
jobs:
build:
working_directory: /go/src/github.com/tanden/go-echo-with-mysql/
docker:
- image: circleci/golang:1.10
steps:
- checkout
- restore_cache:
keys:
- v1-vendor-{{ .Branch }}-{{ checksum "src/Gopkg.lock" }}
- v1-vendor-{{ .Branch }}
- v1-vendor
- v1-dep
- run:
name: dep ensure
command: |
cd src/
if [ ! -d vendor ]; then
if ! type dep >/dev/null 2>&1; then
go get -u github.com/golang/dep/cmd/dep
fi
dep ensure
fi
# ローカルとcircleci上でgo getしたdepのversionが異なると
# dep ensureしたときにGopkg.lockのchecksumが変わってしまい
# 別のcacheとして保存されてしまいrestore_cacheで取り出せない
# cacheしてるdepのversionはv0.5.0
- save_cache:
key: v1-vendor-{{ .Branch }}-{{ checksum "src/Gopkg.lock" }}
paths:
- src/vendor
- save_cache:
key: v1-dep
paths:
- /go/bin/dep
- run:
name: go build
command: |
go build -v -o src/app src/server.go
- persist_to_workspace:
root: .
paths:
- src/
workflows:
version: 2
build:
jobs:
- build
depとvendorのキャッシュ
パッケージをdep管理しているので、CircleCI上のコンテナでdep ensure
コマンドを実行しvendor以下にパッケージをインストールします。
ただ、Gopkg.lockの内容に変化がない(使用しているパッケージが変わらない)場合、前回と同じインストールされたパッケージを使いたい。インストールに6〜7秒かかるので(毎回行われるので合計するとバカになりません)
なので、depコマンド自体と、vendor以下をCircleCIのキャッシュ機能をつかってキャッシュさせます。
キャッシュクリアするにはキーの名前を変える
キャッシュクリアをするために、都度キーの名前を変えるてしまうのがよいようです(restore_cacheをいちいち消して、キャッシュをリストアせずに新しくインストールしてキャッシュした値を更新する、、、などしなくてよくなります)
ドキュメントでは、v1
などのバージョンプレフィックスをつけてキーの名前を変えていくことを推奨しています
https://circleci.com/docs/2.0/caching/#clearing-cache
はまったこと:vendorをキャッシュできない
vendorをキャッシュできず、はまりました。
src/Gopkg.lockのchecksumの値をキャッシュのキーにしているのですが、commitしているGopkg.lockとCircleCIのコンテナ上にcloneしたGopkg.lockのchecksumが異なりrestore_cacheでリストアできませんでした。
自分のローカルのdepのバージョンが古く、最新のdep(CirclCIでgo get
したdepのバージョン)では、Gopkg.lockのフォーマットが異なるようです。
- checkoutでcloneしたリポジトリ上のGopkg.lockのchecksumでrestore_cacheを行う
- restoreできない
- 再度 dep eusureする
- Gopkg.lockのchecksumが変わる
- 変わった後のchecksumを使ったkeyでキャッシュを保存してしまう
- 1でrestoreできない
CircleCI上のコンテナにインストールしているdepのバージョンと、ローカルのバージョンを同じにして再度dep init
を行なって、新しいGopkg.lockをcommitしなおすと想定通りキャッシュしてくれるようになりました!