tl;dr
- GAE/GoのCI/CDでCloud Buildを使う
-
aetest
を使ったtestを実行するため、goapp test
をCloud Build上で実行したい - 最新のGCP SDKではgoappを簡単には使えなくなっているので、
gcr.io/cloud-builders/gcloud
を使う場合ひと工夫必要である
goapp test
GAE/Goでappengine.NewContext
に依存したtestを実行するためには、aetestが必要になります。
aetest
を使ったtestを実行するためにはgoapp testが必要となります。
Cloud Build上のGCP SDK
CI/CDをCloud Buildで行います。
ほぼGithubのprivate repositoryであってもほぼ無料で使用できるのと、GAEへのdeployなどIAMで権限管理できるのでGCP上にアプリケーションを構築するのであれば使わない理由はないといえます。
Cloud BuildでGCP SDKを使ったbuild pipelineを構築する場合、gcr.io/cloud-builders/gcloudを使うことになると思います。
これは割と最新のGCP SDKがinstallされたimageになります。
ただ最近のSDKだとapp-engine-go
componentをinstallしていても、goapp
は簡単には使えないようになっています。
これはgcr.io/cloud-builders/gcloud
であっても同様で、goapp
自体存在はしているものの、PATH
が通ってなかったり、実行フラグが立っていないので使うにはひと手間必要となります。
goappのpathを調べる
gcr.io/cloud-builders/gcloud
上でgoappがどこに存在しているのかを調べるために、gcr.io/cloud-builders/gcloud
を手元にpullしてきて入ってみます。
$ docker run --rm --name gcloud --entrypoint bash -it gcr.io/cloud-builders/gcloud
root@99f4e01f618f:/# which gcloud
/builder/google-cloud-sdk/bin//gcloud
root@99f4e01f618f:/# ls -l /builder/google-cloud-sdk/platform/google_appengine/ |grep goapp
-rw-r--r-- 1 root root 4798 Jul 14 03:17 goapp
ありました、/builder/google-cloud-sdk/platform/google_appengine/goapp
です。
ただ実行権限はついてませんね。
まあgoapp
自体はただのpythonスクリプトなので、python経由で叩けば問題なしです。
cloudbuild.yamlに記述
これまで調べた内容を元に以下1のような感じになります。
steps:
- name: gcr.io/cloud-builders/gcloud
env:
- 'GOPATH=/workspace/gopath'
entrypoint: python
args: ['/builder/google-cloud-sdk/platform/google_appengine/goapp', 'test', './app']
id: goapp-test
GOPATH
を設定しているのは、gcloud deploy
でGAEのdeployをするためにGOPATH
をいじる2からです。
またいまやっているプロジェクトではGAEからFirestoreとCloud Storageにアクセスしており、testでもこれらのAPIを使う3ようにしています。そのため、serviceAccountKey.json
を渡してあげる必要があります。
KMSで暗号化したserviceAccountKey.json
を事前にserviceAccountKey.json.enc
などとしてrepositoryにaddしておきます。
これをCloud Build上でdecryptしてtestで使うようにします。
steps:
- name: gcr.io/cloud-builders/gcloud
args:
- kms
- decrypt
- --ciphertext-file=secrets/serviceAccountKey.json.enc
- --plaintext-file=secrets/serviceAccountKey.json
- --location=global
- --keyring=demo-keyring
- --key=demo-key
id: decrypt-service-account
waitFor: ['-']
- name: gcr.io/cloud-builders/gcloud
env:
- 'GOPATH=/workspace/gopath'
- 'GOOGLE_APPLICATION_CREDENTIALS=/workspace/secrets/serviceAccountKey.json'
entrypoint: python
args: ['/builder/google-cloud-sdk/platform/google_appengine/goapp', 'test', './app']
waitFor: ['decrypt-service-account']
id: goapp-test
事前にgcloud kms
4でrepository上のserviceAccountKey.json.enc
をdecrypt5しておきます。
decryptしたserviceAccountKey.json
はGOOGLE_APPLICATION_CREDENTIALS
で指定することでcloud.google.com/go6から透過的に使えるようになります。
-
別途
goapp
に実行権限をつけて、PATH
も通したimageを用意してGCRにpushしておけば簡単に使えますが、gcr.io/cloud-builders
はCloud Build上でcacheされていて高速に使えるので、gcr.io/cloud-builders/gcloud
を使います。 ↩ -
GAE/Go (+dep) で gcloud app deploy する為の構成を参考にしてます。事前にsymlinkを作ってあげる必要があります。 ↩
-
google-cloud-go-testingにFirestoreのmockはないのと、Cloud Storageのmockも使いにくかったので。。。 ↩
-
keyring
,key
は適当です ↩ -
事前にIAMでCloud Build用のサービスアカウントにKMSの権限をつけておく必要があります ↩