こんにちは。G4B div Product unit でエンジニアをしている murata (@Natch___) です。
社内では toB 向けを中心としたプロダクト開発をいくつか担当しており、Giftee Campaign Platform (通称: GCP) や、直近では giftWallet のサイトリニューアルなどの開発のお仕事をしています。
以前のエントリ では社内のビジネスサイド(biz)から開発サイド(dev)への依頼を効率的に捌くための半自動化手法について執筆させていただきました。ぜひご一読ください。
はじめに
2021/10/04 に The GitHub Blog のエントリ A new public beta of GitHub Releases: How we’re improving the release experience | The GitHub Blog にて GitHub Releases のパブリックベータ版新機能 「auto-generated release notes」 が公開され、利用可能であることをみなさんはご存知でしょうか?
今回は、私が担当しているプロダクトの1つである 「Giftee Campaign Platform」 のリリース作業に 「auto-generated release notes」 を導入し、CI (GitHub Actions) で一工夫をいれることによって、チームの 「DX: Developer Experience (開発体験)」 が向上したことについて紹介します!
対象読者
- 「auto-generated release notes」 がどんなものか興味がある人
- 社内向けのプロダクトリリース告知を効率的に行う方法を知りたい人
- ちょっとした 「GitHub Actions」 の活用事例に興味がある人
Giftee Campaign Platform のリリース作業
まずは、チームで行っているリリース作業がどんな工程か説明させてください。
開発サイクル
Giftee Campaign Platform (以下 GCP) では次のような開発サイクルを経て、毎週の特定曜日にリリースするようにしています。3~6 がリリースに伴う実作業です。
- (開発担当) feature ブランチで開発
- (開発担当) develop ブランチに feature ブランチをマージ
- (リリース担当) master ブランチに develop ブランチをマージ
- (リリース担当) master ブランチを Target にして release の下書きを作成する
- (開発担当) release の内容、および機能のリリース前動作チェックを行う
- (リリース担当) release を公開する
- (CI) release 作成をフックに本番環境にコードをデプロイ
リリースの告知
「6. (リリース担当) release を公開する」 を行うと、 「release notes」 の内容が特定の Slack チャンネルに投稿されます。それには、 GitHub と Slack の連携 を利用することで実現しています。
投稿したい Slack チャンネルに GitHub アプリを連携し、Slackのスラッシュコマンドで当該リポジトリの 「release」 を事前に 「subscribe」 しておきます。
/github subscribe owner/repo [feature]
すると、登録したリポジトリで 「release」 を作成するやいなや連携したチャンネルにその内容が投稿されます。例えば、こんな感じで Slack に投稿されます。
リリース告知の意図
GCPはキャンペーンのセッティングから実施までを一気通貫して提供することができるプロダクトです。このプロダクトはキャンペーン実施に関した多種多様な機能を内包しており、ビジネスサイドのメンバーは機能を組み合わせてキャンペーンの施策を提案します。
そのため、GCPのユーザーはキャンペーンに参加する一般消費者はもちろんのこと、キャンペーンのセッティングを行う社内のビジネスサイドメンバーもユーザの一人です。なので、プロダクトの仕様を周知して理解してもらうことは提案の幅を広げる意味では重要になります。
また、随時機能開発をしているので、細心の注意を払っていても人知れずエンバグしてしまうこともあります。そのような場合にはビジネスサイドからエスカレーションして即時にバグの修正対応をします。そうした修正対応の完了を告知する役割も担っています。
リリース作業に伴う課題
リリース担当が行う作業3, 4では、開発担当がどんな開発を行ったかをマージされているPRを目検で確認し、 「release notes」 にその開発内容の要約を記載していました。
リリース内容の要約それ自体は負荷の高い作業ではないですが、開発担当の意向を汲みきれていないことで修正手戻りが発生してテンポが悪いことがあったり、他の優先度の高いタスクが押しているときはそうしたテンポの悪さからリリースを翌日に見送ることもしばしばありました。
誰しも日々の改修は細かくリリースして安定的にアプリケーションを提供したいはずです。そのことを考えると、リリースの負荷はできるだけ少なくしたいとつねづね感じていました。
リリース作業の負担を軽減する方法
そんな課題感を感じていたときに目に入ってきたのが 「auto-generated release notes」 です。
この機能は、 「Releases」 作成画面の 「Auto-generate release notes」 というボタンをポチッとクリックするだけで 「Target」 に指定したブランチにおける最新の Tag から、今まさに Tag を打とうとしているコミットまでにマージされたPRの要約を 「release notes」 に自動記入してくれます。
引用元:Automatically generated release notes - GitHub Docs
この 「Auto-generate release notes」 によってリリース内容の要約作業を代替することができました。
このように、要約内容が単にテキストとして書き出されるだけではなく、メタ情報がGitHubへのリンクテキストで付帯されるため、あとでリリース内容を振り返りたいときに有用です。
これらのリンクはslack連携によりチャンネルにそのまま投稿されるので、わざわざ GitHubの 「Releases」 にいかずとも、Slackから直リンクでアクセスすることができます。
要約の仕組み
要約は、PRにアタッチされている 「Label」 によって分類される仕組みになっています。
特定の「label」や「title」で分類する、特定の「authors」を分類対象外にするなど、ちょっとした分類の自由度があります。
それらカスタマイズの設定は、リポジトリルートを起点として 「.github/release.yml」 に書きます。なお、 「title」 と 「labels」 は 「Required」 なので注意が必要です。
引用元:Automatically generated release notes - GitHub Docs
.github/release.yml を作成
さきほどのデモは以下のような設定ファイルに基づいています。
changelog: categories: - title: 機能追加 🎉 labels: - enhancement - title: 機能改修 🛠 labels: - spec change - title: バグ修正 🐛 labels: - bug - title: 依存ライブラリの更新 📦 labels: - dependencies - title: その他 labels: - other
Point
設定にあたってのポイントは以下の通りです。
changelog.categories
- PRをいずれか1つに必ず分類できるようにする。
- どうしても分類が難しいときのためのセーフティネットとして「その他」を置きました。
changelog.categories.title
- タイトルは絵文字で華やかに!
- テキストだけの簡素な表示だとぱっとみでわかりにくいし見過ごされてしまう可能性があります。
- また、開発モチベーションにも繋がります!
changelog.categories.labels
- 一部のラベルを新規作成する。
- 後述する「dependencies」 とデフォルトで存在する「enhancement」 と 「bug」 以外のラベルについては新規作成しています。
- GitHub Dependabot Version Updates が作成するPRを考慮する
- GCPでは日々依存するライブラリの更新を行っており、リリース内容にしばしば Dependabot が作成するPRも含まれます。
- Dependabot が作成するPRには「dependencies」 というラベルが自動的にアタッチされるので、それらも分類可能にしています。
- 一部のラベルを新規作成する。
PRへのラベル付けを強制する
CI (GitHub Actions) でヒューマンエラーを解決
「PRにラベルをつけ忘れたらちゃんと分類されないのではないか?」と気づいた人がいるかと思います。鋭いです。そのとおりです。試運用してみたところ、そうしたラベルのつけ忘れはヒューマンエラーとしてどうしても起きてしまいました。
そこで、ラベルのつけ忘れ防止チェックを 「GitHub Actions」 で実現しました。これにより、 「Auto-generate release notes」 を実行時に分類できないPRが作成されてしまっている状況を未然に防ぐことができます。
ワークフローの実装
ラベル付けを強制するワークフローを自作することも視野にいれましたが、エンジニアたるもの車輪の再発明は避けたいところです。そこで、 Require Labels という Action を利用することで実現しました。GitHub Actions そのものの説明はここでは割愛しますが、 「uses」 を使うことで Market に公開された Actions を任意の step で実行することができます。(参考:Understanding GitHub Actions - GitHub Docs)
GitHub Actions のワークフローは .github/workflows/
配下に任意の名前のymlファイルを置くことだけで動きます。 .github/workflows/required_pull_request_labels.yml
にワークフローを定義しました。
name: Required Pull Request Labels on: pull_request: branches: - develop types: [opened, synchronize, reopened, labeled, unlabeled, review_requested, ready_for_review] jobs: label: runs-on: ubuntu-latest steps: - uses: mheap/github-action-required-labels@v1.1.2 with: mode: exactly count: 1 labels: "enhancement, spec change, bug, dependencies, other"
Point
設定にあたってのポイントは以下の通りです。「Require Labels」 の 「Usage」 を参考にユースケースに合わせて設定するとよいでしょう。
on.pull_request.branches
- 開発ブランチ 「develop」 のみをチェックの対象とする。
- master へのPRでもチェックが走らないようにしています。
- 開発ブランチ 「develop」 のみをチェックの対象とする。
on.pull_request.types
- 「labeled」、「unlabeled」 を追加する。
- 「on.pull_request」 はデフォルトで 「opened」、「synchronize」、「reopened」 がアクティビティタイプとして設定されます。
- ただ、「ラベル付け」を強制したいので、ラベルのつけ外しで再チェックしてくれると嬉しいと考えて「labeled」、「unlabeled」 を追加しました。
- なお、 「review_requested」、「ready_for_review」 は好みの問題で、なくてもよいかもしれません。
- 「labeled」、「unlabeled」 を追加する。
DX(開発者体験)の向上
「auto-generated release notes」 を利用することにより、リリース作業の負荷が低減し、以前よりも素早いデプロイサイクルを回すことが可能となりました。
これにより、週一の定期的リリースが安定化したことのみならず、dbマイグレーション実行のためのデプロイ、hotfix といった緊急性の高いデプロイなどの工数短縮にも寄与しています。
また、副次的な効果として、PRのタイトルが 「release notes」 に要約・告知される意識が芽生えることになります。そのことで、各々の開発(≒PR)が本質的な課題解決につながるかどうかを振り返る機会となり長い目で見ると、より質の高いアウトプットにつながるのではないかと踏んでいます。
なによりも、「リリース作業にあたって何も頭を働かせる必要がなく機械的に作業をすればいい」というのは心理的な意味でDXに寄与することになったのではないかと思っています。
最後に
いかがでしたでしょうか?
こうしたちょっとした非効率な部分を改善するだけで、それが波及して思った以上の効果が得られることもときにはあります。
ぜひみなさんもちょっとした効率改善に取り組んでみてください。