リリース作業をかんたんに! git-pr-release + Google Apps Script + Ruby スクリプト + GitHub Actions によるリリース作業改善の取り組み

ジモティーでサーバサイドとインフラを担当している吉田です。

前回は ISUCON10 に参加した話を投稿しました。今年もちょうど ISUCON11 を終えたばかりですが、残念ながら予選敗退となりました。ISUCON への参加はウェブエンジニアとしてのキャリアを見つめ直すとてもよい機会で、来年こそは決勝に進みたいと思っています。

さて、今回はジモティーのサーバサイドで1年ほど運用している、リリース作業の一部自動化の取り組みについて、背景から実施までをご紹介します。

従来のリリースフローとその課題

まず、弊社サーバサイドのリリースフローについて、当時の概要は次の様になっていました*1

変更前のリリースフロー
変更前のリリースフロー

  1. コードレビューを経て、トピックブランチを master ブランチにマージ(作業者: 各機能担当者
  2. リリース PR を作成(作業者: リリース担当者
  3. 機能担当者にリリース前テスト環境での動作確認依頼(作業者: リリース担当者
  4. 動作確認(作業者: 各機能担当者
  5. Jenkins のジョブを実行してリリース(作業者: リリース担当者

リリース担当者はリリースしたいメンバーによる立候補制で、サーバサイドのメンバーであれば誰でもこの役割になる可能性があります*2

この作業の1番の課題は、マージされた PR の「タイトル」「作成者」を目視で抜き出す事が大変な点です(図の2. および 3. に該当)。

詳細な流れは次の内容になります。

リリースPRの作成と動作確認依頼
リリースPRの作成と動作確認依頼

  1. master ブランチへのコミットログの中からマージコミット (メッセージが Merge pull request #xxxx from jmty/xxxx) を確認
  2. マージコミットの PR から「タイトル」「作成者」を確認
  3. 確認した「タイトル」をリリース PR の本文に入力
  4. 確認した「作成者」にリリース前テスト環境での動作確認を Slack のメンションで依頼

また、PR の「作成者」は GitHub のアカウント名なので、Slack のアカウント名に変換して Slack で本人にメンションする必要があります。そのため、たまに誤って違うメンバーにメンションをしてしまう問題も発生していました。

変換ミスによる誤メンション
変換ミスによる誤メンション

これをマージ済み PR の数だけ繰り返す必要があり、リリースタイミングによっては1度に10件を超える事もあります。

改善

事前準備

まず、課題を明確にします。こちらは前述の通りです。

  • リリース PR 作成時に、マージされた PR の「タイトル」「作成者」を目視で抜き出す事が大変
  • 誤って違うメンバーに動作確認依頼を行ってしまう

次に、その解決方法を調べます。

基本的に手作業で行っていた、マージされた PR の「タイトル」「作成者」を目視で抜き出して作業担当者に依頼する作業を自動化する方針で、かんたんな実装を行いました。これは、次で行う提案のための準備になります。フィードバックの結果、内容を大きく変更する可能性も十分あるため、あまり作り込まず、かつ GO サインをもらえるレベルにします。

KPT での提案

準備した内容をもとに、週1で実施しているウェブチームの KPT で下記の提案をしました。

  • 課題の共有
    • リリース作業がツラい
  • 解決案の提示
  • FAQ
    • リリースフローはどう変わるのか
    • 導入・運用コスト
    • メリットだけではなくデメリットも
    • なぜ CI は既存で利用している CircleCI ではなく GitHub Actions で動作させるのか、など

想定していた実装工数は比較的小さいため、一気に導入する手もありますが、次の観点から提案のステップを挟むことにしました。

  • 共通の課題である事の確認および、ニーズの確認
  • 異動や退職などで技術的な負債となる可能性がある
  • リリースフローの変更により、障害に繋がりやすくなる可能性がある

結果はおおむね期待していた良い反応だったため、具体的な実装に移りました。

変更後

最終的に次の流れになっています。

変更後のリリースフロー
変更後のリリースフロー

  1. コードレビューを経て、トピックブランチを master ブランチにマージ(作業者: 各機能担当者
  2. リリース PR を作成(作業者: リリース担当者
  3. 機能担当者にリリース前テスト環境での動作確認依頼
    1. 本文を自動更新 (git-pr-relase gem)
    2. GitHub と Slack ID のマッピングを取得 (Apps Script)
    3. 動作確認依頼 (Ruby スクリプト)
  4. 動作確認(作業者: 各機能担当者
  5. Jenkins のジョブを実行してリリース(作業者: リリース担当者

「機能担当者にリリース前テスト環境での動作確認依頼」の作業を自動化しています。

それぞれの技術トピックについてご説明します。

git-pr-release

git-pr-release はリリース PR を作成・更新する gem です。マージされた PR からタイトルや担当者を取得して、PR を作成・更新してくれます。

当初自作をしようと考えていたところ、希望の機能を満たすこちらの gem が見つかり、OSS かつ定期的にメンテナンスされていたため採用しました。

最近 GitHub の仕様変更があり、期待する動作をしなくなる事がありましたが、すぐに対応されたものがリリースされました。

もし自作していた場合、同様の対応を行う可能性が高かったはずです。

Google Apps Script

GitHub アカウント名と Slack ID のマッピングを JOSN として返すウェブアプリケーションサービスです。

次はサービスのURLに対して curl からの擬似的なアクセス例になります。

$ curl -H "Authorization: token xxxx" -L \
  --dump-header - \
  "https://script.google.com/xxxxxx"
(省略)
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
(省略)

[
  {
    "slack_member_id"=>"XXXX",
    "slack_display_name"=>"kyoshida", 
    "github_login_name"=>"kyoshidajp"
  },
  {
    "slack_member_id"=>"YYYY",
    "slack_display_name"=>"yyyy",
    "github_login_name"=>"zzzz"
  },
  ...
]

マージされた PR からその作成者(機能担当者)のアカウント名を取得した後、Slack ID に変換する際にこのマッピング情報を参照します。

事前に Google スプレッドシートにそれぞれの対応を記載しておきます。新しいメンバーが加入したら都度こちらに追加します。このシートのメンテナンスが手動になってしまいますが、他の利用用途でも使えるようになります。

Ruby スクリプト

リリース PR の本文から、マージされたPRの「タイトル」「担当者」を取得して Slack に通知します。

Ruby は弊社サーバサイドにてメインで利用しているプログラミング言語です。ユニットテストや JSON の変換など、豊富なライブラリが付属している事に加えて、Slack や GitHub 連携など16万を超える*3サードパーティのライブラリによる素晴らしいエコシステムがあります。

同様の目的には、後述する GitHub Actions のワークフローコマンドから gh や jq を駆使して行うことも可能だと思いますが、上記観点から Ruby スクリプトとしました。

GitHub Actions

git-pr-release および、Slack に通知する Ruby スクリプトの実行環境です。

master から release ブランチへマージするリリース PR が作成されたタイミング、もしくはmaster ブランチにコミットが行われたタイミングで実行されます。後者については、リリース PR が作成された後に、追加でリリース機能を含めるケースに対応するためです。

CI 環境としてすでに利用している CicleCI ではなく、GitHub Actions を採用したのは次の理由によるものです。

  • 世の中の流れとして GitHub Actions がかなり普及してきており、キャッチアップをしておきたい
  • 想定の利用ケースでは無料枠に十分収まる
  • 面白そう

結果

改善により、当初の課題であった、リリース担当者による目視かつ手作業での依頼が不要になりました。

自動で通知される動作確認依頼
自動で通知される動作確認依頼

また、誤って別のメンバーに確認依頼してしまう問題も発生していません。

さらに、工夫したポイントとして、デプロイ時に Slack で通知されるリリースノートの内容が分かりづらかったため、同様の仕組みで整理しました。

整理されたリリースノートの通知
整理されたリリースノートの通知

この結果、エンジニアだけでなく、CS を含む社内メンバーは機能概要機能担当者リリース担当者が明確になりました。

まとめ

日常で感じた課題の解消をモチベーションに、その改善の提案、そして実施までをご紹介しました。

自動化した作業は、以前は1回あたりおよそ5〜15分程度だったので、リターンを時間で換算するとどうしても投資効果を低く感じてしまいがちです。しかし、日々課題に感じていて改善の目処が立っているのであれば、積極的に取り組むべきだと思います。

そもそも、対象の作業は手作業で日々繰り返され、自動化が可能なものでした。こういった、いわゆるトイルの撲滅は(インフラ)エンジニアが価値を発揮しやすい領域ではないでしょうか?

少なくとも、以前の状態には戻りたくないのが率直な気持ちです。

宣伝

ジモティーではエンジニアを募集中です。

jmty.co.jp

日々の不満や課題を一緒に解決していきましょう!

*1:master ブランチへのマージ後にリリース前テスト環境への自動反映など、細かい内容は省略

*2:これは執筆時点も同じ

*3:執筆時点の https://rubygems.org/stats より