GitHubにPushしたらGoogle Cloud BuildでCIが動いてSlack通知するやつ

## はじめに

[Google Cloud Build](https://cloud.google.com/cloud-build/?hl=ja)

Cloud BuildでPHPのアプリケーションでphpunit動かしてslackに通知するやつをやります

## 参考

GCP公式ドキュメント

* [GitHub でのビルドの実行](https://cloud.google.com/cloud-build/docs/run-builds-on-github?hl=ja)
* [サードパーティ サービスの通知の構成](https://cloud.google.com/cloud-build/docs/configure-third-party-notifications?hl=ja)

## 準備

* Googleアカウント（要GCP無料トライアル）
* [Cloud SDK](https://cloud.google.com/sdk/docs/quickstarts?hl=ja) をインストールして `gcloud` コマンドが利用できるように
* 対象とするPHPアプリケーションのGitHubリポジトリ

今回は以下のリポジトリをサンプルとして利用します

https://github.com/halnique/cloud-build-sample

## 手順

### 1. GCPプロジェクト作成

<img width="1380" alt="image3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/b6907526-05c6-ad8c-8249-d5e7d67d4190.png">

<img width="501" alt="image4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/3f55b149-b8b6-3634-d0f8-a5f2f3d267db.png">

<img width="1379" alt="image5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/79ed0e66-1007-385d-c68d-f3805a424059.png">

できあがり

### 2. Cloud Build API有効化

<img width="1379" alt="image6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/83a5e0db-003b-2576-3bb0-01ddcef7d207.png">

<img width="1378" alt="image7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/4806c474-2042-bebd-501b-6a9a0e0eb023.png">

有効にします

<img width="1380" alt="image8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/0f55ac49-8db9-eb7c-08dd-b0188b269c4e.png">

有効になりました

### 3. GitHub側でCloud Build Appのセットアップ

GitHub marketplaceで [Google Cloud Build](https://github.com/marketplace/google-cloud-build) applicationを有効化します

対象リポジトリはあとから変更できますが、とりあえず**Only select repositories**にしておくのがよさそう

<img width="1379" alt="image9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/7b2ccee9-ea49-b4d8-10c2-803aa3b1de6a.png">

この設定が完了すれば、ひとまずPull Request作成時にCloud Buildが動く状態にはなります

### 4. cloudbuild.yamlを作成

Cloud BuildはDockerfileかcloudbuild.yamlファイルをベースにビルドを実行しますが、Dockerfileを利用する手順はドキュメントにも記載されているので、ここではcloudbuild.yamlファイルを使ってみます

Cloud Buildでやりたい処理は以下

* ソースコードをclone
* composer install
* phpunit実行

追加するcloudbuild.yamlの中身はこんな感じ

```yaml
steps:
- name: 'gcr.io/cloud-builders/git'
  args: ['clone', 'https://github.com/halnique/cloud-build-sample']
  id: git clone
- name: 'gcr.io/${PROJECT_ID}/composer'
  args: ['install', '--no-interaction', '--no-suggest']
  id: composer install
- name: 'gcr.io/${PROJECT_ID}/composer'
  args: ['test']
  id: phpunit
timeout: 500s
```

※ composer.jsonにphpunitの実行を `test` コマンドとしてscriptsに追加しています

`gcr.io/${PROJECT_ID}/composer` というイメージはCloud Builders コミュニティで提供されているものなので、自分でイメージビルドしてプロジェクトの [Container Registry](https://cloud.google.com/container-registry/?hl=ja) に登録しておく必要があります

`gcr.io/cloud-builders/git` の方は公式提供なのでそのまま利用可能です

### 5. Container Registryにイメージを登録

[コミュニティのGitHubリポジトリ](https://github.com/GoogleCloudPlatform/cloud-builders-community) のREADMEを参考にします

```
git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
cd cloud-builders-community/composer
PROJECT_ID=xxxxxxxx
gcloud --project ${PROJECT_ID} builds submit --config cloudbuild.yaml .
```

※ PROJECT_IDは自分のものに変更してください

終わったらConteiner Registryにアクセスしてみます

<img width="1374" alt="image12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/c166de37-fc33-8485-6e81-21e2e54f167f.png">

登録されたみたいです

この状態でCloud Buildが通るはずなので、先ほどのcloudbuild.yamlを含めた状態で一度適当なPull Requestを作ってみます

<img width="1370" alt="image13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/c9c596fe-aad6-8789-5ed6-0157f4292d9b.png">

<img width="1377" alt="image14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/10955d7a-eb54-98a3-5358-769ab98ec491.png">

動いたようです

### 6. Slackアプリを作成

Slack Appの提供は現状ないみたいなので、自分で作成します

https://api.slack.com/apps

<img width="1371" alt="image15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/c751e8a6-38fc-5685-0141-19659446d368.png">

適当に作成し、Incoming Webhookを有効にします

<img width="1377" alt="image16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/1b0e16fa-f87d-7f9d-504d-d253cb4b64d4.png">

**Add New Webhook to Workspace** からCloud Buildが通知するチャンネルを選択します

<img width="1374" alt="image17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/c77363aa-36fb-bdf6-a014-e999978ba48d.png">

これでWebhook用のURLが手に入ります

### 7. Webhookを叩くCloud Functionsを作成

Cloud Buildをトリガーに実行される [Cloud Functions](https://cloud.google.com/functions/?hl=ja) を作成し、その中でSlackのWebhookを叩くという流れです

※ AWS詳しい人はLambdaみたいなイメージ

Cloud Functionsへのデプロイは [リポジトリ](https://github.com/halnique/cloud-function-slack-sample.git) を用意しておいたので使うと楽かもしれません

```
git clone https://github.com/halnique/cloud-function-slack-sample.git
cd cloud-function-slack-sample

PROJECT_ID=xxxxxxxx
SLACK_WEBHOOK_URL=yyyyyyyy

gcloud --project ${PROJECT_ID} functions deploy subscribeSlack --trigger-topic cloud-builds --runtime nodejs10 --set-env-vars "SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL}"
```

PROJECT_IDとSLACK_WEBHOOK_URLをよしなに変更して実行してください

<img width="1378" alt="image18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/53014268-f15c-40e5-2894-3f96c21ffc40.png">

完了したらCloud Functionsで確認すると、なにやらできあがってます

これで完成です

Pull Requestを作成してみます

<img width="1368" alt="image19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/adc02c53-9c65-1599-d607-902852b116b6.png">

<img width="688" alt="image20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138022/d92add0d-a564-56b7-b3c6-21855b47b58a.png">

できた

## まとめ

基本的に公式ドキュメント見ながらやればできますが、思っていたより簡単でした

記事に上げているGCPプロジェクトは削除済みですが、GitHubリポジトリの方は公開してますので参考にしてもらって大丈夫です