DiscordのWebhook URLの末尾に /slack を付け加えることでSlack互換のWebhookとして利用できる仕組みがある
これを利用して、Bitbucket PipelinesのSlack Notifyを使ってDiscordに通知を送れるようにする
DiscordのWebhook URLを作成する
Discordのサーバ設定、またはチャンネル設定を開き、連携サービスを選択し、ウェブフックから新しいウェブフックを選択
アバター、表示名の入力、通知先チャンネルを選択し、ウェブフックURLをコピーを押下してURLを控えておく
Bitbucket Pipelinesの有効化
BitbucketリポジトリのRepository settingからPIPELINESセクションのSettingsを選択、Enable PipelinesのスイッチをONにする
bitbucket-pipelines.ymlの作成
リポジトリ内ルート直下にBitbucket Pipelinesの定義ファイルであるbitbucket-pipelines.yml
を作成する
サンプル構成として
- NuxtJSの静的サイト生成機能を使ってコンテンツを生成
- 本番サーバにrsyncで転送(SSHを使用)
- 最後にDiscordに通知
- pipelinesの実行はBitbuket上のリポジトリのmasterに変更(push)したとき
とする
image: node:lts-alpine
pipelines:
branches:
master:
- step:
name: Build
caches:
- node
script:
- echo "Building and Generating"
- npm install
- npm run build
- npm run generate
artifacts:
- dist/**
- step:
name: Deploy
deployment: production
script:
- echo "Deploying to production environment"
- pipe: atlassian/rsync-deploy:0.6.0
variables:
USER: $DEPLOY_USER
SERVER: $DEPLOY_HOST
REMOTE_PATH: $DEPLOY_PATH
LOCAL_PATH: 'dist/*'
SSH_PORT: $DEPLOY_PORT
EXTRA_ARGS: '--exclude-from=deploy-list.txt'
DELETE_FLAG: 'true'
- apk --update --no-cache add gettext
- envsubst < "payload.json.template" > "payload.json"
- pipe: atlassian/slack-notify:2.0.0
variables:
WEBHOOK_URL: $WEBHOOK_URL
PAYLOAD_FILE: payload.json
- ベースとなるDockerイメージは公式イメージのnodeから最新のLTS版を使用
- コンテンツを生成するビルドステップと、デプロイ先に転送してDiscord通知するデプロイステップで構成
ビルドステップ
- npmパッケージのインストール、nuxtjsのビルド、静的コンテンツ生成を行う。
- npmコマンドはNuxtJSのcreate-nuxt-appで作成した際に既に定義されているのものを使用(package.json)
- 生成したものはdistフォルダに出力されるので、デプロイステップで利用するのためアーティファクトを使って共有する
デプロイステップ
-
本番環境へのデプロイの想定なので、使用する環境変数はproduction用に設定したものを使用する
-
RSYNC deployを使用してdist/以下を転送する
-
同期したいため不要なファイルを削除するためDELTE_FLAGをtrueに設定(–delete-afterオプションが有効になる)
-
同期先で消されたくないファイル・フォルダがあるため、追加でrsyncの–exclude-fromオプションを使用し、リポジトリルート直下にdeploy-list.txtを作成して、それらを列挙しておく
-
あらかじめ想定通りに動作するかローカルでrsyncコマンドを検証しておく
rsync -nv -rp --delete-after --exclude-from=deploy-list.txt -e 'ssh -p SSHポート番号 -o StrictHostKeyChecking=no' dist/* SSHユーザー名@SSHホスト名:デプロイ先パス
-
-
Slack Notifyを使用して、Discordに通知する
-
Slack Notifyが2.0.0になった際、メッセージのペイロードのデフォルトがBlock Kitを使用するようになったため、Basic exampleをそのまま利用するとエラーになる
INFO: HTTP Response: {"message": "Cannot send an empty message", "code": 50006}
DiscordのSlack互換仕様がBlock Kitに対応していないためなので、Advanced exampleにあるPAYLOAD_FILEを使用するケースを利用してカスタムペイロードファイルを使って、旧形式でメッセージを送るようにする
-
ペイロードファイル内の文言は固定値なので、環境変数を参照したい場合はenvsubstコマンドを使用して、payload.json.templateからあらかじめ環境変数を展開したペイロードファイルをSlack Notify実行の前に作成しておく。(もしくな何らかの方法で動的にペイロードファイルを生成する)
-
nodejs公式イメージにはenvsubtコマンドが存在しないため、apkコマンドでgettextパッケージを追加する
-
payload.json.template
リポジトリ内ルート直下にpayload.json.template
を作成
{
"text": "これはtextの内容です",
"attachments": [
{
"color": "#439FE0",
"pretext": "Notification sent from <https://bitbucket.org/${BITBUCKET_WORKSPACE}/${BITBUCKET_REPO_SLUG}/addon/pipelines/home#!/results/${BITBUCKET_BUILD_NUMBER}|Pipeline #${BITBUCKET_BUILD_NUMBER}>",
"text": "https://example.jp が更新されました"
}
]
}
Slack Notifyの旧バージョンのペイロード部分を元に、互換URLで利用できないものを取り除き(mrkdwn_in)、ペイロード仕様にあるtextを追加。仕様としてはattachmentsがあればtextは不要だが、予備として含めることが推奨されている
pretextの値は、Slack Notifyのデフォルト値を環境変数を使って使用
その他の定義されている環境変数は変数とシークレット | Bitbucket Cloud | アトラシアン サポートより
<URL|Text>
の部分は[Slackのテキストフォーマット仕様](Formatting text for app surfaces | Slack
https://api.slack.com/reference/surfaces/formatting)でリンクで表現される
環境変数の定義
BitbucketリポジトリのRepository settingからPIPELINESセクションのDeploymentsを選択、Production environmentsセクションに以下の環境変数を定義しておく
環境変数名 | 値 |
---|---|
DEPLOY_USER | デプロイ先SSH接続ユーザー名 |
DEPLOY_HOST | デプロイ先SSHホスト名 |
DEPLOY_PORT | デプロイ先SSHホスト ポート番号 |
DEPLOY_PATH | デプロイ先パス |
WEBHOOK_URL | Discord Webhook URL(Slack互換形式) |
Discord Webhook URLのSlack互換形式は、Webhook URLの後ろに**/slack**を付け加えたもの
Webhook URL:https://discord.com/api/webhooks/000000000000000000/AbCdEfGHiJkLmNoPqRStUvWxYz0123456789aaaaaaaaaaaaa_zzzzzzzzzzzzzzzzzz
Slack互換URL:https://discord.com/api/webhooks/000000000000000000/AbCdEfGHiJkLmNoPqRStUvWxYz0123456789aaaaaaaaaaaaa_zzzzzzzzzzzzzzzzzz/slack
デプロイ先SSH接続設定
BitbucketリポジトリのRepository settingからPIPELINESセクションのSSH Keysを選択、SSH Keyセクションで、SSH鍵を生成し、公開鍵をデプロイ先サーバの ~/.ssh/authorized_keys に追記しておく
同じくKnown hostsセクションで、Host addressにデプロイ先SSHホストを入力し、Fetchボタンを押下し、フィンガープリント値を登録しておく
実行例
pipelineの実行結果
Discordへの通知結果