Kami mulai dengan satu pengembang, dan satu repo svn yang berisi semua kode kami:
^/foo/trunk/module-a
^/foo/trunk/module-b
^/foo/trunk/module-b/submodule-b1
^/foo/trunk/website1
(pada saat itu ini merupakan peningkatan besar). Setelah ini mendapat kesempatan untuk tumbuh sedikit, kami mulai mengalami masalah dengan dependensi melingkar, testuites lambat, dan kesulitan umum menggunakan kembali kode (karena misalnya set fitur situs web1 telah merangkak ke dalam modul generik-a).
Ingin memodulasi basis kode, dan berharap kita segera pindah ke git (dan setelah membaca di suatu tempat bahwa git tidak suka svn mega-repos), kami telah beralih ke struktur yang jauh lebih terperinci:
^/module-a/trunk/
^/module-b/trunk/
^/module-b/trunk/sumbmodule-b1
^/earlier-sub-sub-sub-module-c/trunk
etc. (about 120 such modules)
Secara konsep ini hebat. Lebih banyak kode modular, test suite lebih cepat, lebih mudah untuk didokumentasikan, dll. Kami membuka beberapa komponen generik kami, dan membuat semua modul dapat diinstal (gunakan pip install -e .
untuk menginstalnya di development
virtualenv).
Kami membuat ^/srv/trunk
repositori yang berisi struktur folder dari lingkungan runtime, yaitu. ^/srv/trunk/lib
untuk modul, /srv/trunk/src
untuk sisa-sisa ^/foo/trunk
, ^/srv/trunk/www
untuk website dll
Dan akhirnya (mengambil ide dari perforce, yang sudah lama saya kerjakan [ https://www.perforce.com/perforce/r12.1/manuals/cmdref/client.html] ) kami membuat "vcs- ambil "file teks yang mencantumkan semua repo yang relevan dan di mana mereka harus diperiksa ke lingkungan dev, dan perintah yang sesuai untuk melakukannya. Misalnya garis vcs-fetc:
svn srv/lib/module-a ^/module-a/trunk
akan menyebabkan salah satu (pertama kali)
cd /srv/lib && svn co ^/module-a/trunk module-a
atau (sesudahnya)
cd /srv/lib/module-a && svn up
dan juga untuk repositori github (baik paket vendor kami sendiri maupun yang diubah / tidak diubah).
Kami telah menggunakan proses vcs-fetch yang sama untuk menciptakan lingkungan produksi, tetapi kami dengan cepat mengetahui bahwa kami tidak memiliki cara untuk mengetahui versi mana yang digunakan untuk berjalan dalam prod setelah melakukan vcs-fetch.
Dengan mega-repo, kita bisa mencatat nomor revisi sebelum memperbarui prod dari trunk, dan kembali adalah sangat mudah svn -r nnn up .
. Dengan kode di svn dan git (dan satu modul dalam hg) - dan ~ 120 repo, tidak jelas bagaimana melakukan ini ..
Saya membaca http://12factor.net/ hari ini, dan faktor pertama adalah "Satu basis kode" jadi saya juga bertanya-tanya apakah saya jauh dari jalan yang benar di sini?
Satu ide yang saya miliki adalah membuat skrip deploy yang akan membuat pip-installable "deployment" -wheels dan "bundle" bersama-sama dalam sebuah requirements.txt
file. Penempatan kemudian akan melibatkan pembuatan virtualenv baru, pip-instal file requirement.txt daftar roda penyebaran, dan beralih virtualenv aktif. Mengembalikan ke sebelumnya hanya akan melibatkan pengalihan virtualenv kembali (tetapi kecuali kami ingin menyimpan virtualenv selamanya, itu tidak akan memungkinkan kami untuk kembali ke titik waktu - dalam pengalaman saya yang belum pernah dibutuhkan sekalipun).
Pada titik ini saya bertanya-tanya apakah saya berjalan ke arah yang salah, atau apakah saya belum berjalan cukup jauh di jalan yang benar ..? (semua yang saya baca terus berbicara tentang "aplikasi Anda", dan saya tidak tahu bagaimana itu berarti menjalankan 14 situs web dari basis kode yang sama ...)
sumber
Jawaban:
Sepertinya Anda kehilangan cabang (atau lebih tepatnya cabang 'tag' atau 'rilis').
Alih-alih menggunakan revnum SVN Anda sebagai referensi untuk menentukan versi mana yang Anda instal, Anda harus membuat cabang pada revisi yang dirilis. Anda kemudian menggunakan nama cabang itu.
Itu membuatnya lebih mudah untuk bercabang bahkan jika tidak ada perubahan sehingga setiap modul menyimpan nomor rilis yang sama, namun paket OSS Anda mungkin tidak suka bercabang tanpa perubahan, jadi hal terbaik berikutnya adalah menyimpan skrip dependensi - jadi versi 5 produk Anda memerlukan modul OSS X v2 dan sebagainya.
Anda akan mengubah skrip Anda untuk berhenti merujuk ke versi dan alih-alih bekerja dengan nama cabang (meskipun mereka bisa apa saja, yang terbaik untuk memutuskan konvensi penamaan tetap, misalnya Release_1_2_3)
Petunjuk lain adalah menjaga file dengan masing-masing modul yang menggambarkan versi saat ini, Anda dapat membuat-otomatis ini jika perlu, dan mungkin menyertakan changelog penuh juga, tetapi itu berarti siapa pun dapat melihat versi apa yang digunakan hanya dengan melihat.
sumber
Saya pikir Anda sudah memiliki banyak ide bagus, saya telah menggunakan sebagian besar dari mereka di berbagai proyek selama bertahun-tahun, dan perhatian utama Anda tampaknya adalah ketidakmampuan untuk mengetahui versi apa dari semua modul di mana termasuk dalam paket yang diberikan jika Anda membagi mereka.
Saya siap untuk memisahkan mereka, pada tingkat granularitas tertentu, terutama jika Anda memiliki banyak tim dan siklus rilis yang berbeda, seperti yang disebutkan oleh @ Ext3h.
Karena saya tidak yakin seberapa terisolasi modul Anda, atau seberapa rinci Anda ingin versi Anda menjadi, saya akan menyarankan beberapa opsi.
Gunakan git submodules. Dengan submodules, Anda dapat menyimpan setiap modul dalam git repo yang terpisah, mirip dengan pengaturan svn Anda, dan juga dengan apa yang Anda pikirkan. Anda kemudian menautkan modul-modul itu ke proyek root yang akan berisi referensi ke komit yang relevan dari setiap submodule, untuk masing-masing komitnya sendiri.
IMO ini adalah pengaturan yang bagus secara teoritis, dan cukup sederhana. Kelemahan utama adalah bahwa alur kerja untuk submodul sedikit canggung, namun Anda tampaknya telah menyelesaikan hal-hal seperti itu dengan baik dengan skrip sebelumnya, jadi itu mungkin bukan masalah nyata.
Peringatan lainnya adalah bahwa referensi commit submodule hanya akan menjadi SHA1, tidak pernah ada detail yang dapat dibaca manusia tentang cabang apa Anda, dan Anda mungkin harus secara manual checkout cabang yang tepat ketika Anda ingin melakukan pekerjaan secara langsung dalam submodule.
Namun, saya belum pernah menggunakan pola ini secara luas, jadi saya tidak tahu berapa banyak masalah yang mungkin terjadi untuk proyek besar seperti milik Anda.
Alternatif lain adalah menggunakan semacam manajer ketergantungan. Ini mensyaratkan bahwa setiap modul atau set modul dapat diversi, dikemas, dan diterbitkan secara terpisah, dan bahwa Anda memiliki sistem yang dapat menggabungkan paket-paket itu dengan cara yang Anda inginkan ketika Anda menginginkannya.
Anda sudah menyarankan pip, dan apa yang tampaknya hilang dari saran Anda adalah menyimpan persyaratan yang dihasilkan.txt bersama dengan build, atau dalam repo proyek root, sehingga Anda dapat membuat kembali virtualenv nanti daripada harus menyimpan itu pada disk.
Ada sistem lain juga; Saya membuat proyek yang agak besar menggunakan versi yang sedikit disesuaikan dari Apache Ivy sebagai alat untuk paket dan menerbitkan setiap modul, serta menarik mereka bersama-sama untuk proyek akhir. Ivy juga menyimpan manifes yang mencantumkan semua versi dari semua modul yang Anda rujuk, jika Anda perlu membuat ulang pengaturan nanti.
sumber