capistrano-releases-notificationでデプロイ周りのチーム内コミュニケーションが改善した話
capistrano-releases-notification
を導入したことでデプロイ周のチーム内コミュニケーションが改善されました。
今回はその時の話を書いていきます。
試したRubyのバージョンは2.6.5
、Capistranoのバージョンは3.10.1
です。
導入経緯
普段の業務でデプロイツールとしてCapistranoを使っているのですが、今のチームで以下の課題がありました。
- 誰がどの環境に何の内容でデプロイしたかはCapistranoを実行した人しかわからない
revisions.log
などを見ればわかるが、わざわざサーバーにsshするのは手間
- リリース報告が手動でSlackでコメントして連絡するため手間
- staging環境やqa環境などを利用するときは台帳(誰がどの環境で何を検証しているかを記録する謎のスプレッドシート)に書いてチームメンバーに共有しているのだが、台帳のメンテを度々忘れてしまう
ということで、上記の課題を解決できる方法は何かないかを探してみた所、元同僚のkimromi
さんがCapistrano
でデプロイ時にSlackに通知をしてくれる便利なプラグイン(Gem)を公開していたことを思い出し、導入してみました。
また、このプラグインを導入することによってただSlack通知されるだけではなく、どのPullRequestでリリースしたかがわかるようになってさらに便利になりました✨。
使い方
使い方については↑の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-notification
はoctokit.rb
を使ってプルリクエストの情報を取得します。
そのため実行後、途中でGitHub Personal Access Token?
とターミナルでGitHubの個人アクセストークンを求められて処理が中断されるので事前に作成しておきましょう。
作成後、個人アクセストークンをターミナルに入力し、Enterを押すとデプロイ処理が再開されます。
個人アクセストークンの作り方は以下を確認してみてください。
help.github.com
実行してみた所、以下のようにSlackに通知されました。
staging
$ bundle exec cap staging deploy --dry-run
production
$ bundle exec cap production deploy --dry-run
問題なさそうなら、導入したいリポジトリにcapistrano-releases-notification
を導入後、--dry-run
無しでcapistranoを実行すればOKです。
導入してみた結果
導入経緯
で挙がった課題は解消され、デプロイ周りの連絡はSlackを見ればわかる
状態になったため、手間だったSlackでの連絡や謎のスプレッドシートのメンテが不要になりました。
とても便利です。
また、productionへのリリースは今までの場合、どのような内容でリリースしたのかを手動でSlackでコメントして報告していたのですが、プルリクエストの内容でSlack通知されるようになったことでだいぶ楽になりました。
(その分プルリクエストの内容をちゃんと書かないとですね)。
さらにproductionへのSlack通知に対して、導入前よりカジュアルに 👍や 🎉の絵文字リアクションがつくようになってチーム内の雰囲気も良くなった気がします🚀。
kimromiさんありがとうございました!!!
これからCapistranoの通知系のプラグインを入れる人にオススメです。
追記(設定内容がよりわかりやすい実装方法)
なんとkimromiさんからリプを頂いた 🙌
あっちなみにstageごとの設定の分岐をdeploy.rbに書いてもいいんですが、deploy.rbはデフォルト設定として書いて、config/deploy/production.rb とかに環境ごとの設定を書くとそっちで上書きされるのでおすすめです👍
— Hiromi Kimura (@kimromi) October 13, 2019
とのことのため、以下のように実装した方が各環境毎に設定内容が整理されてわかりやすいことがわかりました。
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文でまとめて実装するよりもわかりやすくなりました🙌🙌