第7章 パッケージの作成、リリース、日々の開発

目次

リリースに番号を付ける
リリース番号の構成要素
単純なやり方
奇数/偶数 に意味を持たせるやり方
リリースブランチ
リリースブランチの使い方
リリースを安定させるプロセス
リリースオーナーによる独裁
リリースに含める変更を投票で決める
リリースを安定させるプロセスを管理する
リリースマネージャー
パッケージング
パッケージのフォーマット
パッケージ名とレイアウト
大文字にするか、小文字のままにするか
プレリリース版
コンパイルとインストール
バイナリパッケージ
テストとリリース
リリース候補
リリースを告知する
複数のリリースラインを管理する
セキュリティリリース
リリースと日々の開発
リリースの計画を立てる

この章では、フリーソフトウェアのプロジェクトが、 ソフトウェアをパッケージングしてリリースする方法と、 開発パターン全体がこうした目標にどう繋がっているのかについて述べていきます。

オープンソースプロジェクトと独占的なソフトウェアのプロジェクトとの主な違いは、 開発チームに対して中央集権的な管理が行なわれているかどうかにあります。 新しいリリースを準備しているとき、この違いは特にはっきりします。 独占的なソフトウェアのプロジェクトでは、企業は今度のリリースにかかわる作業に集中し、 新機能の開発や重大でないバグフィックスは、 リリースが終わるまで脇に置いてくれと開発チーム全体に求めることができます。 ボランティアの集団はそんな一枚岩ではありません。 オープンソースプロジェクトの人々は様々な理由で働いています。 よってリリース作業を手伝うことに興味がない人たちは、 たとえリリース作業が進行中でも日々の開発作業を続けたいと考えます。 開発が止まることはないので、 オープンソースソフトウェアのリリース作業は、 独占的なソフトウェアのそれに比べて時間がかかりがちですが、 混沌としたものではありません。 これは高速道路の修復にちょっと似ています。 道路を直すには二つやり方があります。 ひとつは、道路全体に作業員が群がって問題が解決するまで全力で働けるように、 道路を完全に閉鎖することです。 もうひとつは、一度にひとつの車線でだけ作業を行い、 もう一方は通行できるようにしておくことです。 はじめのやり方は 修理を行なう作業員にとっては 効率がいいやり方ですが、 それ以外の人にはよくありません — 作業が終わるまで道路全体が閉鎖されるからです。 ふたつめのやり方は時間がかかり、修理する作業員は大変です(少ない人数、少ない機械、 窮屈な環境での作業を強いられる上、 通行する車を徐行させて交通整理をする旗振り役も置かなければいけない、など)が、 作業員が全力を出さなくても少なくとも道路は使いやすい状態のままです。

オープンソースプロジェクトはよくふたつめのやり方で動いています。 実際、複数の異なったリリースラインがある状態で、 成熟したソフトウェアのモジュールを管理するために、 プロジェクトはずっと小規模な道路修理を続けているような状態です。 いつも二つの車線が閉鎖して作業をしています。つまり、 リリースを定期的なスケジュールに従って行なえるように、 開発チームは裏で起こるささいな不都合にはいつも目をつぶっているのです。

この作業モデルはリリース作業以外にも一般化できます。 互いに依存していないタスクは平行して処理をするという原則です。— これはオープンソースソフトウェアの開発に限ったものではありませんが、 オープンソースプロジェクトは、独自のやり方でこの原則を実践しています。 プロジェクトで作業をしているボランティア達は、 道路工事の作業員や通行する車を気にする余裕はそんなにありませんし、 カラーコーンの傍に待機して車に旗を振らせることに作業員を専念させる余裕もないのです。 つまり、彼らはプロジェクト管理の負荷の変化が激しい管理プロセスよりは、 負荷が一定か、変化が少なくなるようなプロセスを好みます。 ボランティアたちは、ちょっと不便だなと思う状態が続いても嫌がりません。 自分にかかる負荷が予想できるからこそ、 彼らはプロジェクトで起こっていることがスケジュールと衝突しているかどうかを気にせずに作業できるのです。 プロジェクトが別の作業をやめてある作業に専念させるようなマスタースケジュールに縛られていると、 多くの開発者が長い間何もしない状態が発生します — これは非効率であるばかりか、 退屈なので危険です。退屈した開発者は、すぐに辞めてしまうでしょう。

リリース作業は、 平行して行なわれる作業のなかでも開発とは関係ないもっとも目立つタスクです。 よって次のセクションで説明するやり方で、 リリース作業を行なうタイミングを調整しています。 しかし、リリース作業と平行して行なえる作業、 たとえば翻訳や国際化、 コードベース全体に徐々に浸透するようにAPIを大規模に変更する、 などが同時に行なわれていることに注意してください。

リリースに番号を付ける

リリースを行なう方法を議論する前に、 リリースに対する名前の付け方をみておきましょう。 これは、リリースがユーザーにとって何を意味するのかを知らせるのに必要なものです。 リリースとは、次のようなものです。

  • 古いバグが直っています。 これは全てのリリースに当てはまると多分ユーザーが期待していいことでしょう。

  • 新しいバグが入り込んでいます。 これは時々行なわれるセキュリティリリース(この章の後半の「セキュリティリリース」を参照してください)や他の単発リリースを除いて、普通は十分過ぎるほどあり得ることです。

  • 新機能が追加されているかもしれません。

  • 新しい設定オプションが追加され、 古いオプションの意味が微妙に変わっているかもしれません。 あって欲しくないことですが、 直前のリリースと比べてインストール手順も変わっている可能性があります。

  • 互換性のない変更が入っているかもしれません。たとえば、 古いバージョンで使われていたデータフォーマットはある種の変換を(多分手動で)しないともはや使えなくなっているといったものです。

見てわかる通り、全てが良いことばかりではありません。 よって経験豊富なユーザーは、新しいリリースを少し恐る恐る扱います。 特にそのソフトウェアが成熟しており、 既にユーザーが求めた(または欲しいと思った)動きをほとんどしてくれていた場合はなおさらです。 たとえ新機能が追加されても、 それによってソフトウェアが意図しない振舞いをするかもしれないという点で、 ありがた迷惑なものなのです。

よって、リリースに番号を付ける目的はふたつあります。 当然、 リリース番号はリリースの順番を明確に伝える(i.e. ふたつのリリース番号を見れば、 どちらが新しいものかがわかる)べきものですが、 それだけではなくて、 変更の性質や程度をできるだけ簡潔に示すものでなければなりません。

そんなことを全部数字で表現するのかって? まあ、程度の差はありますが答えはYESです。 リリース番号の付け方は、 些細な話題なのに最も古くからあちこちで議論されてきた(6章コミュニケーション 「簡単な議題ほど長引く」 を参照してください)もののひとつですが、 近い将来、唯一の完全な標準に落ち着く気配はありません。 しかし、一貫していること という普遍的に受け入れられた原則に基づいて、 優れた戦略がいくつか出てきています。 番号の付け方を選び、それを文書化し、守るようにしましょう。 番号の付け方をはっきりさせれば、ユーザーはあなたに感謝することでしょう。

リリース番号の構成要素

このセクションではリリース番号を付ける規約を説明しますが、 読者に前提となる知識が殆どないことを想定しています。 主に参考資料として読まれることを意図していますが、 あなたが既にこうした規約に馴染んでいるのなら、飛ばして読んでも構いません。

リリース番号はドットで区切られた数字の集まりです。

Scanley 2.3
Singer 5.11.4

... などです。ドットは 小数点では なく、 単なる区切りです。"5.3.9" の次は "5.3.10" となります。 プロジェクトによっては、ドットを小数点ととしてあらわすところもあります。 もっとも有名な Linux Kernel では、Linux 1.0 に至るまでに、 "0.95", "0.96" ... "0.99" と番号が続きますが、 ドットが小数点ではないという規約は今や確固としたものとして確立され、 標準となっているはずです。 バージョン番号の構成要素(ドットを除いた数字の部分)の数に制限はありませんが、 殆どのプロジェクトでは3つか4つにとどめています。 その理由は後に明らかにしていきます。

数字の部分に加えて、 "Alpha" とか "Beta"(アルファ版/ベータ版 を参照してください) といった、 バージョンの状態を説明するラベルを付加するプロジェクトもあります。 たとえば次のようなものです。

Scanley 2.3.0 (Alpha)
Singer 5.11.4 (Beta)

Alpha や Beta といった識別子は、 同じバージョン番号ながら、 こうした識別子がつかないものが将来リリースされることを示しています。 よって、"2.3.0 (Alpha)" は結局 "2.3.0" になります。 このように、複数の最終リリースの候補となるものを一行であらわすために、 識別子そのものが メタ識別子 を持つことができます。 例として、一般の人が利用できるようになるまでの順番で、 一連のリリースを以下に示します。

Scanley 2.3.0 (Alpha 1)
Scanley 2.3.0 (Alpha 2)
Scanley 2.3.0 (Beta 1)
Scanley 2.3.0 (Beta 2)
Scanley 2.3.0 (Beta 3)
Scanley 2.3.0

"Alpha" という識別子がついているときに、 Scanley "2.3" は "2.3.0" と記されていることに注意してください。 "2.3" と "2.3.0" は等しいものです。 — つまり、番号にくっついているゼロの部分は簡潔にするためにいつでも省略できます。— しかし、識別子があるときは、簡潔さはもはや問題ではありません。 よって、"2.3" という簡潔な記述ではなく、"2.3.0" と完全な形で表記する方がよいでしょう。

比較的よく使われる他の識別子には "Stable", "Unstable", "Development", そして "RC"(リリース候補 という意味)があります。 もっとも広く使われているのは 未だ "Alpha" と "Beta" で、 "RC" が3番目あたりの位置にきますが、 "RC" の後には常に数字のメタ修飾子が付くことに注意してください。 つまり、"Scanley 2.3.0 (RC)" をリリースするのではなく、 "Scanley 2.3.0 (RC 1)" をリリースしてから RC2 を、という具合です。

"Alpha", "Beta", "RC" という3つのラベルは今や広く知られているので、 たとえ他のラベルが、内輪の用語ではなく、 普通の用語だからという理由で一見よい選択のように見えても、 他のラベルを使うのはお薦めしません。 ソフトウェアをインストールする人々はこの3つのラベルに既に馴染んでいますし、 根拠無しに他のプロジェクトがやっていることと違ったことをする理由はありません。

リリース番号にあるドットは小数点ではありませんが、 数字の位置には重要な意味があります。 バージョン "1.0"(これはもちろん、"1.0.0" と等しいです) より前のリリースは全て "0.X.Y" というリリースです。 "3.14.158" のすぐ後は、"3.14.159" であって、 "3.14.160" や、"3.15.XXXXXX" などではないのです。

リリース番号を付ける一貫した決まりがあれば、 ユーザーは同じソフトウェアのふたつのリリース番号を見て、 数字だけでふたつの重要な違いを区別できるようになります。 3つの数字からなる典型的なリリース番号では、 はじめの数字は メジャー番号、 ふたつめは マイナー番号、 そして三つめは マイクロ番号 になります。 たとえば、バージョン "2.10.17" は 2番目のメジャーリリースシリーズのうち、 10番目のマイナーリリースラインであり、 そのライン上での17番目のリリースということになります。 "ライン" と "シリーズ" という言葉は、ここではくだけた使い方をしていますが、 文字通りの意味です。メジャーシリーズというのは、 単に同じメジャー番号を共有するリリース全てを指し、 マイナーシリーズ(またはマイナーライン)は、 同じメジャー番号 マイナー番号を共有する全てのリリースを指します。 つまり、"2.4.0" と "3.4.1" は "4" というマイナー番号は同じですが、 同じマイナーシリーズではありません。 一方、"2.4.0" と "2.4.2" は 、 "2.4.1" がそれらの間にリリースされる場合には隣り合うリリースにはなりませんが、 同じマイナーシリーズに属しています。

これらの数字の意味は、あなたが期待する通りの意味になります。 つまり、メジャー番号をひとつ増やすことは、大きな変更が行われたことを示しています。 マイナー番号をひとつ増やすことは、小さな変更が行われたことを意味しています。 そしてマイクロ番号をひとつ増やすことは、 本当につまらない変更が行われたということになります。 プロジェクトによっては、特にリリース間の違いをきめ細かく管理するために、 パッチ番号 と通常呼ばれる4番目の番号を追加しているところもあります。 (混乱しやすいのですが、"パッチ番号" を、 3番目のマイクロ番号と同じ意味で用いているプロジェクトもあります。) 最後の数字を ビルド番号 として用いるプロジェクトもあります。 ビルド番号はソフトウェアがビルドされるたびにひとつ増えていき、 ビルド以外の変更がないことをあらわしています。 ビルド番号はバグレポートを特定のビルド番号に結びつけるのに役立ちますし、 バイナリパッケージを通常配布しているプロジェクトで、恐らくもっとも役に立つでしょう。

いくつ数字を使うのか、それぞれの数字が何を意味するのかについては、 多くの異なる規約がありますが、その違いの多くはマイナー番号に関するものです。 — マイナー番号については裁量の余地がありますが、そう多くはありません。 次の2つのセクションでは、 もっとも広く使われている規約のうち、いくつかを議論します。

単純なやり方

ほとんどのプロジェクトには、たとえマイクロ番号をひとつ増やすだけの場合であっても、 どんな修正をリリースに取り込むかについてのルールがあります。 マイナー番号を増やす場合にはまた違ったルールがありますし、 メジャー番号を増やす場合はさらにルールが違います。 こうしたルールに決まった基準はありませんが、 複数のプロジェクトでうまく使われてきたルールをここで説明します。 あなたのプロジェクトでこのルールを単純に採用してもよいのですが、 たとえそうしなくても、これはリリース番号が伝える情報をうまく表現する見本になります。 このルールは、APRプロジェクトで使われているものです。 http://apr.apache.org/versioning.html を参照してください。

  1. マイクロ番号だけに影響する(つまり、 同じマイナーライン上で行う)変更は、 前方互換性と後方互換性の両方がなければなりません。 つまり、変更はバグ修正のみか、 既にある機能に対するわずかな改善にとどめるべきです。 新機能は、マイクロ番号を変更するリリースに取り込んではいけません。

  2. マイナー番号に影響する(つまり、 同じメジャーラインで行う)変更には、 後方互換性がなければなりませんが、前方互換性は必ずしも必要ありません。 マイナー番号を変更するリリースでは、 新機能を取り込むのが普通ですが、 一度にたくさん取り込んだりはしません。

  3. 互換性を維持するには限度があります。 メジャー番号に影響する変更がその境目となります。 新しいメジャーリリースには前方互換性も後方互換性もありません。 メジャーリリースには新機能が含まれているはずですが、 全ての機能が新しくなっている場合さえあります。

後方互換性前方互換性 の正確な意味は、 ソフトウェアが実現することに依存しますが、解釈の余地がないのが普通です。 たとえば、あなたのプロジェクトがクライアント/サーバ アプリケーションを作っているとすると、 "後方互換性" とは、サーバを 2.6.0 にアップグレードしても 既にあるバージョン 2.5.4 のクライアントが以前と異なる振舞い(もちろんバグを直した場合は別です)をしたり、 動かなくなる機能があってはいけないということです。 一方、サーバを 2.6.0 にアップグレードすると同時に、クライアントも2.6.0にすると、 新しい 機能がクライアントで使えるようになるかもしれませんが、 2.5.4で使えていたクライアントの機能は 2.6.0 でどう扱われるかわかりません。 こういうことが起こると、このクライアントのアップグレードには 前方互換性が ない ことになります。 つまり、クライアントを 2.5.4 にダウングレードしても、 2.6.0 で使えていた全ての機能は使えないということになります。 なぜなら、2.6.0 の機能には新機能が含まれているからです。

こういうわけで、マイクロリリースは本来バグフィックスのためだけに存在します。 マイクロリリースでは前方、後方互換性の両方を維持しなければなりません。 つまり、2.5.3 から 2.5.4 にアップグレードしたあとで気が変わって 2.5.3 に戻したとしても、 特定の機能が失われてはいけません。 もちろん、2.5.4 で直したバグはダウングレードするとまた再現するでしょうが、 そのバグがあっても既に動いている機能が使えていれば、 機能が失われたことにはならないのです。

クライアント/サーバ 間のプロトコルは、 互換性の問題が起きる可能性がある分野のひとつです。 別の分野として、データフォーマットがあります。 ソフトウェアがデータを永続的なストレージに保存するでしょうか? もしそうなら、読み書きを行うフォーマットはリリース番号のルールで決まっている互換性のガイドラインに従う必要があります。 バージョン 2.6.0 は 2.5.4 が保存したファイルを読み込める必要がありますが、 2.5.4 が読めないフォーマットに黙ってアップグレードしているかもしれません。 なぜなら、マイナー番号をまたがるとダウングレードできる必要はないからです。 あなたのプロジェクトが他のプログラムで使われているライブラリを配布しているとすると、 その API も互換性の問題が起こる領域に入ります。 新しいバージョンに古いバージョンを置き換える形でアップグレードしても安全かどうか、 詳しいユーザーがわかるように、 ソース、バイナリレベルでの互換性に関するルールを詳しく説明しておかなければいけません。 詳しいユーザーは、バージョン番号をみれば互換性があるかどうかがすぐにわかるでしょう。

このしくみでは、メジャー番号を増やすまで過去のしがらみなしに再出発する機会はありません。 このため不便な状況になることもたびたびあります。 自分が本当に追加したいと思っている新機能があったり、 プロトコルを再設計したいと思ったとしても、互換性を維持している間はそう簡単にできません。 最初から拡張可能な方法で設計すること(このトピックに関しては一冊本を書く価値がありますし、 この本の範囲外でしょう)以外に、この問題に対する魔法の解は存在しません。 しかし、リリース間の互換性に関するルールを示し、 それを守ることはソフトウェアを配布するにあたって不可欠です。 不愉快な思いを一度させてしまうと、多くのユーザーが離れていってしまいます。 ここまで説明してきた互換性に関するルールは、 広く知られているだけでなく、まだそういったルールに馴染みがない人にも説明しやすく、 覚えてもらいやすいという点で優れています。

互換性に関するルールは、バージョン 1.0 以前には適用されないことが一般に知られています。 (しかし、はっきりさせておくために、 リリースポリシーではこのことを明示的に宣言しておくべきです) 開発の初期段階にあるプロジェクトは、 バージョン 0.1, 0.2, 0.3 といった順で、 1.0 の準備ができるまでリリースを行うことができますし、 リリース間の違いを適宜大きくすることができます。 バージョン 1.0 以前は、マイクロ番号を使うかどうかは任意です。 プロジェクトの性質とリリース間の差異によっては、 0.1.0, 0.1.1 といった番号があれば便利かもしれませんし、そうでないかもしれません。 バージョン 1.0 以前のリリース番号のルールはかなりルーズです。 これは互換性に関する制約をきつくすると初期段階の開発を著しく妨げることと、 早くから使っている人はどちらにせよ寛大な傾向にあることが主な理由です。

こうした制約は、3つの数字を使った番号の付け方にだけ当てはまります。 あなたのプロジェクトでは、3つの数字を使って、 これとは違った番号の付け方を簡単に思い付くでしょう。 もしくは、細かい粒度は必要ないので、 代わりに2つの番号を使おうと決めることもできるでしょう。 重要なのは、こういうことは早めに決めておいて、 それぞれの数字が意味するところを正確に皆に知らせ、それを守ることです。

奇数/偶数 に意味を持たせるやり方

プロジェクトによっては、 マイナー番号の 偶数/奇数 をソフトウェアの安定度を示すために使うことがあります。 つまり、偶数は安定版で、奇数は不安定版ということです。 これはマイナー番号にのみ当てはまることで、 メジャー番号とマイクロ番号には当てはまりません。 マイクロ番号をひとつ増やすことは、 バグフィックスが行われた(新機能はない)ことを示しますし、 メジャー番号をひとつ増やすことは、 大きな変更が行われたか、新機能が揃っていることをあらわしています。

数あるプロジェクトの中でも、 特に Linux Kernel プロジェクトで使われてきたこの仕組みの利点は、 製品版を使うユーザーが潜在的に不安定なコードの影響を受けることなく、 新しい機能をテスト用にリリースできることです。 ユーザーは、リリース番号から、 "2.4.21" は現在動いているWebサーバのマシンにインストールしていいが、 "2.5.1" は多分家のワークステーションの実験用に限るべきだろう、 ということがわかります。 開発チームは不安定版(マイナー番号が奇数のもの)に関するバグレポートを扱い、 不安定版でいくつかのマイクロ番号のリリースを重ねて安定してきたら、 マイナー番号をひとつ増やし(つまり、マイナー番号を偶数にします)、 マイクロ番号を "0" にリセットします。 そして恐らくは、安定版のパッケージをリリースしていくことになるでしょう。

この仕組みは少なくとも、以前説明した互換性のガイドラインと衝突しないことを保証します。 これはマイナー番号にいくらか追加情報を付加したものです。 これによって、他の仕組みよりマイナー番号がひとつ増える回数が2倍多くなりますが、 大きな害はありません。 奇数/偶数に意味を持たせる仕組みは、 リリースサイクルがとても長いプロジェクトでもっとも有効でしょうし、 プロジェクトの性質上、 新機能よりも安定性に重きを置く保守的なユーザーの割合が高いところでも有効です。 この仕組みが、新機能を大胆にテストする唯一の方法ではありません。 この章の後半の 「リリースを安定させるプロセス」 でも説明していますが、 潜在的に不安定なコードをリリースするもっと一般的な方法は、 ユーザーがリスクと利益のトレードオフをリリース名からすぐに把握できるように、 リリースにマークを付けることです。