Google App Engine で始める Go 実践入門 Part 10 【Circle CI】

連載を通して簡単なブログアプリを作成しつつ Go/GAE について学んでいきます。
今回は Circle CI を使ってデプロイを自動化します。

- [Part 1. 『GO / Cloud SDK のインストール』](https://qiita.com/rema424/items/743bc508ef70cd980e17)
- [Part 2. 『GOPATH』](https://qiita.com/rema424/items/009f6345eb75a80bf369)
- [Part 3. 『プロジェクトの作成』](https://qiita.com/rema424/items/19b946c311f3b3b3f953)
- [Part 4. 『ディレクトリ構成』](https://qiita.com/rema424/items/1a6096c77b90ea350a26)
- [Part 5. 『Visual Studio Code』](https://qiita.com/rema424/items/b2ecdd2c7ec7fc1b0a7c)
- [Part 6. 『Hello World』](https://qiita.com/rema424/items/66ce1b02d7de588e63cf)
- [Part 7. 『リモートデバッグ』](https://qiita.com/rema424/items/996aaf0ab69670224af4)
- [Part 8. 『デプロイ』](https://qiita.com/rema424/items/dbf851908dbfc95f9b6f)
- [Part 9. 『Makefile』](https://qiita.com/rema424/items/3a099dfb023aa06086f5)
- [Part 10. 『Circle CI』](https://qiita.com/rema424/items/4dcb37346cecc544dfaa) ← イマココ
- Part 11. 『Dependency Injection』
- Part 12. 『ローカルDB with Docker』
- Part 13. 『gorm』
- Part 14. 『Cloud SQL』
- Part 15. 『Cloud SQL Proxy』
- Part 16. 『HTML』
- Part 17. 『CSS/JS』
- Part 18. 『Google Analytics』
- Part 19. 『Google Search Console』
- Part 20. 『A/B テスト』
- Part 21. 『ユーザーの作成』
- Part 22. 『Firebase Auth』
- Part 23. 『記事の作成』
- Part 24. 『コメントの作成』
- Part 25. 『ページネーション』

# Circle CI と GitHub リポジトリの紐付け

https://circleci.jp/vcs-authorize/

上記の URL にアクセスして Circle CI にログインします。
Circle CI へのログインには GitHub のアカウントを使用します。
ログインすると Circle CI のダッシュボード画面に遷移します。

ダッシュボードに移動できたら、GitHub のリポジトリと Circle CI のプロジェクトを紐付けます。

```
[サイドメニュー] > [ADD PROJECTS] > [対象リポジトリ] > [Set Up Project] > [Start building]
```

`Start building` をクリックすると Circle CI によるビルドが走ります。
ただし、Build Job を定義したファイルをまだ作成していないため、この時点では失敗します。

# 環境変数の設定

Job 定義ファイルの作成に先立ち、環境変数を Circle CI のプロジェクトに設定します。
設定する環境変数は次の 3 つです。

- GCP プロジェクト ID
- Deploy 用サービスアカウントの秘密鍵 (deploy.json) ([Part 8](https://qiita.com/rema424/items/dbf851908dbfc95f9b6f) で作成したもの)
- ゾーン

環境変数の設定は次の手順で行います。

```
[サイドメニュー] > [JOBS] > [該当リポジトリ] > [歯車アイコン] > [Environment Variables] > [Add Variable]
```

まずは GCP プロジェクト ID ですが、`GOOGLE_PROJECT_ID` という名称で環境変数に設定します。

次に秘密鍵ですが、こちらは `GCLOUD_SERVICE_KEY` という名称で環境変数に設定します。
秘密鍵の JSON ファイルの中身をそのままコピペで OK です。

ゾーンに関しては次のページを参考にお好きなものを選んでください。東京リージョンの場合は、`asia-northeast1-a`, `asia-northeast1-b`, `asia-northeast1-c` のいずれかになります。これを `GOOGLE_COMPUTE_ZONE` という名称で設定します。

[リージョンとゾーン | Google Cloud](https://cloud.google.com/compute/docs/regions-zones/regions-zones?hl=ja)

```
Name: GOOGLE_PROJECT_ID
Value: xxxxxxxxxxxx

Name: GCLOUD_SERVICE_KEY
Value: {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}

Name: GOOGLE_COMPUTE_ZONE
Value: asia-northeast1-x
```

# Job 定義ファイル

Circle CI における Job 定義ファイルは `config.yml` という名称で作成します。
この `config.yml` はプロジェクトルート直下に作成された `.circleci` という名称のディレクトリの下に配置します。

```sh
# プロジェクトルートに移動
cd $GOPATH/src/github.com/rema424/go-gae-blog-app-example

# ディレクトリ作成
mkdir .circleci

# Job 定義ファイルの作成
touch .circleci/config.yml
```

Job 定義ファイルを編集します。途中 GitHub ユーザー名やリポジトリ名が何箇所も出てきますので自分のものに置き換えてください。

```yml:.circleci/config.yml
version: 2.1

orbs:
  gcp-cli: circleci/gcp-cli@1.0.3

executors:
  gcloud:
    working_directory: ~
    docker:
      - image: google/cloud-sdk:latest

commands:
  give_execute_permission_to_appcfg:
    steps:
      - run:
          name: appcfg.pyに実行権限を付与
          command: |
            chmod +x /usr/lib/google-cloud-sdk/platform/google_appengine/appcfg.py
            chmod +x /usr/lib/google-cloud-sdk/platform/google_appengine/goapp
  install_make_command:
    steps:
      - run:
          name: makeコマンドをインストール
          command: apt-get install build-essential -y
  install_go:
    steps:
      - run:
          name: goをインストール
          command: |
            curl -O https://dl.google.com/go/go1.9.linux-amd64.tar.gz
            tar -C /usr/local -xzf go1.9.linux-amd64.tar.gz
            rm -rf go1.9.linux-amd64.tar.gz
  set_up_go_path:
    steps:
      - run:
          name: チェックアウトしたソースコードを GOPATH に配置
          command: |
            mkdir -p /root/go/src/github.com/<your-user-name>/<your-repository-name>
            mv ~/project/* /root/go/src/github.com/<your-user-name>/<your-repository-name>/
  install_dependencies:
    steps:
      - run:
          name: depで依存モジュールをインストール
          command: |
            export GOPATH=/root/go
            export PATH=/usr/local/go/bin:$GOPATH/bin:$PATH
            go get -u -v github.com/golang/dep/cmd/dep
            cd /root/go/src/github.com/<your-user-name>/<your-repository-name>
            dep ensure -v
jobs:
  deploy:
    executor: gcloud
    working_directory: ~
    steps:
      - checkout
      - gcp-cli/initialize
      - give_execute_permission_to_appcfg
      - install_make_command
      - install_go
      - set_up_go_path
      - install_dependencies
      - run:
          name: デプロイの実施
          command: |
            echo $PWD
            cd /root/go/src/github.com/<your-user-name>/<your-repository-name>
            echo $PWD
            export GOPATH=/root/go
            export PATH=$PATH:/usr/lib/google-cloud-sdk/platform/google_appengine
            make update version=$CIRCLE_SHA1
            make migrate version=$CIRCLE_SHA1
workflows:
  deploy_to_production:
    jobs:
      - deploy:
          filters:
            branches:
              only: master
```

これを GitHub のマスターブランチにプッシュすると Circle CI でビルド Job が開始され、App Engine にデプロイされます。

今後はマスターブランチにコミットが発生する度に自動でデプロイが実行されます。
もしもコミットはしたいけどデプロイはしたくないという場合は、コミットメッセージに `[skip ci]` または `[ci skip]` を含めるとビルド Job が回りません。

# おわりに

次回のテーマは『Dependency Injection』です。（~~2019/04/06 投稿予定~~  ~~Splatoonの練習が忙しくGW後半になります~~ 五月病になりました）

よかったら Twitter フォローしてね。[@_rema424](https://twitter.com/_rema424)