こんにちは、クロスイノベーション本部エンジニアリングテクノロジーセンターの小澤英泰です。
本記事ではGitHub DiscussionsでADRを管理する方法を紹介します。
- はじめに
- ADR導入の目的
- ADRに備えたい性質
- ADRの構成
- ADRのステータス管理
- 他のドキュメントとの違い
- ADRの管理にGitHub Discussionsを採用した理由
- GitHub Discussionsでの運用で得たTips
- さいごに
- ADRの例
はじめに
ADRとは
ADRとはArchitecture Decision Recordの略称で、定義はAWSのADRに関するドキュメントを拝借します。
An architectural decision record (ADR) is a document that describes a choice the team makes about a significant aspect of the software architecture they’re planning to build. Each ADR describes the architectural decision, its context, and its consequences. ADRs have states and therefore follow a lifecycle.
- ADRとは、チームが構築するソフトウェアアーキテクチャの重要な選択を記述する文書です。
- 各ADRには、アーキテクチャの決定、その背景、およびその結果を記述します。
- ADRには状態とライフサイクルがあります。
Architecture Decision Recordをカタカナでアーキテクチャディシジョンレコードと表記する場面もありますが、手短に本ブログではADRで統一します。
定義だけでは想像が難しいと思いますので、ご参考までに本記事の最下部にプロジェクトで管理するADRを記載しました。
筆者チームのGitHubとの関わり方
本題に入る前に、筆者チームにおけるGitHubの活用方法を紹介します。
私たちは普段5人前後の開発チームでプロダクト開発を行うことが多く、プロダクトオーナーもGit/GitHubを積極的に活用します。構成管理以外にも下記のようにプロダクト開発で扱うツールをGitHubに集約し、連携することでメリットを最大限に引き出すことを目指しています。
- GitHub Actions: CI/CD
- GitHub Codespaces: 開発環境
- GitHub Discussions: 技術に関する議論やADR、議事録の管理
- GitHub Issues: 課題管理
- GitHub Packages: ソフトウェアパッケージのホスティング
- GitHub Pages: StorybookやAPI仕様書のホスティング
- GitHub Projects: プロジェクト管理
ドキュメント管理においては、GitHubを信頼できる唯一の情報源として位置づけ、他のツールとの分散を避けることで、情報の一元化と信頼性の向上を狙っています。
また、アーキテクチャの決定に影響のあるすべてのメンバーがGitHubにアクセスできることを前提とし、透明性を確保しながらプロダクト開発をしています。
ADR導入の目的
それでは、本題に入っていきましょう。
ADR導入の目的は未来のプロジェクトメンバーが当時のアーキテクチャ決定のトレードオフまで理解できることです。
特定の課題により採用を見送ったアーキテクチャについても、経緯と判断理由を記録することで、将来のリアーキテクチャ時に同様の問題を見落とし、障害やリスクを引き起こすことの未然防止を目的としています。オーラルヒストリーで課題を引き継ぐのは困難を伴うでしょう。
ADRに備えたい性質
次に、上記目的を達成するためのADRに備えたい性質を記載内容と運用の観点で整理します。
記載内容
運用
- 簡潔なテンプレートがある
- 作成およびメンテナンスのコストが低い
- 継続的な運用フローがある
- すべてのプロジェクト関係者がアクセスできる
- 誰がいつ何を変更したかを追跡できる
- 他のドキュメントやコードと整合性が取れている
- 適切にレビューされ、承認されている
ADRの構成
上記の目的や性質を踏まえ、ADRの構成を下記としました。
全体構成
- タイトル
- ステータス
- コンテキスト
- 決定
- 影響
- コンプライアンス
- 参考情報
- 備考
個別の説明
タイトル
- アーキテクチャ決定の簡単な説明
- フォーマットは
[ADR_番号] タイトル
- 例、
[ADR_002] 基盤コードの公開方法
- 例、
ステータス
- ステータスは6種類あり
- Draft(ドラフト)
- Proposed(提案中)
- Accepted(承認済み)
- Rejected(却下)
- Deprecated(非推奨)
- Superseded(置き換え)
ステータスの詳細は後述のADR のステータス管理を参照
コンテキスト
- 決定を下した状況
- 利用中の既存技術との兼ね合いや組織や体制、ビジネス面の時間的な制約を踏まえる
決定
- 決定と根拠
- 他の採用を見送った候補と課題
影響
- 決定による影響
コンプライアンス
- 決定が遵守されていることを確認する方法
参考情報
- 参照すべき一次情報
- 理解を促すブログ(任意)
備考
- その他の備考(任意)
ADRのステータス管理
ADRのステータス遷移と、レビューのプロセスを定義します。
Acceptedのステータスが唯一、ADRが有効であることを示します。
ステータスの遷移図
個別のステータス
Draft(ドラフト)
- 提案者が作成中の状態
- 他のメンバーへは周知前
Proposed(提案中)
- 周知済みでありレビュー可能な状態
Review
※ 判断でありステータスではありません。
- レビュー完了の場合、承認または却下へ進む
- 指摘事項ありの場合、修正者へ差し戻す
Rejected(却下)
Accepted(承認済み)
- レビューを経て承認した状態
- 決定が有効であることを示す
Deprecated(非推奨)
- 承認済みのADRを技術または業務、その他の理由により推奨しない状態
- 決定が無効であることを示す
Superseded(置き換え)
他のドキュメントとの違い
ADRと類似するドキュメントの伝統的なアーキテクチャ記述やDesignDocとの違いを整理します。
- 伝統的なアーキテクチャ記述(Traditional Software Architecture Description)とは、『Design It!』にて言及のある、権威的であり成果物に含まれる設計ドキュメントです。膨大で包括的な特徴があります。
- DesignDocとは、特定の機能の設計方針や技術選定をまとめ、開発チーム内での合意形成や意思決定に扱う設計ドキュメントです。ADRと重複する部分もありますが機能や処理方式に焦点を当てています。DesignDocを作成する場合は、アーキテクチャ決定に関する部分をADRに記載し参照とするのもよいでしょう。
伝統的なアーキテクチャ記述 | DesignDoc | ADR | |
---|---|---|---|
目的 | システム全体のアーキテクチャを記録 | 特定機能や設計変更の記録 | 特定アーキテクチャ上の決定を記録 |
スコープ | システム全体 | 特定の機能やコンポーネント | 特定の決定やその影響範囲に限定 |
記録内容 | システム全体の構造、依存関係、非機能要件など包括的に記録 | 機能の設計詳細や技術的トレードオフ | 決定の背景、選択肢、結論、影響を記録 |
作成タイミング | プロジェクトの初期段階から納品までの期間 | 機能開発前や開発中 機能変更が生じたタイミング |
重要なアーキテクチャ決定が行われたタイミング |
利用期間 | 長期的(システムが稼働する限り) | 長期的(機能がある限り) | 長期的(決定が有効な間) |
更新頻度 | 低 | 高 | 低(承認後の内容は更新せず新たに作成) |
更新難易度 | 高 | 低 | 低 |
形式 | 権威的で公式 | 簡潔 | 簡潔 |
内容の粒度 | 詳細かつ包括的 | 実用的かつ軽量 | 実用的かつ軽量 |
主な読者 | 開発チーム、運用チーム、納品先 | 開発チーム | 開発チーム |
ADRの管理にGitHub Discussionsを採用した理由
筆者チームのGitHubとの関わり方のとおり、ツールはGitHubに集約する方針のため、ドキュメント管理もGitHubで運用する前提があります。GitHubの中でもドキュメントを管理する方法は複数あり、下記4つの候補を検討しました。
比較観点
ADRのGitHubでの管理方法の4候補を下記5つの観点で比較します。
- 構成管理
- 誰がいつ何を変更したか追跡できるか
- テンプレートの利用
- 決まったフォーマットで新規作成できる、または複製できるか
- 検索性
- タイトルや内容を特定ワードで検索できるか
- フィルターの容易性
- 他用途のドキュメントと分離できるか
- ADRの一覧化をできるか
- ADRにレビューを残せるか
- レビューコメントをどこに残すか
比較検討
結果
下表の比較結果より、ADR管理にはDiscussionsを採用しました。
Discussions | リポジトリのdocsフォルダ | Issues | Wiki | |
---|---|---|---|---|
構成管理 | ◎ | ◎ | ◎ | ◎ |
テンプレートの利用 | ◎ | ◎ | ◎ | ◯ |
検索性 | ◎ | ◎ | ◎ | ◯ |
フィルターの容易性 | ◎ | ◯ | ◯ | ◯ |
ADRにレビューを残せるか | ◎ | ◯ | ◯ | × |
◎: 容易に可能 ○: 可能 ×: 不可能または現実的でない
Discussions
- 構成管理(◎)
- 右上のeditedのプルダウンから追跡可能
- ステータス管理の方法から通常のコードと比較して、変更数は少ないため十分と判断
- 右上のeditedのプルダウンから追跡可能
- テンプレートの利用(◎)
- 検索性(◎)
- テキスト検索が可能
- フィルターの容易性(◎)
- ADRにレビューを残せるか(◎)
- Discussion内でのコメントとしてレビュー
- テーマごとにスレッド化して、スレッド内でリプライ可能
- ADR本体とレビューのコメントが同一ページにあり、思考過程を辿ることができる
リポジトリのdocsフォルダ
- 構成管理(◎)
- 明らか
- テンプレートの利用(◎)
- テンプレートファイルを用意し、複製利用
- 検索性(◎)
- テキスト検索が可能
- フィルターの容易性(◯)
- ADRにレビューを残せるか(◯)
Issues
- 構成管理(◎)
- 右上のEditsのプルダウンから追跡可能
- 右上のEditsのプルダウンから追跡可能
- テンプレートの利用(◎)
- Issue Templateでテンプレート化可能
.github/ISSUE_TEMPLATE/{templateName}.yml
でテンプレート化
- 検索性(◎)
- テキスト検索が可能
- フィルターの容易性(◯)
- LabelsのプルダウンからADRラベルでフィルター(2クリック)
- Discussionは1クリックのため評価は◯
- LabelsのプルダウンからADRラベルでフィルター(2クリック)
- ADRにレビューを残せるか(◯)
- スレッド化はできないがフラットにコメント可能なため評価は◯
Wiki
- 構成管理(◎)
- revisionsから追跡可能
- revisionsから追跡可能
- テンプレートの利用(◯)
- テンプレートのページを作成し、複製利用
- ファイルの複製と比較すると手間があるため評価は◯
- 検索性(◯)
- フィルターの容易性(◯)
- サイドバーで階層構造を表現できるが手間があるため評価は◯
- ADRにレビューを残せるか(×)
- ADRに追記することでレビューとコメントが可能だが現実的でないため評価は×
GitHub Discussionsでの運用で得たTips
GitHub Discussionsを用いて、ADR管理をシンプルに運用することができます。運用する中で得たTipsを紹介します。
無効なADRもOpenのままとする
- ADRのステータスがDeprecated、Rejected、Supersededに変化し、無効なADRとなってもDiscussionはOpenのままで運用します。これはGitHub Discussionsのデフォルトのフィルター条件がOpenなDiscussionのみ表示のためです。無効なADR含め一覧で見たいため、無効なADRもCloseしません。
DiscussionとIssueに関連を持たせる
- Discssionに記述したADRがIssueの課題に関連を持つ場合は辿れるように相互にリンクを貼ります。
- Discussionsページの検索窓からはIssueは検索範囲外です。Issueやコードを含めて検索したい場合は、リポジトリ全体で検索しましょう。
アーキテクチャの決定をGitHub Copilotに読ませる
- 2025年3月時点では、GitHub CopilotはGitHub Discussionsのドキュメントを読み取ることはできないようです。アーキテクチャの決定をGitHub Copilotに読ませたい場合は、必要な箇所をリポジトリのdocsやREADME、copilot-instructions.mdに記載しましょう。
さいごに
ADRの目的から構成やステータスを定め、GitHub Discussionsを用いてADRを管理する方法を紹介しました。今後の運用で新たな気づきがあれば、改めて記事を投稿したいと思います。
プロジェクトによってADRの最適な管理方法は異なりますが、1つの例として参考になれば幸いです。
ADRの例
タイトル: [ADR_002] 基盤コードの公開方法
ステータス
Proposed
コンテキスト
案件カスタマイズをする際に基盤のコードを利用し、容易に案件カスタマイズを実施できるようにしたい。
基盤のコードをどのようにパッケージングし、公開するかを検討する。決定
結論
以下の候補を検討し、GitHub Packages(npm packages)として公開することとする。
- GitHub Packages
- npm packages
- Docker Images
- Monorepo
- Micro Service
評価の観点は以下。
- 独立性
- 基盤コードと案件コードが独立しているか
- 利用容易性
- 案件側から容易にパッケージを利用できるか
- パッケージのインターフェースは便利か
- カスタマイズ性
- 案件側で振る舞いを変更できるか
- 案件側で振る舞いを上書きできるか
- 拡張性
- 基盤コードはメンテナンスしやすいか
- 基盤コードは機能追加しやすいか
方法 独立性 利用容易性 カスタマイズ性 拡張性 GitHub Packages(npm packages) ◯ △ ◯ ◯ GitHub Packages(Docker Images) ◯ △ × △ Monorepo × ◯ ◯ × Micro Service ◯ × ◯ ◯ 採用の選択肢とその理由
GitHub Packages(npm packages)
- 独立性(◯)
- 基盤コードと案件コードでリポジトリを分割可能
- パッケージはバージョニングできるため、基盤コードのバージョン間でも独立している
- 利用容易性(△)
- ユーザはnpm installで利用可能
- 実装にもよるがライブラリ形式のためある程度の利便性
- コンポーネントの組み合わせ相当の実装は呼び出し側の責務となり、多少実装コストがある
- カスタマイズ性(◯)
- メンテナンス・拡張性(◯)
採用見送りの選択肢とその課題
GitHub Packages(Docker Images)
- 独立性(◯)
- リポジトリを分割できる
- バージョニングできる
- 利用容易性(△)
- Docker Image形式で利用可能
- 呼び出し側はDocker実行時のパラメータを変更するのみ
- パラメータが大量になる可能性あり
- カスタマイズ性(×)
- パラメータを変更することで振る舞いを変更可能
- 振る舞いの上書きはできない
- パラメータ以上の振る舞い変更は不可能
- 拡張性(△)
- 実行時パラメータを増やすことで拡張可能
- カスタマイズの数だけ実行時パラメータが増えてしまう
- 引数が大量にあるDocker Imagesは基盤側にとっても案件側にとっても便利ではないと予想
Monorepo
- 独立性(×)
- ディレクトリ相当のため、独立性があるかと言われると微妙
- 案件担当者が基盤コードを直接参照したり、修正できたりする
- バージョニングできない
- 利用容易性(◯)
- npm workspaceなどを使ったライブラリの形式になる
- ライブラリ形式のためGitHub Packages(npm packages)と同程度か
- コードのコピペも可能
- カスタマイズ性(◯)
- パラメータを変更することで振る舞いを変更可能
- パラメータ以上の振る舞い変更は不可能
- メンテナンス・拡張性(×)
- バージョニングができないため、基盤コードの修正とリリースが簡単に実施できないMicro Service
- 独立性(◯)
- リポジトリの分割ができる
- バージョニングができる
- 利用容易性(×)
- APIを通した呼び出しになる
- バックエンド機能の共有には便利だが、フロントエンドコードの共有は難しい
- カスタマイズ性(◯)
- メンテナンス・拡張性(◯)
- APIを拡張していく方式になる
影響
- GitHub リポジトリを新しく作り、そのリポジトリでパッケージング用のビルドスクリプトを書き、GitHub PackagesにpushするCIフローを書く
- 公開の際のバージョニングの方法を別途検討する
コンプライアンス
基盤コードのリポジトリを分割し、そのリポジトリからパッケージを公開することで、GitHub Pacakges(npm packages)経由での利用を案件側に強制することが可能。
基盤コードのリポジトリについてはアクセス制限を厳密に実施する。
外部メンバーにはwrite, read程度の権限を付与し、mainブランチはブランチプロテクションで制限し、自分たちの知らないところで基盤コードを変更されないようにする。基盤コードを案件開発者が閲覧し、案件コードにコピペすることは許容する。
参考情報
備考
- 別途案件カスタマイズ時の初期セットアップをサポートするために、Templateリポジトリを作りたい
執筆:@ozawa.hideyasu、レビュー:@takami.yusuke
(Shodoで執筆されました)