私たちは1人の開発者と、すべてのコードを含む1つのsvnリポジトリから始めました。
^/foo/trunk/module-a
^/foo/trunk/module-b
^/foo/trunk/module-b/submodule-b1
^/foo/trunk/website1
(当時、これは大きな改善でした)。これが少し成長する機会を得た後、循環依存、テストスイートの遅延、コードの再利用に関する一般的な問題が発生し始めました(たとえば、website1の機能セットが他の汎用モジュールaに侵入したため)。
コードベースをモジュール化して、まもなくgitに移動することを期待して(そしてgitがsvn mega-reposを好きではないところを読んだことを期待して)、もっと細かい構造に移行しました:
^/module-a/trunk/
^/module-b/trunk/
^/module-b/trunk/sumbmodule-b1
^/earlier-sub-sub-sub-module-c/trunk
etc. (about 120 such modules)
これは概念的に素晴らしかった。モジュール化されたコードの増加、テストスイートの高速化、ドキュメント化の容易化など。より一般的なコンポーネントの一部をオープンソース化し、すべてのモジュールをpipインストールpip install -e .
可能にしました(development
virtualenv にインストールするために使用)。
^/srv/trunk
ランタイム環境のフォルダ構造を含むリポジトリを作成しました。^/srv/trunk/lib
モジュール、/srv/trunk/src
残りの部分^/foo/trunk
、^/srv/trunk/www
ウェブサイトなど
そして最後に(非常に長い時間前に使用したperforceからのアイデア([ https://www.perforce.com/perforce/r12.1/manuals/cmdref/client.html]))を作成し、「vcs-関連するすべてのリポジトリと、それらを開発環境にチェックアウトする場所と、それに対応するコマンドをリストしたテキストファイル。たとえば、vcs-fetc行:
svn srv/lib/module-a ^/module-a/trunk
いずれかを引き起こします(初回)
cd /srv/lib && svn co ^/module-a/trunk module-a
または(後で)
cd /srv/lib/module-a && svn up
そして同様にgithub repos(私たち自身と変更された/変更されていないベンダーパッケージの両方)についても同様です。
本番環境の作成には同じvcs-fetchプロセスを使用しましたが、vcs-fetchを実行した後、prodで実行されていたバージョンを知る方法がないことはすぐにわかります。
mega-repoを使用すると、トランクから製品を更新する前にリビジョン番号をメモするだけで済み、戻るのは簡単でしたsvn -r nnn up .
。svnとgitの両方のコード(およびhgの1つのモジュール)と〜120リポジトリでは、これを行う方法は明らかではありません。
私は今日http://12factor.net/を読みました、そして最初の要素は「One codebase」なので、私はここで正しい道を離れているのかどうかも疑問に思っていますか?
私が持っていた1つのアイデアは、pipでインストール可能な「展開」ホイールを作成し、それらをrequirements.txt
ファイルに「バンドル」する展開スクリプトを作成することでした。デプロイでは、新しいvirtualenvを作成し、デプロイホイールをリストしたrequirements.txtファイルをpipインストールして、アクティブなvirtualenvを切り替えます。以前の状態に戻すには、virtualenvを元に戻すだけです(ただし、virtualenvを永久に保持したいと思わない限り、特定の時点に戻ることはできません-私の経験では必要ありませんでした)。
この時点で、間違った方向に歩いているのか、それとも正しい道を十分に歩いていなかったのかと思います。(私が読んでいるすべてのものが「あなたのアプリ」について話し続けており、それがどのように同じコードベースから14のWebサイトを実行することになるのかわかりません...)