トランクベース開発とは? 本番を守る実践ガイド
要約
トランクベース開発は、全員が短命のブランチで小さな変更を1日1回以上メインへ統合し、常にリリース可能な状態を保つ方式です。成立には、短いCI、信頼できるテスト、速いレビュー、フィーチャーフラグが必要です。フラグは期限付きの負債として管理し、マージ後数分以内に回帰を見つけられる観測体制を整えてから導入してください。
午前3時、リリース用のブランチがマージできません。3週間前に作られた40個のコミットが、mainと同じファイルを書き換えています。その痛みこそが、トランクベース開発を考える理由です。トランクベース開発とは、チーム全員が小さな変更を1つの共有ブランチ(トランクまたはmain)へ少なくとも1日1回統合し、そのブランチを常にリリース可能な状態に保つ開発モデルです。
この記事は、Gitには慣れているプラットフォームエンジニアとSREに向けたものです。このモデルが何を求め、何から守ってくれ、どこで静かに壊れるのかを整理します。
トランクベース開発を運用の言葉で言うと何か
定義を制約まで削ってみます。全員が1つのブランチに統合します。その他のブランチが生きる時間は、数週間ではなく数時間です。トランクはすべてのコミットでビルドとテストを通すため、いつでもリリースできます。
DORAの能力ページは、これを数字で示しています。リポジトリ内のアクティブなブランチは3つ以下、トランクへのマージは少なくとも1日1回、コードフリーズなし、ビルドとテストは数分で完了する、という基準です。この数字こそが重要です。このモデルはブランチの書き方の好みではなく、フィードバックループの予算なのです。

小規模なチームはトランクに直接コミットすることもあります。大きめのチームは、レビューとビルドチェックのために短命のブランチとプルリクエストを使いますが、統合を遅らせる目的では使いません。trunkbaseddevelopment.comの解説は両方のやり方を紹介しており、Googleが約35,000人の開発者を1つのモノレポのトランクで運用している例も挙げています。
長命ブランチが予測可能なタイミングで壊れる理由
機能ブランチは借金です。利息はマージコンフリクトで、メインに変更が入るたびに膨らみます。ブランチが長く生きるほど差分は大きくなり、差分が大きいほど誰も丁寧に読まなくなります。
これは変更失敗率に直接響きます。2,000行のマージは流し読みされて承認されます。60行のマージは実際に読まれます。レビュアーは怠けているのではなく、注意力を配分しているのです。レビューの質を保てる仕組みは、小さなバッチしかありません。
2つ目のコストは、リリースまで見えません。個別にCIを通過した2つのブランチでも、統合したときに互いを壊すことがあります。それが分かるのは統合の時点、つまり締め切りが迫った最悪のタイミングです。
トランクを信頼する前に必要なもの
サポートする実践なしにトランクへ移行すると、四半期以内に機能ブランチへ戻ることになります。先に4つ揃えておく必要があります。
ビルドとテストが10分前後で終わること。CIが40分かかるなら、開発者は変更をまとめるようになり、それがモデルを壊します。
本当の理由でだけ失敗するテストであること。不安定なテストは、再実行してそのままマージする習慣を生みます。
速く誠実なレビュープロセスであること。DORAは、重いレビューや非同期のコードレビューを、作業のバッチ化を促す一般的な障害として挙げています。
未完成の作業を安全にリリースする方法があること。これは次のセクションで扱います。
どれか1つでも欠けると、トランクは壊れたものが蓄積する場所になってしまい、壊れたものを捕まえる場所にはなりません。
未完成の作業を、出荷せずにマージするには
懐疑的な人が必ず聞く質問です。答えは地味です。デプロイとリリースを切り離すのです。コードは本番に無効化された状態で届きます。誰に見せるかは、フラグが決めます。
// checkout.ts
import { flags } from "./flags";
export async function renderCheckout(user: User) {
if (await flags.isEnabled("new-payment-flow", { userId: user.id })) {
return renderNewPaymentFlow(user); // トランクにマージ済み、デフォルトは無効
}
return renderLegacyCheckout(user);
}新しいフローは初日にマージされ、フラグはオフのままです。まず社内ユーザーに、次に1%、10%とフラグを切り替え、各段階でSLOのゲートを通します。エラー率が予算を超えたら、フラグをオフにするだけで、デプロイなしに実質的な巻き戻しが完了します。ホスト型のフラグサービスを評価するチームは、LaunchDarklyから検討を始めることが多いです。ただし、このパターンはどのプロバイダーでも、自社の設定ストアでも機能します。
2つ目の手法は、大きなリファクタリング向けのbranch by abstractionです。インターフェースを導入し、呼び出し元をそのインターフェース経由にし、新しい実装をその裏に作り、準備ができたら切り替えます。長命のブランチも、大きなビッグバンマージも不要です。

正直なコスト:フラグには半減期のある負債がある
カンファレンスではあまり語られませんが、追加したフラグはすべて、誰かが削除しなければならない本番環境の条件分岐です。80人規模のエンジニアリングチームが、テストしきれない古いフラグを数百個抱えている例も見てきました。
フラグは、期限付きの短命なものとして扱ってください。作成時に担当者と有効期限を決めます。期限を過ぎたフラグにはアラートを出します。フラグを削除するプルリクエストの中で、不要になったコードパスも一緒に削除します。
組み合わせのリスクも現実です。独立したboolean型のフラグが10個あると、1,024通りの設定になります。すべてをテストすることはできません。フラグ同士の相互作用は少なく保ち、リリース用のフラグと、キルスイッチのような長期の運用トグルは分けて管理してください。
トランクの上でのリリース戦略
トランクからリリースを切る一般的な方法は2つあり、どちらも長命のブランチを必要としません。
トランクから直接リリースする。緑のコミットはすべてリリース候補になります。バグは古いブランチにパッチを当てるのではなく、新しいコミットで前に進めて修正します。自動テストが強く、デプロイが速いチームに向いています。
必要になったときにリリースブランチを切る。信頼できるトランクのコミットからブランチを切り、強化してリリースし、ブランチを削除します。修正はまずトランクに入れ、そのあとブランチにcherry-pickで戻します。リリースゲートが遅いチームや、規制上の承認が必要なチームに向いています。
どちらを選ぶかは、検知時間で決まります。悪いデプロイを5分以内に気づき、2分以内に戻せるなら、前に進めて修正すれば十分です。平均検知時間が1時間なら、リリースブランチが踏みとどまれる足場になります。

オブザーバビリティは取引のもう一つの半分
トランクベース開発はデプロイ頻度を上げるので、何かが壊れうる瞬間の数も増えます。このモデルが機能するのは、マージから数分以内に回帰を見つけられる場合だけです。特定のリリースに紐づくエラー率、レイテンシのパーセンタイル、リソースの飽和度が必要です。月曜日に誰かがチェックするダッシュボードでは足りません。
有効なテストがあります。マージ後に「この変更でp99かエラー率が動いたか」を、5つのタブを開かずに答えられますか。答えられないなら、1日に何度もマージする準備はまだできていません。
どのスタックを使っていても、要件は同じです。グラフにデプロイのマーカーがあること、SLOのバーンレートのアラートがあること、疲れた人が午前3時にも迷わず実行できる巻き戻しの経路があることです。
トランクベース開発、GitFlow、GitHub Flowの違い
3つは混同されがちなので、1つの性質で区別します。作業が共有ブランチから離れている時間です。
GitFlowは、developブランチ、機能ブランチ、リリースブランチ、ホットフィックスブランチを持ちます。作業は数週間隔離されることがあります。バージョン管理されたスケジュール型のリリースのために設計されており、1日に10回デプロイしようとすると限界が見えます。
GitHub Flowはトランクに近い方式です。短命のブランチ、プルリクエスト、mainへのマージ、デプロイという流れです。参考サイトが示す違いは、主にリリースをどこから切るかにあります。
トランクベース開発は3つの中で、ブランチの寿命に最も厳しい方式です。1つの小さな変更でリリースできないものには、フィーチャーフラグかbranch by abstractionを前提とします。
すでにGitHub Flowで、2日以内に終わるブランチを回しているチームは、思う以上にトランクに近いです。足りないのは通常ツールではなく、フラグの規律とレビューのリードタイムです。
最初に動くDORA指標
始める前に計測してください。さもないと、後から感覚で議論することになります。デプロイ頻度と変更のリードタイムは最初に反応します。小さなバッチがパイプラインをより速く流れるからです。変更失敗率と復旧時間はそのあとに続きますが、これはブランチ戦略だけでなく、オブザーバビリティと巻き戻しの経路に依存します。
数字を個人の評価表にしないでください。数字が示すのはシステムです。リードタイムが伸びたら、人を見る前にレビューの待ち行列とCIの時間を確認してください。
トランクベース開発が間違った選択になるとき
いくつかのケースでは、導入を見送るか、少なくとも遅らせるべきです。どのケースに当てはまるかを正直に判断してください。
テストスイートが1時間かかり、並列化もできない。変更をまとめるようになり、それがモデルを壊します。
数年間古いバージョンに留まる顧客に、バージョン管理された成果物を提供している。保守用ブランチが必要です。それは正当な理由で、それでも毎日トランクに統合することはできます。
フラグの仕組みがなく、作る意欲もない。完成していない作業がリリースに漏れ出します。
チームがビルドを信頼していない。先にテストを直してください。トランクは直してくれません。
トランクベース開発は、何かを保証するものでもありません。DORAの知見は2016年と2017年のデータに基づく相関です。これらの実践に従うチームは、より良い提供力と運用パフォーマンスを示しました。ブランチ名を変えればパイプラインが直る、とはいっていません。
ビッグバン移行をせずに始めるには
ポリシーを発表しないでください。まず計測し、それから小さくしていきます。
現在のブランチの寿命と、プルリクエストの中央値サイズを記録します。これがベースラインになります。
上限を設定します。例えば2日を超えるブランチは作らない、というルールです。ダッシュボードで見えるようにします。
CIの最も遅い部分を直します。ビルドに30分かかるなら、ほかのことはまだ重要ではありません。
1つの実際の機能に1つのフラグを導入します。無効な状態で出荷し、1スプリント以内に削除します。
コードフリーズは最後に外します。巻き戻しの経路を、本当に一度使ってからです。
1か月後にもう一度レビューしてください。最初に動く数字は、通常プルリクエストのサイズとマージまでの時間です。変更失敗率には時間がかかり、問題が早く見えるようになるため、一時的に悪化することもあります。
あなたのポストモーテムは、ブランチ戦略について何と言うでしょうか
ポストモーテムには何と書かれるでしょうか。これが、出荷前に問うべき有用な質問です。直近のインシデントが、誰もレビューできなかったマージ、3週間乖離したブランチ、40件の変更をまとめたリリースに起因していたなら、その負債がどこで支払期限を迎えるかは、すでに分かっています。
直近の3件の障害を見直してください。大きく、遅いタイミングでの統合が関係していたものは何件ありましたか。その件数が、トランクベース開発に投資する根拠になります。