大規模プロジェクトはバージョン管理が重要になってくる
ソース管理について良い記事があったのでメモ。
「複数のアジャイルチームでのバージョン管理」の指摘は非常に重要なので、まとめておく。
【1】バージョン管理の目的
1-1. Fail First
コードのコンフリクトや統合の問題を早期に解決する。
1-2. 常にリリース可能
どんなに悪いイテレーションでも、その成果物はリリース可能にならねばならない。
1-3. シンプル
チェックインやマージ作業などのポリシーはシンプルで明確であること。
オブジェクト指向のパッケージ原則の一つに「再利用できる粒度とリリースできる粒度は同じだ」という法則がある。
つまり、最終的にリリース可能であるということは、その成果物が公開された時、他の誰もが安心して使える品質レベルを保障しているということ。
我々プログラマは、結局、他の開発者が使えるライブラリにするためにプログラムを書いている。
バージョン管理は、その開発インフラを支える最も基本的なインフラなのだ。
【2】バージョン管理が必要になる事情
2-1.小さなプロジェクトでは、SVNトランクだけにチェックインして、開発するだけでいい。
SVNトランクが常に最新ソースで、ビルドもされて最も安定している状態。
このレベルは、5~8人のPGが1個のチームで1個のwarを作っている事とほぼ同じ。
しかし、本番リリース後、運用保守と2次開発が平行開発するような場合、初めてリリースブランチが必要になってくる。
本番環境で動く本番モジュールはリリースブランチで管理する。
緊急のバグ修正は、このブランチ上で行う。
2次開発中のソースはトランクで管理する。
このソースは本番モジュールに混ぜない。
理由はビルドが不安定だからとか、新機能のリリース予定日は決まっていて、その日以前にリリースするのはビジネス上よろしくないなどの事情があるだろう。
重要なことは、リリースブランチにコミットされたバグ修正ソースは、すぐにトランクにマージする。
つまり、トランクは前バージョン互換であるのが基本ルールだ。
これによって、トランクの機能はリリースブランチと同じか、それ以上になる。
但し、トランクの品質は、2次開発のソースが混じっているので、リリースブランチと同等かやや落ちるはず。
2-2.大規模プロジェクトでは、更に複雑なバージョン管理が必要になる。
例えば、小売系Webシステムを考えてみよう。
そのシステムは、コンシューマ向けはS2Struts+Ajax、バックエンドのオペレーター向けはS2Dao+Flexで作るとする。
このアーキテクチャで作る場合、DB層に当たるS2Daoとそれに関連する業務ロジック層は、S2StrutsとFlexの両方で使えるように共通化しておきたい。
その理由は、S2Dao層は、S2StrutsとFlexの両方からテストされるので安定した品質を速く作りこむことができるからだ。
だから、下記のような依存関係になるように、S2Dao層をjar化しておく。
S2Struts(war)→S2Dao(jar)←Flex
このアーキテクチャでは、コンポーネント単位に開発チームが作られる。
1チーム5人程度で3チームが作られるだろう。
SVNトランクへS2Struts、S2Dao、Flexごとのメインラインが作られるだろう。
更に、Mavenを使うと、このコンポーネント単位にバージョン付けできる。
だから、war1.0.1は、jar1.0.4を使う、といった風にバージョン依存関係を指定できる。
だが、複数のコンポーネントのバージョン管理のルールはどうあるべきなのか?
基本ルールがなければ、jarのバージョンが上がるとwarやFlexで動かなくなる事象が頻繁に起こるだろう。
この場合に、「複数のアジャイルチームでのバージョン管理」のやり方が使える。
【3】バージョン管理に出てくる概念
ここで再度、「複数のアジャイルチームでのバージョン管理」にある概念を整理しておく。
3-1.メインライン
トランクがリリース可能な状態であること。
これによって、トランクがブランチを切る幹線になる。
3-2.コードライン
メインラインモデルでは、ブランチはコードラインと呼ばれる。
正確にはブランチはコードラインの実装と見なされる。
ここで、コードラインが「堅い」「柔らかい」という概念が現れる。
この概念は、コードラインの安定状態を示す。
3-2-1.堅いコードラインは安定していて、十分テストがされ、変更されることはほとんどなく、リリース間近のもの。
例えば、リリースブランチに相当するだろう。
3-2-2.柔らかいコードラインは不安定で、テストがほとんどされてなく、変更もしばしばで、リリースには程遠いもの
例えば、作業ブランチやタスクブランチが相当するだろう。
3-3.ベースライン
コードラインの親(つまりコードラインが生成された時の生成元)はベースラインと呼ばれる。
メインラインはベースラインを持たないコードラインとなっている。
この概念は、メインラインとコードラインが系統樹のように書かれる場合に良く出るだろう。
3-4.コードラインには2種類ある。
3-4-1.リリースコードライン
3-4-2.作業コードライン
メインラインより上にあるものは全てリリースコードラインと呼ばれ、これはメインラインより堅固なコードラインを意味する。
メインラインより下にあるものは全て作業コードラインと呼ばれ、これはメインラインより柔弱なコードラインを意味する。
つまり、リリースコードラインは本番モジュールそのもので、バグ修正時ぐらいしか手が入らないコードライン。
作業コードラインは、開発チームが日々チェックインしてビルドしながら作りこむコードライン。
普通は、作業ラインの1イテレーションがリリース可能状態として終わるたびに、作業ラインからメインラインへマージして、機能を反映する。
リリースラインにバグ修正が発生したら、メインラインへマージして、バグ修正を反映する。
この2つの作業によって、常にメインラインは最新機能と安定した品質が保たれる。
【4】バージョン管理の基本ルール
4-1.運用ルールは色々あろうが、「複数のアジャイルチームでのバージョン管理」によると「最も基本的なルールは、下記2点だ。
4-1-1.安定のための変更を常に受け入れること
このルールは、リリースコードライン→メインライン、メインライン←→作業コードラインへのマージ作業を指す。
4-1-2.不安定の原因になる変更を持ち込まないこと
このルールは、メインライン→リリースコードライン、Aチームの作業コードライン→Bチームの作業コードラインのマージ作業は不可を指す。
4-2.このやり方を大規模プロジェクトで置き換えてみる。
すると、下記3つを常に管理する必要があるだろう。
4-2-1.リリースコードライン
本番環境で実際に動くwar, jar, Flexモジュールそのもの。
ソースにコミットする場合は、バグ修正だけ。
メインライン(trunk)からの反映すら行わない。
4-2-2.メインライン
最新機能と安定した品質を持つモジュール一式。
いつでもリリース可能な状態に置いておく。
つまり、追加システムをリリースするたびに、このメインラインからリリースブランチを作る。
4-2-3.作業コードライン
開発チームが日々作業するモジュール一式。
基本はビルドは通すが、色んな業務フローに耐えうる品質まで至っていない場合が多いだろう。
また、SQLインジェクション対応でビッグリファクタリングする時や、新しいフレームワークを試す場合は、作業コードラインから別ブランチを作り、そこで実験することもあるだろう。
上記のバージョン管理は、実は、大手SIerよりもオープンソースに従事する開発者の方が使いこなしている。
例えば、RubyAPIやMozillaFireFoxでは、安定バージョンと新規開発バージョンを上記のように使いこなしている。
そして、世界中の開発者から送られたバグ修正パッチや改善要望を、適宜マージしながら、オープンソースを育ててゆくスタイル。
システムはリリースしたら終わりではない。
リリース後の運用保守が大切と言われる理由は、バグ修正による品質改善モードと、改善要望による機能追加モードがぐちゃぐちゃになりがちだから。
プログラマにとってバージョン管理は必須であるにも関わらず、実は使いこなせていない人は多くないだろうか?
| 固定リンク
「プロジェクトマネジメント」カテゴリの記事
- 「スクラムの拡張による組織づくり」のScrum@Scaleの感想(2024.03.31)
- ストラテジストとプロジェクトマネージャの役割の違いは何なのかpart2~プロセスのレイヤと達成目標のレイヤが異なる(2023.02.18)
- ストラテジストとプロジェクトマネージャの役割の違いは何なのかpart1~CSFはWBSみたいなものと捉える(2023.02.14)
- PM理論では課業志向の方が関係志向よりも生産性が高いことを主張しているのではないか(2023.01.22)
- 現代日本人の弱点はリーダーシップ不足と生産性が著しく低いこと、そしてリスク許容度が著しく低いことだ(2022.12.23)
コメント