Posted at

Cloud Build上でgoapp testを実行する

More than 1 year has passed since last update.


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 kms4でrepository上のserviceAccountKey.json.encをdecrypt5しておきます。

decryptしたserviceAccountKey.jsonGOOGLE_APPLICATION_CREDENTIALSで指定することでcloud.google.com/go6から透過的に使えるようになります。





  1. 別途goappに実行権限をつけて、PATHも通したimageを用意してGCRにpushしておけば簡単に使えますが、gcr.io/cloud-buildersはCloud Build上でcacheされていて高速に使えるので、gcr.io/cloud-builders/gcloudを使います。 



  2. GAE/Go (+dep) で gcloud app deploy する為の構成を参考にしてます。事前にsymlinkを作ってあげる必要があります。 



  3. google-cloud-go-testingにFirestoreのmockはないのと、Cloud Storageのmockも使いにくかったので。。。 



  4. keyring, keyは適当です 



  5. 事前にIAMでCloud Build用のサービスアカウントにKMSの権限をつけておく必要があります 



  6. Getting Started with Authenticationを参照