Beeeat’s log

Beeeat’s log

プログラミングで出くわした知識やツール、日常生活、働き方その他色々なことをメモしていくブログ

capistrano-releases-notificationでデプロイ周りのチーム内コミュニケーションが改善した話

capistrano-releases-notificationを導入したことでデプロイ周のチーム内コミュニケーションが改善されました。 今回はその時の話を書いていきます。
試したRubyのバージョンは2.6.5Capistranoのバージョンは3.10.1です。

f:id:bake0937:20191013144616p:plain

導入経緯

普段の業務でデプロイツールとしてCapistranoを使っているのですが、今のチームで以下の課題がありました。

  • 誰がどの環境に何の内容でデプロイしたかはCapistranoを実行した人しかわからない
    • revisions.logなどを見ればわかるが、わざわざサーバーにsshするのは手間
  • リリース報告が手動でSlackでコメントして連絡するため手間
  • staging環境やqa環境などを利用するときは台帳(誰がどの環境で何を検証しているかを記録する謎のスプレッドシート)に書いてチームメンバーに共有しているのだが、台帳のメンテを度々忘れてしまう

ということで、上記の課題を解決できる方法は何かないかを探してみた所、元同僚のkimromiさんがCapistranoでデプロイ時にSlackに通知をしてくれる便利なプラグイン(Gem)を公開していたことを思い出し、導入してみました。
また、このプラグインを導入することによってただSlack通知されるだけではなく、どのPullRequestでリリースしたかがわかるようになってさらに便利になりました✨。

kimromi.github.io

github.com

使い方

使い方については↑のkimromiさんの記事とリポジトリをご確認ください。
私なりに工夫した設定は以下に記載します。

ちょっと一工夫

ひとまず記事の内容を見て導入してみた結果、この時点でもだいぶ便利になったのですがチームメンバーから以下のフィードバッグを貰いました。

  • どの環境にもデプロイされたことはSlackに通知してほしい
  • staging(production以外)のSlack通知は以下の情報がほしい
    • デプロイした人
    • デプロイしたブランチ名
    • デプロイしたソースコードのコミットのURL

ということで、以下のように修正をしました。

  • どの環境にもデプロイされたことは通知してほしいとのことのため各deploy/以下に設定してあるafter 'deploy:finishing', 'release:notify'を削除し、config/deploy.rbに設定することで共通化
  • デプロイした人の情報はgitコマンドを利用して表示できるように設定
  • productionとstaging以外の環境がある場合はelsifで設定していく

config/deploy.rb

# config valid for current version and patch releases of Capistrano
lock "~> 3.10.1"

set :application, "アプリケーション名を入れる"
set :repo_url, "git@github.com:GitHubアカウント名/リポジトリ名.git"

# slack webhook
set :slack_endpoint, 'https://hooks.slack.com'
# 実際に使う場合、この値は環境変数に入れた方が良さそう
set :slack_path, '/services/xxxxxxxxxx/xxxxxxxxxx/xxxxxxxxxx'

# 設定したいチャンネル名を設定
set :release_notify_channel, ['#general']

set :release_notify_title, '通知のタイトル名を入れる'

if fetch(:stage).to_s == 'production'
  # 設定したいメンション先を設定
  set :release_notify_mention, ['@channel']
  set :release_notify_message, (lambda {
    "#{fetch(:stage)}をリリースしたよ〜\n#{proc { `git config user.name`.chomp }.call}さん ありがとう〜 #{fetch(:release_notify_mention).join(' ')}"
  })
  set :release_notify_attachment, (lambda {
    pull_request = Octokit.pull(fetch(:github_repo), fetch(:pull_request_id))
    [
      pull_request.title,
      pull_request.html_url,
      '------------',
      pull_request.body[0, 200]
    ].join("\n")
  })
else
  set :release_notify_message, (lambda {
    "Deployed #{fetch(:branch)} to #{fetch(:stage)} \n commit: https://github.com/#{fetch(:github_repo)}/commit/#{proc { `git rev-parse #{fetch(:branch)}`.chomp }.call} \n by: #{proc { `git config user.name`.chomp }.call} #{fetch(:release_notify_mention).join(' ')}"
  })
  # production以外はプルリクエスト未作成の場合があり、空にしないと最新のプルリクエスト情報が表示され、混乱するため空にした
  set :release_notify_attachment, (-> {})
end

#デプロイ終了後に通知する設定
after 'deploy:finishing', 'release:notify'

動作確認

実際に実行する際はbundle exec cap 環境名 deployですが、これをやるとホントにデプロイしてしまうため、まずは--dry-runオプションをつけて実行し、Slackでどんな内容で通知されるかを確認してみましょう。

capistrano-releases-notificationoctokit.rbを使ってプルリクエストの情報を取得します。
そのため実行後、途中でGitHub Personal Access Token?とターミナルでGitHubの個人アクセストークンを求められて処理が中断されるので事前に作成しておきましょう。

作成後、個人アクセストークンをターミナルに入力し、Enterを押すとデプロイ処理が再開されます。 個人アクセストークンの作り方は以下を確認してみてください。
help.github.com 実行してみた所、以下のようにSlackに通知されました。

staging

$ bundle exec cap staging deploy --dry-run

f:id:bake0937:20191013144839p:plain

production

$ bundle exec cap production deploy --dry-run

f:id:bake0937:20191013144616p:plain

問題なさそうなら、導入したいリポジトリcapistrano-releases-notificationを導入後、--dry-run無しでcapistranoを実行すればOKです。

導入してみた結果

導入経緯で挙がった課題は解消され、デプロイ周りの連絡はSlackを見ればわかる状態になったため、手間だったSlackでの連絡や謎のスプレッドシートのメンテが不要になりました。
とても便利です。

また、productionへのリリースは今までの場合、どのような内容でリリースしたのかを手動でSlackでコメントして報告していたのですが、プルリクエストの内容でSlack通知されるようになったことでだいぶ楽になりました。
(その分プルリクエストの内容をちゃんと書かないとですね)。

さらにproductionへのSlack通知に対して、導入前よりカジュアルに 👍や 🎉の絵文字リアクションがつくようになってチーム内の雰囲気も良くなった気がします🚀。
kimromiさんありがとうございました!!!

これからCapistranoの通知系のプラグインを入れる人にオススメです。

追記(設定内容がよりわかりやすい実装方法)

なんとkimromiさんからリプを頂いた 🙌

とのことのため、以下のように実装した方が各環境毎に設定内容が整理されてわかりやすいことがわかりました。

config/deploy.rbにデフォルト設定を実装

# config valid for current version and patch releases of Capistrano
lock "~> 3.10.1"

# このリポジトリを自分のリポジトリに作りたい場合は、GutHubにリポジトリを作成し、作成したリポジトリ名、リポジトリのURLに変更する
set :application, "test-capistrano-release-notification"
set :repo_url, "git@github.com:bake0937/test-capistrano-release-notification.git"

# slack webhook
set :slack_endpoint, 'https://hooks.slack.com'
set :slack_path, ENV['SLACK_PATH']

# 設定したいチャンネル名を設定
set :release_notify_channel, ['#general']

set :release_notify_title, 'test-capistrano-releases-notification'

set :release_notify_mention, ['@channel']

config/deploy/staging.rbに以下を追加

set :release_notify_message, (lambda {
  "Deployed #{fetch(:branch)} to #{fetch(:stage)} \n commit: https://github.com/#{fetch(:github_repo)}/commit/#{proc { `git rev-parse #{fetch(:branch)}`.chomp }.call} \n by: #{proc { `git config user.name`.chomp }.call} #{fetch(:release_notify_mention).join(' ')}"
})
# production以外はプルリクエスト未作成の場合があり、空にしないと最新のプルリクエスト情報が表示され、混乱するため
set :release_notify_attachment, (-> {})

#デプロイ終了後に通知する設定
after 'deploy:finishing', 'release:notify'

config/deploy/production.rbに以下を追加

set :release_notify_message, (lambda {
  "#{fetch(:stage)}をリリースしたよ〜\n#{proc { `git config user.name`.chomp }.call}さん ありがとう〜 #{fetch(:release_notify_mention).join(' ')}"
})
set :release_notify_attachment, (lambda {
  pull_request = Octokit.pull(fetch(:github_repo), fetch(:pull_request_id))
  [
    pull_request.title,
    pull_request.html_url,
    '------------',
    pull_request.body[0, 200]
  ].join("\n")
})

#デプロイ終了後に通知する設定
after 'deploy:finishing', 'release:notify'

config/deploy.rbにif文でまとめて実装するよりもわかりやすくなりました🙌🙌