Memilih strategi percabangan yang tepat untuk rilis


11

Dimulai dengan tim pengembang baru pada proyek baru dan kita harus mendefinisikan strategi percabangan untuk repositori sumber kami ( mis. Microsoft Team Foundation Server 2010 ). Kami telah mengalami diskusi lengket tentang apakah ...

A . Memiliki satu cabang Rilis dari mana kami melakukan produksi membangun dan kemudian Label ketika ada sesuatu yang sebenarnya dirilis

ATAU

B . Miliki cabang Rilis baru untuk setiap Rilis baru ke dalam produksi ( Mis. Versi 1, 2, 3, dll ... )

Opsi A tampaknya cukup mudah tetapi kami tidak yakin apakah ini akan menyebabkan masalah dalam jangka panjang. Opsi B sepertinya hanya menciptakan banyak cabang sekali seumur hidup yang hanya menumpuk dari waktu ke waktu.

Adakah yang punya pengalaman yang bisa membantu kita memutuskan? Secara khusus, saya mencari untuk mendengar di mana titik-nyeri untuk satu pilihan. Jangan ragu untuk memberikan pengalaman spesifik relatif terhadap TFS dan / atau implikasi Manajemen Rilis.

Jawaban:


15

Opsi A. Hanya menggunakan jalur utama dan penandaan untuk rilis

Pro:

  • Anda menghindari menggabungkan neraka.
  • Tetap mengikuti arus utama mendorong beberapa praktik terbaik seperti perencanaan rilis yang tepat, tidak memperkenalkan banyak WIP, menggunakan percabangan dengan abstraksi untuk menangani pekerjaan jangka panjang yang out-of-band, dan menggunakan sistem tertutup terbuka dan fitur yang dapat dikonfigurasi untuk menangani pekerjaan pengelolaan dalam proses yang mungkin; atau mungkin tidak; perlu dinonaktifkan sekarang atau di masa depan untuk melepaskan atau untuk menghindari rollback penuh.

Cons:

  • Berurusan dengan pekerjaan yang sedang berlangsung menjadi masalah dan menambah area serangan permukaan potensial ketika tiba saatnya untuk melepaskan. Namun, jika pengembang Anda disiplin maka fitur-fitur baru harus dapat dikonfigurasi dan modular dan karenanya mudah dinonaktifkan / diaktifkan, atau tidak ada WIP dan pada setiap titik rilis semua pekerjaan sudah selesai atau belum dimulai (mis. Scrum).
  • Perubahan skala besar / out-of-band membutuhkan lebih banyak pemikiran sebelumnya untuk diimplementasikan (misalnya percabangan dengan abstraksi).

Secara pribadi saya lebih suka pendekatan ini. Cakupan kode dan tes unit harus mengidentifikasi kode yang tidak siap digunakan dan orang-orang tidak boleh mengerjakan kode yang tidak akan dirilis selama iterasi saat ini. Bercabang dengan abstraksi atau mekanisme lain dapat digunakan untuk menghadapi perubahan jangka panjang dan pekerjaan yang sedang berlangsung.

Ketika Anda tidak melakukan ini, Anda mulai menemukan diri Anda berurusan dengan masalah penggabungan, kode basi, fitur yang tidak pernah dirilis, dll.

Opsi B. Cabang dengan rilis

Pro:

  • Anda dapat mulai mengerjakan iterasi berikutnya sementara iterasi saat ini menyelesaikan putaran pengujian penerimaan.
  • Saya yakin hal-hal lain.

Cons:

  • Banyak cabang.
  • Masih perlu memberi tag pada cabang di titik rilis.
  • Masih perlu berurusan dengan WIP dan menggabungkan WIP dari cabang rilis sebelumnya ke cabang rilis berikutnya jika itu tidak akan berhasil dan masih perlu menonaktifkan atau mencabut cabang rilis dan menjalankan kembali tes penerimaan
  • Perbaikan terbaru perlu diterapkan ke lebih banyak cabang (cabang rilis + perbaikan terbaru + tag baru + menggabungkan perbaikan terbaru ke cabang vnext dan mungkin vnextnext tergantung di mana perbaikan terbaru jatuh.)

Saya bukan penggemar berat dari solusi ini ^ _ ^.

Secara umum saya akan merekomendasikan hanya mencoba tetap berpegang pada garis utama. Jika pengembang Anda mengalami masalah dengan tidak menulis WIP yang dapat dengan mudah ditarik ketika gagal memotong atau yang diperiksa lebih awal untuk rilis berikutnya maka Anda dapat mulai berbicara tentang penandaan kode pada titik di mana kode harus lengkap dan bercabang dari sana jika perlu untuk mengatasi cacat dan bug yang diabaikan yang gagal ditangkap oleh unit pengembang Anda.

Idealnya saya pikir Anda ingin itu menjadi proses pengecualian, bukan aturannya.

Opsi C. Opsi Bonus Gila

Jika Anda ingin menjadi mewah, Anda juga dapat mempertimbangkan model percabangan per-pengguna-cerita / per-fitur. ( Gagasan mengerikan di TFS atau non DVCS sementara pada saat yang sama sangat sepele untuk diterapkan jika menggunakan DVCS seperti git atau lincah ).

Di masa lalu saya menerapkan di bawah ini untuk tim pemeliharaan majikan sebelumnya yang bekerja dengan basis kode warisan yang tidak dapat dengan mudah dipindahkan ke lincah dari svn. Banyak pekerjaan yang tidak perlu dilibatkan untuk memenuhi persyaratan bisnis dari jalur utama yang selalu dapat dirilis daripada hanya mengoordinasikan rilis yang lebih baik tetapi. . .

  1. Fitur dikembangkan oleh dev di cabang dev tim mereka.
  2. Ketika sebuah fitur siap ditinjau oleh rekan, bundel devs bersama menjadi satu gabungan dari cabang Dev ke cabang CR dan sertakan id fitur / kisah pengguna dalam judul. * Diperkuat dengan kait pra-komitmen *
  3. Setelah melewati CR alat admin digunakan untuk Mempromosikan fitur ke cabang QA. (Saya menulis aplikasi terminal kecil yang mencantumkan cerita pengguna yang hadir dalam berbagai tahap penerimaan dan memungkinkan operator untuk mempromosikan atau menurunkannya di antara tahap-tahap penerimaan tersebut)
  4. QA menjalankan tes otomatisasi dan kegunaan manual. Jika fitur ini bagus, didorong ke cabang rilis (garis utama). Jika fitur tersebut ditolak, maka akan didemosiasikan / dikembalikan keluar dari cabang QA hingga devs dapat mengatasi masalah yang muncul selama pengujian dan menambahkan mengirimkan tambalan ke cabang CR.
  5. Jika kode dikembalikan dari cabang QA dan perbaikan diterapkan, alat terminal akan menerapkan kembali perubahan yang diperlukan untuk membawa fitur kembali ke cabang QA dari cabang CR sehingga QA dapat meninjau kembali kode dan mempromosikannya atau turunkan lagi.
  6. Kapan saja cabang rilis harus dalam keadaan stabil yang dapat dirilis.
  7. Setelah rilis Dev, QA, dan CR baru berputar dari jalur utama.

@Keith_Brings Ini ringkasan yang bagus, terima kasih. Seperti yang sudah Anda tunjukkan, Opsi C sebenarnya bukan opsi karena saya menggunakan TFS, tetapi yang menarik.
JoeGeeky

Saya tidak melihat cara kerja opsi A. Di perusahaan saya, kami memiliki rilis yang berbeda untuk pelanggan yang berbeda. Jika kami masih melakukan pengembangan fitur / perbaikan terbaru pada versi 1.0, dan juga aktif bekerja pada versi 2.0, dan mungkin bahkan 3.0 juga, kami tidak dapat melakukan semua ini di satu cabang. Mungkin Anda memiliki kemewahan menikmati Opsi A karena model rilis Anda. Tapi itu bukan model rilis semua orang, dan bagi kita yang terjebak dengan fitur creep atau beberapa rilis paralel, kita harus menggunakan Opsi B.
void.pointer

6

Kami memiliki cabang terpisah untuk setiap rilis yang kami keluarkan (kira-kira 4 tahun). Sangat nyaman ketika Anda perlu menarik rilis tertentu.

Jika Anda perlu mempertahankan beberapa rilis yang lebih lama, saya tidak berpikir bahwa pelabelan akan berhasil. Dengan cabang rilis tertentu, Anda dapat menerapkan hot-fix untuk masing-masing cabang secara terpisah (atau pilihannya) tanpa khawatir tentang rilis lainnya.

Itu juga membuat membandingkan rilis yang jauh lebih mudah ketika Anda mencari ketika bug atau fitur diperkenalkan.

Jangan khawatir tentang jumlah cabang atau waktu mereka pergi tanpa perubahan. Sistem versi Anda memberi Anda kendali dan memberikan sejarah perkembangan proyek Anda. Sejarah memiliki kecenderungan untuk tidak berubah ... Dan jangan khawatir cv Anda tidak bisa mengatasinya. Kami menggunakan Perforce, 9000+ file di cabang pengembangan, hingga 50 cabang pengembangan untuk rilis yang sedang kami kerjakan dan seperti yang sudah dikatakan, satu cabang per rilis yang kami terbitkan. Perforce bahkan tidak bernafas lebih keras.

Singkatnya: menjadikan hidup Anda sebagai pengembang / pemelihara / pemecah masalah / pemburu masalah lebih mudah dan jangan khawatir tentang jumlah cabang atau jumlah file. Setiap cv yang menghargai diri sendiri akan mengatasinya.

Edit:

Kami sama sekali tidak mengalami kebingungan sehubungan dengan jumlah cabang yang kami miliki. Skema penamaan kami untuk cabang rilis dan kebijakan 1 masalah 1 cabang kami untuk pengembangan (atau pekerjaan) cabang mungkin ada hubungannya dengan itu.

Cabang rilis diberi nama untuk rilis yang mereka pegang, yaitu: R2011SP1 untuk Paket Layanan Rilis 2011 1. Cabang kerja kami memiliki nama yang kurang cerdas: sub01, sub02, sub03 dll. "Sub" berasal dari kenyataan bahwa semua cabang kerja adalah sub cabang dari cabang penerimaan. Cabang penerimaan menjadi cabang di mana semua masalah dikumpulkan yang siap dirilis.

Kebijakan cabang kerja 1 edisi 1 kami, dikombinasikan dengan fakta bahwa sistem pelacakan masalah kami telah disesuaikan dengan bidang "cabang" memastikan bahwa kami selalu tahu masalah apa yang dikembangkan di cabang mana. Ketika masalah diintegrasikan ke dalam cabang penerimaan bidang ini diperbarui. Ini berarti kami selalu tahu masalah mana yang siap untuk dirilis (setelah pengujian penerimaan selesai). Demikian pula kami memperbarui bidang ini ketika cabang rilis dibuat dan dengan cara ini kami selalu dapat melacak di mana rilis masalah dirilis.


1
Saya percaya Anda dapat bercabang dari label di TFS. Jadi, Anda harus menyetujui perbaikan terbaru pada versi produk saat ini selama Anda tidak melupakan labelnya.
Keith Membawa

@ KeithBrings Thats benar, saya baru saja mengujinya dan Anda memang bisa bercabang dari label.
JoeGeeky

@ MarsjanVenema Saya tidak begitu khawatir tentang beban pada sistem karena kebingungan sejumlah besar cabang dapat menyebabkan. Saya juga sedikit khawatir bahwa perubahan yang dilakukan di tumpukan cabang rilis tidak akan digabung ke cabang rilis lain yang seharusnya mendapatkannya, apalagi jalur utama. Sudahkah Anda mengalami masalah seperti ini?
JoeGeeky

@ JoeGeeky: tidak, tidak ada kebingungan sama sekali. Lihat pembaruan untuk jawaban saya.
Marjan Venema

2

Ini semua tentang konteks: seberapa sering Anda melepaskan dan apa yang ada dalam rilis.

Inilah sedikit studi kasus yang saya miliki dengan pekerjaan lama saya, menggunakan metode B (kami menyebutnya cabang dengan sengaja ).

Untuk menempatkan cerita dalam konteks,

  • Rilis terdiri dari fitur-fitur baru dalam perangkat lunak kami: mode permainan baru, fungsi baru, opsi konfigurasi baru.
  • Siklus rilisnya cukup lama: klien kami adalah universitas yang akan bertahan dengan satu set fitur biasanya satu tahun.

Pengembangan utama dibuat ke dalam bagasi sampai kami mencapai fitur lengkap untuk rilis tertentu. Pada saat itu, kami akan membuat cabang, katakanlah projectname-january2012 dan lakukan pengujian kualitas dan perbaikan bug kami di cabang itu. Setelah kami siap untuk rilis publik, kami akan menandai kode di cabang itu, dan rilis.

Namun, pengembangan pada rilis tidak berakhir pada tag itu. Tidak dapat dihindari, kami memiliki klien yang menemukan bug atau masalah kecil dengan rilis tersebut. Jadi dalam hal itu, yang perlu kita lakukan adalah kembali ke cabang itu, menambal kode dan membuat versi baru dari cabang january2012 yang akan dirilis, dan menggabungkan perbaikan kembali ke bagasi.

Dalam kasus kami, pendekatan ini menguntungkan karena beberapa pengguna lebih suka tinggal dengan rilis yang lebih tua dengan serangkaian fitur yang terbatas, atau hanya karena biaya penggelaran di infrastruktur mereka versi yang sama sekali baru daripada perbaikan terbaru yang menyebabkan beberapa masalah.

Jadi pertanyaan yang harus Anda tanyakan pada diri sendiri adalah:

  • Seberapa sering saya melepaskan?
  • Apakah rilis saya akan kompatibel 100% ke belakang?
  • Apakah klien saya setuju dengan peningkatan total untuk memperbaiki bug?

Jika Anda sering merilis, maka mungkin tidak layak untuk memiliki cabang untuk masing-masing. Namun, jika siklus rilis Anda cukup panjang seperti kasus penggunaan lama saya, dan bahwa penerapan, kompatibilitas mundur, dan klien yang bergantung pada rilis lama mungkin berisiko, opsi B tentu akan menghemat banyak rasa sakit, akan membuat segalanya lebih mudah untuk didukung klien Anda dengan biaya minimal berurusan dengan kekacauan cabang.


Saya suka bagaimana Anda menyebut opsi itu. Dalam hal ini, kami adalah pelanggan kami sendiri ( dengan cara berbicara ) sehingga penyebaran sebagian besar akan tetap berada dalam kendali kami. Kami juga toko Scrum dan berharap memiliki siklus rilis yang cukup sering ( mis. Setiap 2-4 minggu ). Meskipun kami berharap dapat mendukung peningkatan versi bergulir, kompatibilitas ke belakang hanya akan menjadi masalah selama diperlukan untuk meluncurkan peningkatan, jadi ... mungkin menit. Dari suara itu; dalam pengalaman Anda; opsi B mungkin bukan pilihan terbaik bagi saya. Terima kasih atas informasinya, sangat menarik.
JoeGeeky

Ah ya, dalam hal ini opsi B terdengar seperti kekacauan dengan sedikit pengembalian. Saya hanya ingin menyoroti bahwa kedua opsi tersebut layak dan masing-masing memiliki kelebihan. Saya lupa menyebutkan secara eksplisit: bagaimana Anda menangani perbaikan bug? Apakah mereka secara eksklusif dimasukkan ke dalam rilis baru atau di patch / rilis lama yang ditambal?
Bushibytes

1

Saya lebih suka opsi A. Kembangkan pada rilis trunk dan cabang saat stabil. Ini secara signifikan membatasi pekerjaan dalam mengintegrasikan hot fix yang diterapkan pada rilis produksi.

Saya telah dikontrak untuk membantu tim yang mencoba opsi B kembali ke jalurnya.

Beberapa hal yang perlu dipertimbangkan.

  • Migrasikan hotfix ke depan melalui semua cabang kode aktif. Ini dapat dilakukan dengan menggabungkan, menambal, dan / atau pembangunan kembali. Ini harus dikelola sepenuhnya untuk memastikan perbaikan diterapkan ke semua rilis yang sesuai, kemudian ke trunk.
  • Pertimbangkan cabang fitur untuk mengaktifkan pengembangan fitur secara terpisah dari aliran kode utama. Ini disarankan untuk perubahan eksperimental. Jangan ragu untuk meninggalkan cabang fitur jika fitur tidak berhasil.
  • Tandai dan lacak poin gabungan Anda.
  • Cabang rilis Anda saat diminta. Saya menemukan ini biasanya ketika rilis siap untuk membangun kandidat rilis. Dalam beberapa kasus, memperkenalkan perubahan yang tidak kompatibel ke bagasi dapat memaksa dan melakukan percabangan awal. Pertimbangkan cabang fitur.

0

Saya telah bekerja selama beberapa tahun pada sistem yang menggunakan sesuatu di antara dua skema yang Anda jelaskan. Kuncinya adalah bahwa ada skema penomoran multi-level yang digunakan. Level luar pada dasarnya adalah versi API, dan itu dikelola pada cabang (dengan gabungan lintas yang tepat ketika ada sesuatu yang harus diperbaiki pada beberapa cabang) dan tingkat dalam adalah rilis yang tepat dilakukan, yang dikelola dengan tag.

Khususnya, jika kita tahu versi persis apa yang dimiliki pelanggan, kita tahu persis dari mana sumber kode itu dibuat dan dapat membuat duplikat yang tepat sehingga kita bisa melihat dengan tepat apa yang sedang terjadi. Ini sangat penting untuk dukungan! Namun tingkat luar cabang, versi API yang saat ini kami rilis, mereka berkembang dari waktu ke waktu (dengan batang utama pengembangan mendapatkan sebagian besar fitur baru). Juga, ketika kami melakukan rilis besar baru dari API, kami melakukan cabang baru untuk mendukungnya dari (sehingga trunk selalu dapat berorientasi pengembangan hard-core) dan kami mempertimbangkan apakah kami harus mengakhiri masa pakai dukungan tertua saat ini cabang.

Jadi saya merekomendasikan sesuatu yang benar-benar campuran A dan B ; keduanya memiliki aspek yang baik, tetapi keduanya tidak lengkap. Gunakan yang terbaik dari kedua dunia.


0

Saya telah menggunakan TFS untuk secara efektif mengimplementasikan opsi (B) di masa lalu.

Percabangan / penggabungan adalah alat yang hebat ketika dilakukan dalam potongan-potongan kecil. Kesulitannya bukan terletak pada membuat cabang (itu bodoh mudah), atau mendorong kerja seminggu untuk cadangan pohon (itu biasanya mudah juga) ... itu dalam mendapatkan sistem CI di belakang kontrol sumber Anda untuk secara otomatis bekerja untuk kamu.

Karena percabangan diperdebatkan jika sistem tidak secara otomatis membuat dan menjalankan pengujian untuk cabang Anda.

Kami telah menyesuaikan alur kerja build default TFS untuk mengenali jalur relatif changesets, dan menetapkan konvensi yang dengannya kustomisasi dapat mengenali cabang baru (bukan sekadar subfolder baru di bawah beberapa root pengembangan). Itu mulus, mudah bercabang, mudah untuk membunuh cabang, dan kami mendapat umpan balik terus menerus dari sistem kami untuk kompilasi dan pengujian.

Saya melihat banyak orang menyatakan betapa tidak mungkinnya strategi-strategi ini berada di bawah TFS, dan saya percaya itu karena kurangnya pengetahuan tentang kemungkinan-kemungkinan mesin pembuat berbasis XAML. TFS bukan hanya kontrol sumber, ini adalah solusi menyeluruh, dan harus digunakan seperti itu.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.