下流のパッケージングをサポートする

ページステイタス:

ドラフト

最終査読日:

2025-?

PyPI および pip のような Python のパッケージングツールは、Python パッケージを配布する主要な手段ですが、その一方で、しばしば他のパッケージングエコシステムの一部として利用可能にされています。これらの再パッケージングの努力は、ダウンストリーム パッケージングと総称され (対して元の方は アップストリーム パッケージングと総称されます)、 Linux ディストロ・Conda・Homebrew・MacPorts といったプロジェクトが (訳註:ダウンストリームパッケージングに) 該当します。これらは、一般的には、 Python パッケージングツール単独では取り扱えないようなユースケースをよりよくサポートすること、例えば、特定のオペレーティングシステムとの間でネイティブな統合をすることや、非 Python ソフトウェアの特定のバージョンとの互換性を保証することを目指しています。

この議論では、ダウンストリームパッケージングが通常どのように行われるのか、および、ダウンストリームパッケージングが直面する追加的なチャレンジがどのようなものであるかを説明することを試みます。 (アップストリームプロジェクトを保守する上で何らかの大きな追加作業を招来しない範囲で) ダウンストリームパッケージングを 劇的に 簡単なものにするような、プロジェクトの保守者が追随することを選択してもよいいくつかの選択可能なガイドラインを提供することを目指しています。これが全部採用するかまったく採用しないかという提案ではないことを銘記してください -- アップストリーム側の保守者が為し得ることは、たとえそれが小さな部分だけだったとしても、すべて役に立ちます。ダウンストリーム側の保守者もこれらの問題を解決するためのパッチを提供することに意欲的です。他のダウンストリーム群がパッチを作成してリベースし続ける必要を取り除くことや、同じ問題に対して一貫性のない解決策を適用するリスクを取り除くことができるので、このようなパッチをマージすることは非常に助けになります。

ソフトウェアの保守者達とダウンストリームのパッケージ作業者の間の良い関係を確立することは、相互に利益をもたらします。ダウンストリーム側は、しばしば、パッケージを改良するために彼らの経験・時間・ハードウェアを共有したいと望み、そうしなければ獲得するのに多大な労力を必要とする他パッケージとの関係について情報を提供したいと望んでいます。パッケージ作業者は、しばしば、プロダクションレベルになった後でユーザがそのバグを踏むよりも前に、高品質のバグレポートを提供し、可能な時ならいつでもパッチを供給します。例えば、彼らは、新しい Python のバージョンがリリースされた時に起きる互換性問題のいずれについても、彼らが再配布するパッケージがアップデートされていることを確実にすることに恒常的に活発です。

ダウンストリームのビルドには、バイナリ形式での再配布だけでなく、 (例えば、Gentoo Linux のようなソースコードありきのディストロで) ユーザ側のシステムで行われるソースビルドも含まれることを銘記してください。

完全な形のソースコード配布物を提供する

なぜ?

ダウンストリームのパッケージ作業者の大多数は、アップストリーム側が提供するバイナリのパッケージを使ってやるよりも、ソースコードからパッケージをビルドすることを好みます。いくつかの場合には、パッケージを配布物に同梱してもらうためにソースコードを使うことが要求されていることもあります。これは、また、汎用 <universal> の wheel を提供する純 Python のパッケージにも当てはまります。ソースコード配布物を用いる理由には次のようなものがあるでしょう:

  • すべてのパッケージのソースコードを監査することができるようにするため。

  • 試験一式を動作させることができるようにし、また、説明文書をビルドすることができるようにするため。

  • プロジェクトのリポジトリからのバックポートされたコミットを含めてパッチの適用が容易にできるようにするため、また、逆にプロジェクトへパッチを送ることができるようにするため。

  • アップストリームのビルドではカバーされていない特定のプラットフォームでのビルドができるようにするため。

  • システムのライブラリの特定のバージョンに対してビルドができるようにするため。

  • すべての Python パッケージを通じて守備一貫したビルドプロセスを保持するため。

通常は、 Git リポジトリからパッケージをビルドすることができますが、代わりに静的なアーカイブファイルを提供する重要ないくつかの理由があります:

  • 単一のファイルをダウンロードする方が、より効率が良く、より信頼できて、例えば Git clone を使うよりも良くサポートされていることがしばしばです。これによって、貧弱なインターネット接続性の元にあるユーザを助けることができます。

  • ダウンストリーム側は、引き続くビルドに用いるためのソースファイルの真正性を検証するために、時を経てもビット単位で同一であることを要求するハッシュ値を使うことがしばしばあります。例えば、仮にサーバ上の gzip がアップグレードされれば、圧縮されたデータが変化するかもしれないので、自動的に作成される Git アーカイブはこのようなことを保証しません。

  • アーカイブファイルはミラーサイトにおくことも可能で、アップストリームとダウンストリームの両方の帯域幅を節約することができます。実際のビルドは、ローカルミラーまたは前もって再配布を受けたソースファイル群にしかアクセスが提供されないファイアウォールの内側もしくはオフラインの環境下で後から実行することが可能です。

  • 明示的にアーカイブファイルを公開することで、そのソースコードアーカイブが作成された時点でバージョン管理システムのメタデータに関する依存関係がすべて解決されていたことを保証することができます。例えば、自動的に生成される Git アーカイブはコミットタグ情報をすべて削除していて、そのビルドに必要なバージョン情報の詳細が不正確になっている可能性があります。

どのように?

理想的には、 ** PyPI上で公開されたソースコード配布物のアーカイブには、そのパッケージの Git リポジトリのファイルを全て含み ** 、それらのファイル群からパッケージ自体をビルドし、テストスイートを走らせ、説明文書をインストールするために必要なファイルや、シェル補完やエディタ用のサポートファイルなどエンドユーザにとって役に立つかもしれない他のファイルを全て含めるべきです。

この点は、パッケージそれ自体に属するファイル群にだけ適用します。Python のパッケージ管理機構に極めてよく似ていますが、ダウンストリームパッケージの処理では、必要な Python の依存関係や、そのパッケージとそのビルドスクリプトが必要とするシステムツールや外部のライブラリの依存関係を提供します。しかしながら、ダウンストリーム側が必要な依存関係を決定し、それらの変更をチェックするために、これらの依存関係を列挙するファイル (例えば requirements*.txt ファイル) もまた同梱されるべきです。

プロジェクトによっては、PyPI からのソースコード配布物を使う Python パッケージ管理機構に関して心配する場合があります。彼らとしては、特定のプロジェクトをソースコードからビルドするという問題含みではっきりと機能しないことがわかっている代替策を有効にすることになるので、これらのツール類によって使われることのないファイル群で彼らのパッケージのサイズが増えることを望まなかったり、ソースコード配布物を公開することを全く望まなかったりするのです。

他方で、(例えば NumPy のような) いくつかのプロジェクトでは、そのインストールパッケージの中にテストスイートを同梱することに決めたものがあります。これによって、そのようなパッケージをインストールした後に、例えば依存先のパッケージをアップグレードした後にリグレッション (退行)がないかどうかの確認を行うために、ユーザがテストスイートを走らせることを許すという利点を追加することができます。さらに別のやり方としては、テストスイートやテストデータを別の Python パッケージに分割する方法があります。そのような方法は、巨大なテストベクトルを cryptography-vectors_package に分離する形で、 cryptography_project で採用されています。

リリースの際のワークフローでソースコード配布物を用いるのは良い考えです。例えば、 ビルド ツールは正にそれをやります -- まずソースコード配布物をビルドし、それを使って wheel をビルドするのです。これによって、ソースコード配布物が実際に動作することを確実にし、誤って公式の wheel よりも数の少ないファイル群をインストールしてしまうことがなくなります。

理想的には、テストスイートを走らせたり説明文書をビルドしたりといったことや、全ての必要なファイルが実際に含まれていることを確実にする特殊なテストを追加するのに、ソースコード配布物も使いましょう。当然のことですが、これはより多くの努力を必要としますので、こうしなくても問題はありません -- ダウンストリームのパッケージ作業者たちが素早く不足しているファイルを報告してくれるでしょう。

ビルドプロセスの最中にインターネットを使うことはやめましょう

なぜ?

ダウンストリームのビルドは、しばしば、インターネットにアクセスすることができないサンドボックス化された環境の中で行われます。パッケージのソースファイルがこの環境内に展開され、必要な全ての依存関係がインストールされます。

仮にこれが当てはまらない場合でも、適切にダウンロードを認証するために十分な注意を払っていたものと仮定して、インターネットを使うことはいくつもの理由から推奨されません:

  • インターネット接続は (例えば受信状態が悪いために) 不安定であるかもしれませんし、プロセスを失敗させたりハングさせたりしかねない一時的な問題の影響を受けるかもしれません。

  • リモートにあるリソース群は、もはやビルドができなくなるような形で、一時的または永続的に利用不可能になるかもしれません。これは、特に、誰かが古いバージョンのパッケージをビルドする必要に迫られた時に問題となります。

  • リモートのリソース群は、ビルドが再現可能にならない形に変化するかもしれません。

  • リモートのサーバにアクセスすることは、当該システムでそのパッケージをビルドしていることに関する情報を暴露するので、プライバシー問題と潜在的なセキュリティ問題をもたらします。

  • ユーザは、制御下にないインターネットアクセスが追加料金やその他の不都合に帰結してしまう、そのようなデータ量に制約のある通信サービスを使っているかもしれません。

どのように?

パッケージが、例えば売り物の依存関係を自動的にダウンロードしたり、Git のサブモジュールをフェッチしたりするような、そのようなインターネットを使用する何らかのカスタムビルド バックエンド 動作を実装しているなら、そのソースコード配布物は、これらのファイル群をすべて同梱するか、別途準備することができるようにするかのいずれかをするべきで、ファイル群がすでに存在する場合にはインターネットを使用しないようにしなければなりません。

この点は、パッケージのメタデータの中で指定された Python の依存関係には当てはまらないということ、また、それらは (ビルドpip のような) フロントエンド によるビルドやインストールのプロセスの最中にフェッチされるということに注意してください。ダウンストリーム側では、Python の依存関係をローカルに準備するようなフロントエンドを使います。

理想的には、カスタムビルド用スクリプトは、明示的に要求された場合を除いて、インターネットへのアクセスを試みることさえ全く行うべきでありません。もし、何らかのリソースが不足していてフェッチする必要があるなら、まずユーザに許可を求めるべきです。それが実現不可能であれば、次善の策は、あらゆるインターネットアクセスをさせないというオプトアウトのスイッチを提供するべきです。これは、例えば NO_NETWORK 環境変数が空でない値に設定されているか否かを調べることで行うことができます。

ダウンストリームは、しばしばテストを走らせたり説明文書をビルドしたりしますので、理想的を言えば、上記のことはこれらのプロセスにも同様に拡大適用されるべきです。

もし、リモートのリソースをフェッチするのであれば、悪意ある第三者がファイルを置換しているという事態から保護するために、 (通常はハッシュ値を使って) 絶対に その真正性を検証 しなければならないことも覚えておいてください。

システムの依存関係に対してビルドすることをサポートする

なぜ?

Python プロジェクトの中には、 C や C++ で書かれたライブラリのような非 Python の依存関係を持つものがあります。アップストリームパッケージング内でこのような依存関係のシステムバージョンを使おうとする試行は、エンドユーザに多数の問題をもたらすかもしれません:

  • 公開された wheel は、使っているライブラリのバイナリ互換のバージョンがユーザのシステム上に存在することを要求します。もし、ライブラリが不足していたり非互換のバージョンがインストールされていたりすると、 Python パッケージは、経験豊かとは言えないユーザにとっては明晰でないエラーを伴って失敗するかもしれませんし、動作時に誤動作することさえあるかもしれません。

  • ソースコード配布物からのビルドには、ソースコードレベルで互換性のあるバージョンの依存関係先が、システムによってはライブラリ本体とは別のパッケージとして用意されていることがある、開発用のヘッダーファイルやその他の補助ファイルと共に、存在していることが要求されます。

  • 経験を積んだユーザにとってさえ、互換性のある依存関係先のバージョンをインストールすることは極めて難しかもしれません。例えば、使っている Linux ディストロが要求されているバージョンを提供していないこともあり得るし、他のパッケージが互換性のないバージョンのものを要求しているかもしれません。

  • Python パッケージとそのシステム依存関係の間の関連性は、パッケージングシステムによって記録されているということはありません。次回のシステム更新がライブラリを、 Python パッケージとのバイナリ互換性を破壊するような、より新しいバージョンへとアップグレードするかもしれず、ユーザが修復のために介入することが要求されるかもしれません。

これらの理由は、依存関係先を静的にリンクするか、インストールされるパッケージの中にローカルコピーを用意するかのいずれかに決める合理的な理由になります。ソースコード配布物の中にも依存関係先を含めることもあるかもしれません。時に、これらの依存関係先もまた PyPI でパッケージされていて、他のすべての Python パッケージのように、プロジェクトの依存関係先として宣言され得ることもあります。

しかしながら、これらの課題のどれひとつを取ってもそれはダウンストリームのパッケージングには当てはまらず、ダウンストリーム側ではシステムの依存関係に直接にリンクする方を好む十分な理由があります。とりわけ次のような場合:

  • 多くのケースでは、部品間で動的な依存関係を信頼できる形で共有することが、ダウンストリーム側のパッケージングエコシステムの 目的 の大きな部分を占めています。それをサポートするのを補助することは、そのようなシステムのユーザが好ましいフォーマットでアップストリームのプロジェクトにアクセスすることをより容易にします。

  • 静的なリンキングと提供は、その出自の検証が難しくなるので、外部への依存関係の使用をわかりにくくします。

  • 動的なリンキングは、ダウンストリームのパッケージングエコシステム全体で使用されるライブラリを素早く体系的に置き換えることができるようにしますが、それは、セキュリティ上の脆弱性や致命的なバグを含んでいることが判明した時には特に重要になり得ます。

  • システムの依存関係を使うことで、ダウンストリーム保守者が様々なパッケージ内で提供される依存関係に統一的にパッチしなければならないということがない形で、特定のプラットフォーム上でユーザ経験を改善し得るところのダウンストリームでのカスタマイゼーションからの利益をパッケージにもたらします。これは、互換性の向上やセキュリティハードニングを含み得ます。

  • 静的なリンキングとベンダーリングによって、同一ライブラリの複数の異なるバージョンが同じプロセスの中でロードされ得ます (例えば、同じライブラリの別バージョンにリンクしたふたつの Python パッケージを import しようと試みた場合) 。ある時には、事件にならずに動作しますが、ライブラリのローディングエラーに起因する問題や、微妙な動作中のバグや、 (突然クラッシュしてデータを失うといった) 壊滅的な失敗へと至ることもあり得ます。

  • 最後ではあるが最も軽微といういうわけではありませんが、静的なリンキングとベンダーリングの結果として重複が起きて、ディスクスペースとメモリの両方を余計に使うことになります。

どのように?

双方のニーズの間の良い妥協点は、ベンダード (訳註:パッケージ側が準備したものの意か) のものを使うかシステムの依存関係を使うかを切り替えるスイッチを提供することです。理想的には、パッケージ側が複数の独自の依存関係を持つならば、それぞれの依存関係について独立したスイッチを提供するべきで、かつ、例えば USE_SYSTEM_DEPS 環境変数のようにデフォルト設定を制御する一般的なスイッチをも持つべきです。

ユーザがシステム側の依存関係を使うことを要求していて、特定の依存関係が存在しないか非互換である場合には、ビルドは、ベンダードのバージョンにフォールバックするよりも説明的なメッセージと共に失敗するべきです。これによって、パッケージ製作者が誤りに気付き、どのように解決するかを意識して解決する機会を得ることができます。

アップストリーム側プロジェクトが、システム側の依存関係を使ってビルドする テスト をダウンストリーム側の再パッケージ作業者に残しておくことは合理的です。これらのガイドラインのゴールは、アップストリーム側プロジェクトとダウンストリーム側再パッケージ作業者の間の協調作業がより効率的になるようにお膳立てすることであって、ダウンストリーム側再パッケージ作業者がよりよく取り扱えるように装備を整えるというタスクをアップストリーム側プロジェクトが分担するようにと示唆するものではありません。

ダウンストリーム側のテストをサポートする

なぜ?

さまざまなダウンストリームプロジェクトが、何らかの形でパッケージ済みの Python プロジェクトのテストを走らせています。これは、それぞれのケースに依って、最低限のスモークテストからテストスイートを隅から隅まで網羅的に行うところまでの幅を持ちます。こうしたことを行うにはさまざまな理由があり得ます:

  • ダウンストリームのパッケージングがどんなバグも持ち込まないようにするために検証すること。

  • アップストリームのテストではカバーされていない追加的なプラットフォームでのテストを行うこと。

  • 特定のハードウェアやシステムパッケージのバージョンといったものだけで再現し得る些細なバグを探索すること。

  • アップストリーム側でのリリース時のテストで使われたものに比べて、より新しい (またはより古い) 依存先バージョンに対してリリース済パッケージをテストすること。

  • 本番構成に非常によく似た環境でパッケージをテストすること。これによって、パッケージ自身の依存関係先ではないパッケージを含めて、異なるインストール済パッケージとの間の自明でない相互作用によって引き起こされる問題点を検出することができます。

  • リリースされたパッケージを、 (ポイントリリースを含めて) より新しい Python のバージョンや、よりテストされていない PyPy のような Python 実装に対してテストすること。

確かに、ダウンストリーム側でテストを行うと、偽陽性や、アップストリーム側プロジェクトがサポートする上で興味を持たないようなシナリオについてのバグ報告を生み出すかもしれません。しかしながら、おそらく、もっとよくあるのは、問題に関する早期の気付きを得たり、発見できなければアップストリーム側プロジェクトのユーザにとっての問題を引き起こしたであろう非自明のバグを発見したりということでしょう。過誤は起きるものですが、ダウンストリーム側パッケージ作業者の大半は、結果をダブルチェックすることに最善の努力を行っていますし、自分たちが報告したバグをアップストリーム側の保守者が優先順位を付けて修正することを助けます。

どのように?

ダウンストリーム側の再パッケージ作業者がそのパッケージを効率よく効果的にテストするのを助けるために、アップストリーム側プロジェクトができることは、すでに上述した示唆のいくつかを含めて沢山あります。これらは、典型的には、テストスイートが誰にとってもより信頼できて簡単に使えるようにするような改善です。いくつかの特定の示唆は:

  • テストファイルと必要品はソースコード配布物の中に含めておくか、簡単に個別にダウンロードできるようにしておきましょう。

  • テストを実行している間は、パッケージのディレクトリに書き込んではいけません。ダウンストリーム側のテスト構成は、インストールパッケージのトップディレクトリで実行される場合があり、テスト実行中の修正や一時的なテストファイルがインストールパッケージの一部となってしまうかもしれません!

  • テストスイートがオフラインで動作するように作ってください。 responsesvcrpy のようなパッケージを使って、ネットワークとの相互作用を疑似的に行ってください。もし可能であれば、たとえば pytest マーカを経由するなどして、インターネットアクセスを伴うテストを簡単に無効にできるようにしてください。テストがオフラインで動作可能であることを検証するには、 pytest-socket を使ってください。このようにすることで、テストワークフローがより素早く、かつ、より信頼できる形で実行できるようになります。

  • テストが特別な設定なしで動作するようにするか、または、必要な設定をテストの必要物の一部として行うようにしましょう。データベースのようなシステム側のサービスに接続することができるとは絶対に仮定しないでください -- とんでもない場合には、供用中のサービスをクラッシュさせるかもしれませんよ!

  • パッケージがオプションの依存関係を持つなら、その部分のテストもまたオプションにしましょう。必要なパッケージがインストールされていなければ、そのようなテストをスキップするか、簡単に選択外にすることができるようなマーカを追加しましょう。

  • もっと一般的に、特別な要求事項を伴うテストにはマーカを付けましょう。これには、例えば、相当な記憶スペースを使用する、相当なメモリを使用する、長時間を要する、並行でテストを走らせることができない、などが含まれます。

  • テストスイートが -Werror 付きで実行されるであろうと仮定してはなりません。それは、例えばより新しい依存関係のバージョンなどのせいで偽陽性を引き起こすので、往々にしてダウンストリーム側では無効にする必要があります。 pytest.raises() を使うよりも pytest.warns() を使って警告をアサートしてください!

  • テストスイートが信頼できて再現可能なものになることを目指しましょう。当てにならないテストを避けましょう。浮動小数点計算や操作のタイミングの結果をそのまま信頼することなど、特別なプラットフォームの細部に依存するものを避けましょう。ファジングには利点もありますが、完全性を期すための静的なテストも持っておきたいでしょう。

  • その目的に従ってテストを分割し、重要でないカテゴリや問題含みのカテゴリを簡単にスキップできるようにしましょう。ダウンストリーム側でのテストの一義的な目的は、そのパッケージ自体が動作することを保証することであって、一般的に、ダウンストリーム側ではコードカバー率・コードフォーマット・型チェックやベンチマークするというようなタスクには興味がありません。パッケージ自体に実際に影響を与えることはなくとも、依存関係先がアップグレードされたりシステムが高負荷下にあったりするとこれらのテストが失敗する可能性があります。

  • テストスイートの実行に非常に長い時間がかかるなら、並行テストをサポートしましょう。ダウンストリーム側は、しばしば、多数のパッケージを維持管理していて、それらを全てテストするには長い時間がかかります。ボトルネックを避けるには、 pytest-xdist を使うことが助けとなるでしょう。

  • 理想としては、テストスイートを pytest``を通じて走らせることをサポートしてください。 pytest_ は、テストを便利に非選択にしたり、当てにならないテストを (pytest-rerunfailures_を通じて) 再実行したり、テストがハングアップしてしまうのを防ぐためのタイムアウトを (pytest-timeout_ を通じて) 追加したり、 (pytest-xdist_ を通じて) テストを並行して走らせたり、といったダウンストリーム側に真に役立つ多くのコマンドライン引数を持っています。テストスイートが ``pytest と一緒に 書かれている ことや pytest と一緒に 実行される 必要はないことを覚えておいてください: pytest は、標準ライブラリの unittest テスト探索と互換性のあるほぼ全てのテストケースを探索して実行することができます。

安定版リリースの目的

なぜ?

多くのダウンストリームは、メインのパッケージストリームに加えて、ステーブルリリースチャンネルを提供しています。このようなチャンネルのゴールは、より高い安定性を必要とするユーザ向けに、より保守的なアップグレードを提供することです。このようなユーザは、しばしば、最新の機能を得ることよりも、問題発生のリスクがより低いことを選択することを好みます。

正確にはポリシーはそれぞれに異なりますが、新しいバージョンのパッケージをステーブルリリースチャンネルに取り込む際の重要な評価基準は、すでに幾らかの時間をかけてテストが行われているものを利用可能にする、既知の大きな手戻りがない、ということです。例えば、 Gentoo Linux では、あるパッケージがステーブルであると印をつけられるのは一ヶ月間のテストが行われた後であり、その時点で依存関係先のパッケージ群がステーブルであるバージョンを使ってテストされていることです。

しかしながら、もっと素早い行動が要求される状況もあります。例えば、ステーブルチャンネルで現に利用可能になっているバージョンにセキュリティ上の脆弱性や大きなバグが発見された場合、ダウンストリーム側はそれを解決する必要に直面します。このような場合には、以下のようなさまざまな選択肢を考慮の対象とする必要があります:

  • 新しいバージョンをステーブルチャンネルに早期に送り、

  • その時点で公開されているバージョンにパッチを追加し、

  • あるいは、ステーブルチャンネルを以前のリリースへとダウングレードさえも行う。

これらのオプションは、それぞれ、それなりのリスクとそれなりの作業量を伴うものであり、パッケージ作業者はアクションの方向性を決定するために重み付けを行う必要があります。

どのように?

ステーブルリリースチャンネル向けのワークフローを調整するためにアップストリーム側ができることがいくつかあります。これらのアクションは、しばしば、パッケージのユーザにも恩恵を与えます。いくつかの具体的な示唆が続きます:

  • リリースの頻度をコード変更の割合に適合させましょう。稀にしかリリースされないパッケージは、しばしば、毎回のリリースに巨大な変更を持ち込み、偶発的な手戻りのリスクを高めます。

  • 可能であれば、バグ修正と新機能を混ぜないようにしましょう。とりわけ、既知のバグ修正がすでにマージされているなら、機能ブランチをマージする前に新しいリリースを行うことを検討しましょう。

  • 大きな変更の後には、ユーザやダウンストリーム側が自発的に参加するような試験の機会をより多く提供するために、プレリリースを作ることを検討しましょう。

  • プロジェクトが集中した開発を必要とするのであれば、より保守的なコミットだけを含むブランチを分岐させて、個別にリリースを行うことを検討しましょう。例えば、現状では、 Django は main ブランチに加えて3個のリリースブランチを維持しています。

  • 追加のブランチを恒常的に維持していくことを望まない場合であってさえ、特にセキュリティ上の脆弱性が発見された時には、以前のバージョンに最低限の変更を加えたパッチリリースを追加することを検討しましょう。

  • 必要となればそれ以前のリリース用にチェリーピッキングした変更を取り込みやすくなるように、変更は、ある時点でひとつの問題に対処することに焦点を当てたコミットに分割しましょう。