Bitbucket PipelinesのSlack Notifyを使ってDiscordに通知

DiscordのWebhook URLの末尾に /slack を付け加えることでSlack互換のWebhookとして利用できる仕組みがある

これを利用して、Bitbucket PipelinesのSlack Notifyを使ってDiscordに通知を送れるようにする

DiscordのWebhook URLを作成する

Discordのサーバ設定、またはチャンネル設定を開き、連携サービスを選択し、ウェブフックから新しいウェブフックを選択

アバター、表示名の入力、通知先チャンネルを選択し、ウェブフックURLをコピーを押下してURLを控えておく

Webhook設定

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_FLAGtrueに設定(–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ボタンを押下し、フィンガープリント値を登録しておく

fingerprint

実行例

pipelineの実行結果

pipelines結果

Discordへの通知結果

Discord通知結果

参考