Edited at

Cloud BuildをGitHubと連携させて、ビルド結果をSlackで通知する。

Cloud BuildがGitHubと連携できるようになっていたので、セットアップからSlack通知までの構築を試してみた。

Cloud FunctionsのソースはGitHubにもあげてます。


前提条件


  • gcloudがインストールされていること


Cloud BuildのGitHubアプリをインストールする

次のURLに行き、Cloud BuildのGitHubアプリを自分のGitHubアカウントにインストールする。

https://github.com/apps/google-cloud-build

インストールするとリポジトリの選択画面に遷移するので、好きなリポジトリまたはすべてのリポジトリを選択する。


これで、選択したリポジトリをpushすると自動でCloud Buildが動くようになる。

対象のリポジトリをあとから変更したいときは次のURLからGoogle Cloud Buildを選択し、Repository access -> Saveをクリックする。

https://github.com/settings/installations/


Slack通知用のCloud Functionを作る

新しいディレクトリを作って、その中に次のファイルを作る。


package.json

{

"name": "cloud-build-notification",
"version": "0.0.1",
"description": "Slack integration for Google Cloud Build, using Google Cloud Functions",
"main": "index.js",
"dependencies": {
"@slack/client": "3.9.0"
}
}


index.js

const IncomingWebhook = require('@slack/client').IncomingWebhook;

const webhook = new IncomingWebhook(process.env.SLACK_WEBHOOK_URL);

// subscribe is the main function called by Cloud Functions.
module.exports.subscribe = (event, callback) => {
const build = eventToBuild(event.data);

// Skip if the current status is not in the status list.
// Add additional statues to list if you'd like:
// QUEUED, WORKING, SUCCESS, FAILURE,
// INTERNAL_ERROR, TIMEOUT, CANCELLED
const status = ['SUCCESS', 'FAILURE', 'INTERNAL_ERROR', 'TIMEOUT'];
if (status.indexOf(build.status) === -1) {
return callback();
}

// Send message to Slack.
const message = createSlackMessage(build);
webhook.send(message, callback);
};

// eventToBuild transforms pubsub event message to a build object.
const eventToBuild = (data) => {
return JSON.parse(new Buffer(data, 'base64').toString());
}

// createSlackMessage creates a message from a build object.
const createSlackMessage = (build) => {
let message = {
text: `Build \`${build.id}\``,
mrkdwn: true,
attachments: [
{
title: 'Build logs',
title_link: build.logUrl,
fields: [{
title: 'Status',
value: build.status
}, {
title: 'Branch',
value: build.substitutions.BRANCH_NAME
}, {
title: 'Repository',
value: build.substitutions.REPO_NAME
}]
}
]
};
return message
}


参考:

https://cloud.google.com/cloud-build/docs/configure-third-party-notifications?hl=ja


作ったCloud Functionをデプロイする

デプロイする前にCloud Function用のCloud Storageを作る必要がある。

バケット名は世界中でユニークでないといけないので気をつける。

SlackのWebhook URLはココで新しいアプリを作成したあと、Incoming Webhooksから生成できる。

# ストレージバケットを作成する

BUCKET='<your storage bucket name>'
gsutil mb gs://$BUCKET

# Cloud Functionをデプロイする
SLACK_WEBHOOK_URL='<your webhook url>'
gcloud functions deploy cloud-build-notification-slack \
--stage-bucket $BUCKET \
--entry-point subscribe \
--trigger-topic cloud-builds \
--runtime nodejs8 \
--set-env-vars SLACK_WEBHOOK_URL=$SLACK_WEBHOOK_URL


リポジトリをpushして動作確認してみる

Cloud Buildはcloudbuild.yamlをビルド構成ファイルとして書くこともできるし、cloudbuild.yamlを書かなくてもDockerfileだけ置いておけばDockerイメージをビルドしてContainer Registryに保存するタスクが自動的に実行される。

今回はとりあえずシンプルにDockerfileでCIを動かしてみる。

GitHubアプリで設定した好きなリポジトリでDockerfileを書いて、pushする。

FROM alpine:3.9

RUN echo 'Hello world.'

うまく行っていれば、CIが動いてDockerイメージがContainer Registryに保存され、Slackにビルド結果の通知がくる。ちなみに、Container Registryに保存されるイメージ名はgcr.io/<プロジェクトID>/<リポジトリ名>になる。

スクリーンショット 2019-08-14 17.12.51.png

できた!!


おまけ

Cloud ConsoleからGUIで確認もできるけどCLIで確認したいときに。

Cloud Buildのビルド一覧を取得する。

gcloud builds list

Container Registryにあるイメージ一覧を取得する。

gcloud container images list


参考

https://medium.com/google-cloud-jp/try-github-cloudbuild-integration-5149175105fb