Strategi percabangan terbaik saat melakukan integrasi berkelanjutan?

100

Apa strategi percabangan terbaik untuk digunakan saat Anda ingin melakukan integrasi berkelanjutan?

  1. Release Branching: kembangkan di trunk, pertahankan cabang untuk setiap rilis.
  2. Pencabangan Fitur: kembangkan setiap fitur di cabang terpisah, hanya gabungkan setelah stabil.

Apakah masuk akal untuk menggunakan kedua strategi ini bersama-sama? Seperti, Anda bercabang untuk setiap rilis tetapi Anda juga bercabang untuk fitur-fitur besar? Apakah salah satu dari strategi ini lebih cocok dengan integrasi berkelanjutan? Akankah menggunakan integrasi berkelanjutan masuk akal saat menggunakan trunk yang tidak stabil?

KingNestor
sumber
2
Catatan tambahan: beberapa orang akan berpendapat bahwa meskipun fitur baru telah dimasukkan, semuanya harus selalu stabil. Di sisi lain, itu mungkin agak idealis.
Keith Pinson

Jawaban:

21

Saya menemukan topik ini sangat menarik karena saya sangat bergantung pada cabang dalam pekerjaan saya sehari-hari.

  • Saya ingat Mark Shuttleworth mengusulkan model tentang menjaga cabang utama tetap murni sambil melampaui CI konvensional. Saya memposting tentang itu di sini .
  • Karena saya akrab dengan Cruise Control, saya juga membuat blog tentang cabang tugas dan CI di sini . Ini adalah tutorial langkah demi langkah yang menjelaskan bagaimana melakukannya dengan SCM Plastik .
  • Akhirnya, saya menemukan beberapa topik tentang CI (dan berpotensi berbicara tentang percabangan) di buku Duvall tentang CI juga sangat menarik .

Semoga Anda menemukan tautannya menarik.

pablo
sumber
Kami menambahkan dukungan ke Bamboo untuk melakukan cabang per tugas codicesoftware.blogspot.com/2012/02/… , dan tampaknya versi terbaru mereka akan melakukannya secara native dengan beberapa kontrol versi, termasuk dvcs.
pablo
20

Jawabannya bergantung pada ukuran tim Anda dan kualitas kontrol sumber Anda dan kemampuan untuk menggabungkan kumpulan perubahan kompleks dengan benar. Misalnya dalam kontrol sumber cabang penuh seperti penggabungan CVS atau SVN bisa jadi sulit dan Anda mungkin lebih baik dengan model pertama, sementara jika menggunakan sistem yang lebih kompleks seperti IBM ClearCase dan dengan ukuran tim yang lebih besar Anda bisa lebih baik dengan model kedua. model atau kombinasi keduanya.

Saya pribadi akan memisahkan model cabang fitur, di mana setiap fitur utama dikembangkan pada cabang terpisah, dengan sub-cabang tugas untuk setiap perubahan yang dilakukan oleh pengembang individu. Saat fitur stabil, fitur tersebut digabungkan ke trunk, yang Anda pertahankan agar cukup stabil dan melewati semua uji regresi setiap saat. Saat Anda mendekati akhir siklus rilis dan semua cabang fitur bergabung, Anda menstabilkan dan mencabangkan cabang sistem rilis tempat Anda hanya melakukan perbaikan bug stabilitas dan backport yang diperlukan, sementara trunk digunakan untuk pengembangan rilis berikutnya dan Anda lagi bercabang untuk cabang fitur baru. Dan seterusnya.

Dengan cara ini trunk selalu berisi kode terbaru, tetapi Anda berhasil menjaganya tetap stabil, membuat label (tag) yang stabil pada perubahan besar dan penggabungan fitur, cabang fitur adalah pengembangan yang serba cepat dengan integrasi berkelanjutan dan tugas individu sub-cabang dapat sering disegarkan dari cabang fitur agar semua orang yang mengerjakan fitur yang sama tetap sinkron, sekaligus tidak memengaruhi tim lain yang mengerjakan fitur yang berbeda.

Pada saat yang sama Anda telah melalui sejarah serangkaian cabang rilis, di mana Anda dapat memberikan backport, dukungan dan perbaikan bug untuk pelanggan Anda yang karena alasan apapun tetap menggunakan versi produk Anda sebelumnya atau bahkan hanya versi rilis terbaru. Seperti halnya trunk, Anda tidak menyiapkan integrasi berkelanjutan pada cabang rilis, mereka diintegrasikan secara hati-hati setelah melewati semua uji regresi dan kontrol kualitas rilis lainnya.

Jika karena alasan tertentu dua fitur saling bergantung dan memerlukan perubahan yang dilakukan oleh satu sama lain, Anda dapat mempertimbangkan untuk mengembangkan keduanya pada cabang fitur yang sama atau meminta fitur untuk secara teratur menggabungkan bagian kode yang stabil ke trunk dan kemudian menyegarkan perubahan dari trunk untuk bertukar kode antar cabang trunk. Atau jika Anda perlu memisahkan kedua fitur tersebut dari yang lain, Anda dapat membuat cabang umum yang Anda gunakan untuk membuat cabang fitur tersebut dan yang dapat Anda gunakan untuk bertukar kode di antara fitur-fitur tersebut.

Model di atas tidak masuk akal dengan tim di bawah 50 pengembang dan sistem kontrol sumber tanpa cabang yang jarang dan kemampuan penggabungan yang tepat seperti CVS atau SVN, yang hanya akan membuat keseluruhan model ini menjadi mimpi buruk untuk disiapkan, dikelola, dan diintegrasikan.

Jiri Klouda
sumber
5
Saya tidak yakin apakah saya setuju bahwa penjelasan Anda tidak masuk akal untuk tim di bawah 50 pengembang. Saya juga bisa melihat keuntungan untuk tim yang lebih kecil. +1
Aardvark
2
Tentu saja, ada keuntungan bagi tim dengan ukuran berapa pun. Pertanyaannya adalah pada ukuran tim apa manfaatnya lebih besar daripada biaya yang terkait dengan proses yang berat.
Jiri Klouda
Ini mirip dengan model GitFlow, dan / atau GitHubFlow. Saya rasa model ini tidak memfasilitasi Continuous Integration (CI). Menurut saya, Trunk Based Development merupakan peningkatan yang signifikan dari model-model ini.
Yani
Anda dapat melihat bahwa komentar ini sebenarnya mendahului rilis asli git flow. Tidak begitu yakin apa yang Anda maksud dengan "lebih baik". Saya telah mendukung tim yang terdiri dari 1, 5, 25, 150, 1.000, dan 20.000 pengembang yang mengerjakan proyek yang terintegrasi sampai batas tertentu. Persyaratan bervariasi dan "lebih baik" adalah istilah yang sangat relatif. Apakah Anda pernah perlu mem-backport kode? Perbaikan keamanan? Jika tidak, maka hidup Anda sederhana. SaaS adalah akibat langsung dari pembatasan yang diberlakukan oleh pengembangan berbasis trunk. Tanda fitur sama rumitnya dengan cabang fitur. Kecuali Anda hanya mencari tahu dari pelanggan ketika permutasi mereka rusak.
Jiri Klouda
9

Saya pribadi merasa jauh lebih bersih memiliki trunk yang stabil dan melakukan percabangan fitur. Dengan begitu, penguji dan sejenisnya dapat menggunakan satu "versi" dan memperbarui dari trunk untuk menguji fitur apa pun yang merupakan kode lengkap.

Juga jika beberapa pengembang mengerjakan fitur yang berbeda, mereka semua dapat memiliki cabang yang terpisah, kemudian bergabung ke trunk setelah selesai dan mengirim fitur untuk diuji tanpa penguji harus beralih ke beberapa cabang untuk menguji fitur yang berbeda.

Sebagai bonus tambahan, ada beberapa tingkat pengujian integrasi yang datang secara otomatis.

Adnan
sumber
Selain itu, apakah Anda masih bercabang dan memberi tag untuk setiap rilis utama? Atau hanya menandai?
KingNestor
1
Ia bekerja dengan baik dengan CI selama cabang-cabang fitur digabungkan menjadi trunk dengan beberapa disiplin agar tidak merusak build. Saya melakukan pencabangan dan tag untuk setiap rilis produksi yang hanya akan digunakan untuk perbaikan bug. Itu bisa segera digabungkan ke dalam bagasi kandang.
Adnan
@king Saya akan mengatakan itu mungkin tergantung pada apa yang Anda sebut rilis utama, tetapi dalam kedua kasus Anda dapat memberi tag, dan bercabang nanti saat Anda membutuhkannya (berdasarkan tag :))
eglasius
5

Saya pikir salah satu strategi dapat digunakan dengan pengembangan berkelanjutan asalkan Anda mengingat salah satu prinsip utama yang dikomitmenkan oleh setiap pengembang ke trunk / mainline setiap hari.

http://martinfowler.com/articles/continuousIntegration.html#EveryoneCommitsToTheMainlineEveryDay

EDIT

Saya telah membaca beberapa buku ini tentang CI dan penulis menyarankan bahwa percabangan menurut rilis adalah strategi percabangan yang mereka sukai. Saya harus setuju Bercabang menurut fitur tidak masuk akal bagi saya saat menggunakan CI.

Saya akan mencoba dan menjelaskan mengapa saya berpikir seperti ini. Katakanlah tiga pengembang masing-masing mengambil cabang untuk mengerjakan fitur. Setiap fitur membutuhkan waktu beberapa hari atau minggu untuk menyelesaikannya. Untuk memastikan tim terus berintegrasi, mereka harus berkomitmen ke cabang utama setidaknya sekali sehari. Segera setelah mereka mulai melakukan ini, mereka kehilangan manfaat dari pembuatan cabang fitur. Perubahan mereka tidak lagi terpisah dari semua perubahan pengembang lain. Karena itu, mengapa repot-repot membuat cabang fitur?

Menggunakan percabangan menurut rilis membutuhkan lebih sedikit penggabungan antar cabang (selalu merupakan hal yang baik), memastikan bahwa semua perubahan terintegrasi ASAP dan (jika dilakukan dengan benar) memastikan basis kode Anda selalu siap untuk dirilis. Sisi bawah dari percabangan dengan rilis adalah Anda harus lebih berhati-hati dengan perubahan. Misalnya refactoring besar harus dilakukan secara bertahap dan jika Anda sudah mengintegrasikan fitur baru yang tidak Anda inginkan di rilis berikutnya maka itu harus disembunyikan menggunakan semacam mekanisme toggling fitur .

EDIT LAINNYA

Ada lebih dari satu pendapat tentang hal ini. Berikut adalah posting blog yang merupakan percabangan fitur pro dengan CI

http://jamesmckay.net/2011/07/why-does-martin-fowler-not-understand-feature-branches/

Phil Hale
sumber
menarik, tidak dapat menemukan posting ini lagi.
Jirong Hu
5

Cabang rilis sangat berguna, dan bahkan mutlak diperlukan, jika Anda perlu mempertahankan beberapa versi aplikasi Anda.

Cabang fitur juga sangat nyaman, terutama jika satu pengembang perlu mengerjakan perubahan besar, sementara yang lain masih merilis versi baru.

Jadi bagi saya, menggunakan kedua mekanisme tersebut adalah strategi yang sangat bagus.

Link menarik dari Kitab SVN .

SirFabel
sumber
4

Saya baru-baru ini menyukai model ini saat menggunakan git. Meskipun pertanyaan Anda diberi tag "svn", Anda mungkin masih dapat memanfaatkannya.

Integrasi Berkelanjutan sampai batas tertentu dapat terjadi di cabang "pengembangan" (atau apa pun sebutannya) dalam model ini, meskipun memiliki cabang fitur yang berjalan lama untuk rilis mendatang tidak akan membuatnya begitu kaku untuk mempertimbangkan setiap perubahan yang terjadi pada kode di suatu tempat. Pertanyaannya tetap, apakah Anda benar-benar menginginkannya. Martin Fowler melakukannya.

hermannloose
sumber
2

Integrasi berkelanjutan seharusnya tidak menjadi faktor apa pun dalam menentukan strategi percabangan Anda. Pendekatan percabangan Anda harus dipilih berdasarkan tim Anda, sistem yang sedang dikembangkan, dan alat yang tersedia untuk Anda.

Karena itu ...

  • tidak ada alasan mengapa CI tidak dapat digunakan di kedua pendekatan yang Anda gambarkan
  • pendekatan tersebut bekerja dengan cukup baik dalam kombinasi
  • tak satu pun dari keduanya bekerja "lebih baik" dari yang lain
  • CI sangat masuk akal dengan trunk yang tidak stabil

Semua ini terjawab pada pertanyaan keempat di halaman tempat Anda mengambil diagram dari: http://blogs.collab.net/subversion/2007/11/branching-strat/

Zac Thompson
sumber
2

Selama Anda memahami prinsip, Anda selalu dapat menemukan kembali praktik terbaik. Jika Anda tidak memahami prinsip-prinsip, praktik terbaik akan membawa Anda sejauh itu sebelum berantakan karena beberapa persyaratan eksternal yang bertentangan.

Untuk pengenalan terbaik tentang Model Garis Utama, baca ini: https://web.archive.org/web/20120304070315/http://oreilly.com/catalog/praktisperforce/chapter/ch07.pdf

Baca linknya. Setelah Anda menguasai dasar-dasarnya, bacalah artikel berikut oleh Yang Mulia Henrik Kniberg. Ini akan membantu Anda menghubungkan Model Garis Utama dengan integrasi berkelanjutan.

http://www.infoq.com/articles/agile-version-control

zvolkov.dll
sumber
Bab O'Reilly tidak lagi dapat diakses
Jason S
1

Ketika kami memulai tim kami, kami mewarisi strategi berbasis rilis dari vendor yang awalnya mengembangkan sistem yang akan kami tangani. Ini bekerja sampai saat pelanggan kami meminta agar beberapa fitur yang dikembangkan tidak boleh disertakan dalam rilis (fyi ~ 250k baris kode, ~ 2500 file, Scrum dengan XP SDLC).

Kemudian kami mulai melihat cabang berbasis fitur. Ini juga berhasil untuk sementara waktu - seperti 2 bulan sampai kami menyadari bahwa proses pengujian regresi kami akan memakan waktu lebih dari 2 minggu yang dikombinasikan dengan ketidakpastian tentang apa yang akan dirilis menciptakan ketidaknyamanan yang sangat besar.

"Paku di peti mati" terakhir dari strategi SC murni datang ketika kami memutuskan bahwa kami harus memiliki 1. batang stabil dan 2. Produksi harus mengandung ST, UAT, dan BINARY teruji Regresi (bukan hanya sumber - pikirkan CC.)

Hal ini mengarahkan kami untuk merancang strategi yang merupakan gabungan antara fitur dan strategi SC berbasis rilis.

Jadi kami memiliki bagasi. Setiap sprint kami membuat cabang sprint cabang (untuk orang-orang yang tidak gesit - sprint hanyalah upaya pengembangan waktu terbatas dengan output variabel berdasarkan kompleksitas.) Dari cabang sprint kami membuat cabang fitur dan pengembangan paralel dimulai di dalamnya. Setelah fitur selesai dan sistem diuji, dan kami menerima niat untuk menerapkannya, fitur tersebut digabungkan ke cabang sprint - beberapa mungkin mengambang di beberapa sprint, biasanya yang lebih kompleks. Setelah sprint hampir berakhir dan fiturnya selesai ... kami "mengganti nama" cabang sprint menjadi "regresi" (ini memungkinkan CruiseControl untuk mengambilnya tanpa konfigurasi ulang) dan kemudian pengujian regresi / integrasi dimulai pada cc-built TELINGA. Ketika semuanya selesai, itu masuk ke dalam produksi.

Singkatnya, cabang berbasis fitur digunakan untuk mengembangkan, menguji sistem, dan fungsionalitas UAT. Cabang sprint (sebenarnya cabang rilis) digunakan untuk secara selektif menggabungkan fitur on-demand dan integrasi-test.

Sekarang, inilah pertanyaan kepada komunitas - kami jelas mengalami masalah dalam melakukan integrasi berkelanjutan karena fakta bahwa pengembangan terjadi di banyak cabang dan overhead konfigurasi ulang CruiseControl. Adakah yang bisa memberi saran dan nasihat?

XAvatar
sumber
Saya belum tentu setuju dengan kesimpulannya, tapi terima kasih atas diskusi proses Anda. Tidak ada solusi satu ukuran untuk semua.
RaoulRubin
0

Menurut saya, Anda ingin memiliki sekumpulan cabang terbatas di mana Anda dapat fokus. Karena Anda ingin pengujian, metrik kualitas kode, dan banyak hal menarik untuk dijalankan dengan build, memiliki terlalu banyak laporan mungkin akan membuat Anda melewatkan info.

Kapan dan apa yang akan dicabangkan, biasanya tergantung pada ukuran tim dan ukuran fitur yang dikembangkan. Saya tidak berpikir ada aturan emas. Pastikan Anda menggunakan strategi di mana Anda bisa mendapatkan umpan balik lebih awal / sering, dan itu termasuk melibatkan kualitas sejak awal fitur. Sedikit kualitas, berarti bahwa saat Anda mengotomatiskan saat tim berkembang, jika Anda membuat cabang untuk kumpulan fitur besar yang sedang dibangun tim, Anda juga harus memiliki kualitas yang terlibat dalam tim.

ps Dari mana Anda mendapatkan referensi pendekatan tersebut? - tidak merasa bahwa grafik tersebut mewakili semua opsi

Pembaruan 1: Memperluas mengapa saya mengatakan itu bukan aturan emas. Pada dasarnya untuk tim yang relatif kecil saya telah menemukan yang terbaik dengan menggunakan pendekatan campuran. Cabang fitur dibuat jika itu adalah sesuatu yang panjang dan bagian dari tim akan terus menambahkan fitur yang lebih kecil.

eglasius.dll
sumber
Ini memiliki lebih banyak juga. Namun menurut saya, Pencabangan Fitur dan Pencabangan Fitur adalah 2 yang paling umum.
KingNestor
0

Dave Farley , seorang penulis Continuous Delivery , menyebut Trunk Based Development (TBD) sebagai landasan dari Continuous Integration (CI) dan Continuous Delivery (CD). Dia berkata:

Segala bentuk percabangan bertentangan dengan Integrasi Berkelanjutan.

Dia juga berkata,

Pencabangan Fitur sangat bagus dari perspektif pengembang individu tetapi kurang optimal dari perspektif tim. Kita semua ingin mengabaikan apa yang dilakukan orang lain dan melanjutkan pekerjaan kita. Sayangnya, kode tidak seperti itu. Bahkan dalam basis kode berfaktor sangat baik dengan pemisahan perhatian yang indah dan komponen yang sangat longgar digabungkan, beberapa perubahan mempengaruhi bagian lain dari sistem.

Trunk Based Development (TBD) adalah praktik mengintegrasikan perubahan kode ke dalam trunk (alias, master, jalur utama) setidaknya sekali sehari - lebih disukai beberapa kali per hari. Continuous Integration (CI) adalah praktik serupa kecuali yang juga melibatkan verifikasi perubahan kode menggunakan tes otomatis. Strategi percabangan terbaik untuk ini adalah bekerja langsung dari trunk dan melakukan tinjauan kode melalui Pair-Programming . Jika karena alasan tertentu Anda tidak dapat memasangkan, atau Anda hanya ingin bercabang, pastikan cabang Anda berumur pendek (kurang dari sehari).

Saya mengerjakan Trunk, "master" di repo GIT saya. Saya berkomitmen untuk menguasai secara lokal dan segera mendorong, ketika saya terhubung ke jaringan, ke repo master pusat saya tempat CI berjalan. Itu dia!

Untuk fitur besar (yaitu fitur yang membutuhkan waktu lebih dari satu hari), cobalah untuk memecahnya menjadi potongan kecil logika yang dapat diintegrasikan ke dalam trunk tanpa merusak perangkat lunak. Anda juga dapat menggunakan teknik seperti penandaan fitur dan pencabangan dengan abstraksi yang memungkinkan Anda menerapkan pekerjaan yang tidak lengkap tanpa memengaruhi pengguna akhir.

Saya menggunakan branch dengan abstraction, dark-releasing dan terkadang feature-flags. Apa yang saya dapatkan sebagai balasannya adalah umpan balik yang cepat, pasti (setidaknya untuk kualitas pengujian saya).

Yani
sumber
Dave Farley dan Jez Humble salah dalam pendirian mereka tentang percabangan. Alasannya adalah karena ini mengkodekan asumsi penting "Anda tidak akan pernah harus memanipulasi kode pada tingkat fitur dan jika, maka tidak apa-apa menjadikannya operasi yang mahal" dan mereka mendasarkan penilaian mereka pada asumsi lain "penggabungan terlalu mahal dengan otomatis menggabungkan menjadi hampir tidak mungkin dalam skala ". Jika kedua asumsi tersebut tidak benar, jika Anda tinggal di dunia di mana penggabungan itu murah, tetapi perlu memanipulasi kode pada tingkat fitur untuk port belakang dan perbaikan keamanan, maka pernyataan mereka akan rusak. Ini kasus yang jarang terjadi.
Jiri Klouda
Beberapa perusahaan juga perlu memajukan fitur ke rilis mendatang, setelah fitur tersebut mengalami hambatan dalam implementasi dan menunda rilis. Terkadang ada opsi untuk membiarkan kode tetap masuk, seperti di produk SaaS, tetapi jika kode dirilis ke pelanggan, ini mungkin bukan opsi karena dapat dianalisis oleh pesaing. Begitu banyak kode hari ini yang tidak dikompilasi dan bahkan jika ya, tanda / tanda fitur dalam kode berada pada tingkat kompleksitas yang sama dengan cabang.
Jiri Klouda
-3

Saya pikir alat yang Anda gunakan adalah faktor besar di sini.

  • Jika Anda menggunakan subversi, tetap dengan opsi 1 dan lepaskan dari cabang.
  • Jika Anda menggunakan GIT, opsi 2 akan bekerja dengan baik untuk Anda.
Tony Zampogna
sumber
2
Pencabangan