リリースを安定させるプロセス

リリースを安定させるプロセス とは、 リリースブランチをリリースできる状態に持っていく作業です。 つまり、どの変更をリリースに含めるか、含めないかを決定し、 その方針に従ってブランチを整備することです。

この "決定" という言葉には、厄介なことがたくさん含まれています。 リリース直前に新機能がたくさん出てくるのは、 協調的なソフトウェアプロジェクトでは日常茶飯事です。 開発者はリリースが近いことを知ると、 それに乗り遅れまいとして大急ぎで変更作業を終えようとします。 これは勿論、リリースするときにはまさに起こって欲しくないことです。 開発者は自分の好きなペースで新機能を実装していればいいのであって、 自分の変更が今回、または次のリリースに含まれるかどうかは心配しない方がいいのです。 ひとつのリリースに多くの変更を直前に詰め込もうとすればするほど、 コードは不安定になり、(普通)多くのバグが発生してしまうのです。

ほとんどのソフトウェアエンジニアは、 リリースを安定化する過程でどの変更をリリースに取り込むべきかについて、 おおまかな点で一致しています。深刻なバグ、 特に回避しようがないバグの修正は含めていいでしょう。 ドキュメントの更新も含めていいでしょうし、エラーメッセージの修正(但し、それがインターフェイスの一部と考えられていて、 安定していなければいけない場合は別です)も同様です。 多くのプロジェクトでは、リスクが低いか、コアに影響しない変更も受け入れますし、 リスクを測るための正式なガイドラインもあるでしょう。 しかし、どんな基準があったとしても人間の判断は必ず必要です。 変更をリリースに取り込むか否かをプロジェクトが決めなければいけないのは日常茶飯事でしょう。 危険なのは、開発者それぞれが自分の変更をリリースに含めたいと思っているので、 変更を受け入れることを望む人は多いのに、それに対して NO という人が少ないことです。

そういうわけで、リリースを安定化させるプロセスは、 ほとんどが "NO" と言う仕組みを作ることと同じです。 オープンソースプロジェクトに特有なのは、 開発者を傷つけたり、がっかりさせることなく "NO" といいつつ、 価値がある変更はリリースに取り込むようにする方法に知恵を絞っていることです。 たくさんの方法がありますが、いったん開発チームがそれらを重要な基準として注目すれば、 基準を満たす仕組みを作るのは簡単です。 ここではもっとも人気のある、両極端なやり方をふたつ簡単に説明しますが、 二つだけにすることで、プロジェクトが創造性をなくしてはいけません。 他のやり方はたくさんあるでしょうから、 私が実際に使われているのを見たことがあるふたつだけに留めておきます。

リリースオーナーによる独裁

開発者グループは特定の人物がリリースオーナーになることに同意します。 リリースオーナーはどの変更をリリースに取り込むかを決める最終的な権限を持ちます。 勿論、それについては通常議論が行われますし、期待されていますが、 開発者グループは結局、リリースオーナーに最終的な決断を行うための十分な権限を与えなければなりません。 この仕組みがうまく機能するには、加えられた全ての変更を理解できる卓越した技術力を持ち、 社会的にうまくやっており、多くの人を傷つけずにリリースにもっていけるよう議論を導くコミュニケーション能力がある人を選ばなければいけません。

よくあるのは、"この変更は間違ってないけど、テストをする十分な時間がとれていない。 だから、今回のリリースに含めるべきではない。" というものです。 これは、リリースオーナーがプロジェクトに関連した技術の知識を広く持っている場合に大いに役立ちますし、 その変更が潜在的にコードを不安定にする(たとえば、ソフトウェアの他の部分に与える影響や、移植性に関することなど)理由を得ることができます。 場合によっては、リリースオーナーの決定が正しいことを証明せよという人や、 見た目ほどその変更はリスキーでないと主張する人も現れます。 リリースーオーナーは、こうした主張のすべてが自分の決定に反対しているか、 反対に固執しているわけではないと判断できれば、 こうした主張に真正面からぶつかる必要はありません。

プロジェクトリーダーがリリースオーナーになる必要はないことに注意してください。 (そもそもプロジェクトリーダーがいる場合は、4章プロジェクトの政治構造と社会構造「優しい独裁者」 を参照してください) 実際、プロジェクトリーダーとリリースオーナーは兼任 しない ほうがよいことがあります。 優れたプロジェクトリーダーになるのに必要なスキルは、リリースオーナーになるのに必要なそれと同じではありません。 リリースプロセスと同じくらい重要な局面では、 誰かがプロジェクトリーダーの判断を相殺するくらいの方が賢いかもしれません。

この章の後半にある 「リリースマネージャー」 で説明するリリースマネージャーは、 リリースオーナーとは対照的に独裁的ではありません。

リリースに含める変更を投票で決める

リリースオーナーの独裁と正反対のやり方ですが、 開発者はどの変更をリリースに取り込むかを投票することができます。 しかし、リリースの安定化するプロセスで一番重要なのは変更を除外することなので、 複数の開発者が積極的に賛成した変更をリリースに取り込めるように投票システムを設計することが重要になります。 変更をリリースに取り込むには、過半数以上の賛成が必要とすべきです(4章プロジェクトの政治構造と社会構造「誰が投票するのか?」) を参照してください)。 別のやり方として、一人が賛成し、他の人が反対しなければ十分という考え方もあるでしょうが、 不幸な政治力学によって、各々の開発者は自分が加えた変更に賛成票を投じるが、 報復を恐れて他の開発者の変更には反対票を投じたがらなくなるという状況が生まれます。 これを避けるには、開発者達にあらゆる変更をリリースに取り込めるよう協力して行動させるように、システムを変えるべきです。 これは多くの開発者が個々の変更をレビューするだけでなく、 それぞれの開発者が変更に対して反対票をためらわずに投じることも意味します。 なぜなら、自分の意見とは反対の票を投じる人が、自分を侮辱していると思う人はいないからです。 参加する人が多くなればなるほど、個人に関する議論ではなく、 変更に関する議論が多く行われるようになります。

Subversion プロジェクトで使われているシステムは、 うまくバランスがとれているようなので、私はここでそれをお勧めします。 ある変更をリリースブランチに適用するには、 少なくとも3人の開発者が賛成しなければならず、反対する人がひとりもいてはいけません。 "反対" の票がひとつでもあれば、リリースに含めるのを止めるのに十分です。つまり、 リリースにおける "反対" 票は拒否権と同じになります(「拒否権」 を参照してください)。 当然のことですが、この手の反対票を投じるには正当な理由がなければなりませんし、 理屈の上では十分多くの人が不当だと感じれば覆すことができますし、 特別な投票があっても同様です。実際、こんなことは決して起こりませんし、 起こって欲しくもありません。どちらにせよ人々はリリースに対しては保守的ですし、 誰かがある変更をリリースに含めることに拒否権を投じたいと強く感じるときは、 普通は十分な理由があるときです。

リリースの手続きはわざと保守主義に偏っているので、 正当な理由が付けられた反対票は、技術的というより手続き的に扱われることがあります。 たとえば、ある変更はよく書かれていて、バグは起こさないだろうけど、 マイクロリリースに含めるには変更の規模が大きいからという理由で反対票を投じる人がいるかもしれません。 — 多分その変更は新機能を加えるものか、 微妙な点で互換性のガイドラインに完全に準拠していないのでしょう。 ある変更にもっとテストが必要だと直感で思ったという理由で反対票を投じる開発者を見たことがありますが、 綿密に調べても何のバグも見付けられなかったのです。 開発者たちはちょっと不平をいいましたが、反対票は有効なまま、 その変更はリリースに含められなかったのです。 (ですが、後のテストでバグが見付かったかどうかを私は覚えていません)

リリースを安定させるプロセスを管理する

プロジェクトで投票システムを変える選択をした場合、 投票用紙や決選投票を行う物理的な仕組みをできるだけ便利にすることが求められます。 たくさんの電子投票システムがオープンソースで公開されていますが、 実際もっとも簡単なのは、 リリースブランチに STATUS または VOTES といったテキストファイルを用意することです。 このファイルは提案されている変更を一覧にしています。— 開発者であれば誰でも変更をリリースに取り込むよう提案することができます。 — このファイルには、全ての投票と、それに対する賛成、反対意見、それに加えてあらゆるメモ、そしてコメントが書き込まれています。 (ところで、変更を提案することは、 必ずしもその変更に賛成票を投じているというわけではありません。しかし、 そのふたつは同時に行われることがよくあります。) こうしたファイルのエントリは、次のようになるでしょう。

* r2401 (問題 #49)
  クライアント/サーバのハンドシェイクが2度行われるのを避ける。
  変更する理由:
    余計なネットワークのターンアラウンド時間を減らす。変更の規模は小さく、レビューしやすい。
  メモ:
    これについては http://.../mailing-lists/message-7777.html
    及びこのスレッドにある他のメッセージで議論された。
  投票:
    +1: jsmith, kimf
    -1: tmartin (バージョン 1.0以前のサーバとの互換性が壊れてしまう。
                 確かに、1.0以前のサーバはバグが多いが、だからといって
                 何故必要もないのに互換性を壊すのか?)

この場合、提案された変更は賛成票を2つ得ていますが、 tmartin によって拒否権を行使されています。 tmartin は括弧つきのメモで拒否権を行使した理由を述べています。 正確なフォーマットは問題ではありません。 つまり、プロジェクトでどのように決めてもよいのです — 多分、 tmartin が拒否権を行使した理由は "メモ:" のセクションに移すか、 変更の理由は他のセクションに合わせて "説明:" ヘッダをつけるべきでしょう。 重要なのは、変更を評価するのに必要な全ての情報を到達可能にしておくことと、 決選投票をする仕組みをできるだけ簡単にしておくことです。 提案されている変更はリポジトリのリビジョン番号で参照します。 (今回の場合は、単一のリビジョン r2401 ですが、複数のリビジョンでも簡単にできます) リビジョン番号は、trunk に加えられた変更を参照することが想定されています。 既にリリースブランチに変更が加えられている場合は、投票する必要はないでしょう。 もしバージョン管理システムが個々の変更を参照する明示的な文法を持ってない場合は、 プロジェクトが作るべきです。投票を実効性のあるものにするためには、 対象となる各々の変更は曖昧でない状態で識別できなければならないのです。

こうした変更の提案、もしくは投票の対象になる変更は、 必ずリリースブランチに綺麗に適用できなければなりません。つまり、 衝突せずに適用できるということです(コンフリクト を参照してください) もし衝突がある場合は、綺麗に適用するよう調整したパッチか、 変更を調整したバージョンを格納した一時ブランチを投票のエントリに記述すべきです。 たとえば次のようなものです。

* r13222, r13223, r13232
  libsvn_fs_fs の自動マージアルゴリズムを書き直した
  変更する理由:
    30万リビジョンが格納されたリポジトリのパフォーマンスが許容できない
    (小さなコミットをしても50分以上かかる)
  変更を加えたブランチ:
    1.1.x-r13222@13517
  投票:
    +1: epg, ghudson

この例は実在のプロジェクト、 つまり Subversion 1.1.4 のリリースプロセスで作られた STATUS ファイルから引用したものです。 変更が起こした衝突を調整したブランチがあるにもかかわらず、 オリジナルのリビジョンを、どうやって変更を表現する規則的な名前にしているかに注意してください。 (そのブランチも、変更をリリースにマージするのを容易にするために3つのtrunkリビジョンを r13517 というリビジョンにまとめていますが、これは許されるはずです) この例にはオリジナルのリビジョンが記述されています。 なぜなら、ログメッセージが残っているので、もっともレビューしやすいからです。 一時的なブランチにはそうしたログメッセージはないでしょう。 情報の重複を避けるため(3章技術的な問題「情報の一元管理」 を参照してください)、 ブランチのログメッセージは"r13222, r13223, r13232 を 1.1.x ブランチ用に調整した" と簡単にすべきでしょう。 変更に関する情報は全てオリジナルのリビジョンから追いかけることができます。

リリースマネージャー

リリースに取り込む変更を実際にリリースブランチにマージする(マージ (あるいはポート) を参照してください)プロセスは、開発者であれば誰でもできます。 変更をマージする専門の人を置く必要はありません。もし変更がたくさんあれば、 マージする負担を分散させた方がよいかもしれません。

投票することと変更をマージすることは別々に行われますが、 実際にはリリースプロセスを指揮する人がひとりかふたりはいます。 この役割を正式に リリースマネージャー と呼ぶことがありますが、 どの変更を取り込むかに関する最終的な決定権があるリリースオーナー(この章のはじめの方の 「リリースオーナーによる独裁」 を参照してください)とは全く別物です。 リリースマネージャーは、リリースに取り込む候補になる変更の数や、 実際に取り込まれた変更の数、そして取り込まれる可能性が高い変更の数などを追いかけています。 重要な変更に対して開発者が十分に注意を払わず、 投票もされずに放置されるかもしれないとリリースマネージャーが感じた場合、 彼らは他の開発者に小言を言ってレビューや投票をするよう促します。 リリースに取り込む変更がたまってきたら、 リリースマネージャーが引き取ってまとめてリリースブランチにマージすることもあります。 変更を明示的にコミットする以外の仕事を全て彼らにやらせる必要はないと理解しているのなら、 他の開発者がそうした仕事をリリースマネージャーに任せられるのはよい状態です。 リリースを世に出す時がきたら(この章の後半の 「テストとリリース」 を参照してください)、 リリースマネージャーは最終的なリリースパッケージを作成したり、 デジタル署名を集めたり、パッケージをアップロードしたり、 公式にアナウンスを出す作業に注意を払います。