Apakah praktik yang baik untuk menyimpan nomor versi perangkat lunak di VCS?

22

Versi produk, seperti v1.0.0.100, tidak hanya mewakili rilis produksi perangkat lunak yang unik, tetapi juga membantu mengidentifikasi rangkaian fitur dan tahapan perbaikan terbaru untuk produk tersebut. Saat ini saya melihat dua cara untuk mempertahankan versi akhir paket / build / biner suatu produk:

  1. Kontrol Versi. File di suatu tempat menyimpan nomor versi. Server pembangunan Continuous Integration (CI) akan memiliki skrip untuk membangun perangkat lunak yang menggunakan nomor versi check-in ini untuk menerapkannya ke semua area perangkat lunak yang diperlukan (binari, paket penginstal, halaman bantuan, dokumentasi, dll).

  2. Parameter lingkungan dan / atau bangunan. Ini dipertahankan di luar kontrol versi (yaitu mereka tidak terikat pada snapshot / tag / cabang). Skrip build mendistribusikan dan menggunakan nomor dengan cara yang sama, namun mereka hanya mendapatkan nilainya secara berbeda ( disediakan untuk skrip build, alih-alih membuat skrip tahu di mana harus mendapatkannya relatif terhadap pohon kode sumber).

Masalah dengan pendekatan pertama adalah bahwa hal itu dapat mempersulit penggabungan lintas cabang-cabang arus utama. Jika Anda masih mempertahankan 2 rilis paralel dari perangkat lunak yang sama, Anda akan menyelesaikan konflik saat menggabungkan antara kedua arus utama jika versi telah berubah pada keduanya sejak penggabungan terakhir.

Masalah dengan pendekatan kedua adalah rekonsiliasi. Saat Anda kembali ke rilis 1 tahun yang lalu, Anda hanya akan bergantung pada informasi tag untuk mengidentifikasi nomor rilisnya.

Dalam kedua kasus, mungkin ada aspek-aspek tertentu dari nomor versi yang tidak diketahui sebelum CI membangun. Sebagai contoh, build CI dapat secara terprogram memasukkan komponen ke-4 yang benar-benar nomor build otomatis (mis. Build 140 di cabang). Mungkin juga nomor revisi di VCS.

Apa cara terbaik untuk mengikuti nomor versi perangkat lunak? Haruskah bagian "dikenal" selalu dipertahankan dalam VCS? Dan jika demikian, apakah konflik lintas cabang utama merupakan masalah?

Saat ini kami mempertahankan nomor versi kami melalui parameter yang ditentukan dan dipelihara dalam CI build plan (Atlassian Bamboo). Kita harus berhati-hati sebelum bergabung ke mastercabang kami bahwa nomor versi telah disiapkan dengan benar sebelum CI membangun dimulai . Sehubungan dengan alur kerja Gitflow, saya merasa bahwa jika nomor versi dilacak dalam kontrol sumber, kami dapat menjamin itu diatur dengan benar ketika kami membuat releasecabang kami dalam persiapan rilis. QA akan melakukan pengujian integrasi / asap / regresi akhir pada cabang ini dan pada saat penandatanganan, penggabungan masterterjadi yang menandakan komitmen untuk dirilis.

void.pointer
sumber
3
Apakah konflik gabungan antara dua versi file di version.txtmana satu versi berisi satu baris 1.0.7dan yang lainnya 1.2.0benar - benar sulit untuk diselesaikan? Jika ini adalah satu-satunya konflik dalam menggabungkan dua cabang yang terpisah, saya akan menganggap diri saya sangat beruntung. Seberapa sering itu terjadi? Jika hal itu terjadi, bukankah itu hal yang baik bahwa Anda dipaksa untuk berpikir tentang nomor versi apa yang seharusnya dimiliki oleh versi gabungan? (Maaf atas penggunaan kata "versi" yang
mendua
1
@ 5gon12eder Kesulitan atau perasaan tentang penggabungan itu sendiri tidak relevan. Itu hanya aspek negatif dari solusi keseluruhan.
void.pointer

Jawaban:

28

Secara pribadi, saya memilih opsi 3: menyimpan informasi versi dalam metadata VCS , khususnya, tag.

Git membuatnya sangat mudah untuk melakukannya, karena ada perintah git describe, yang dapat secara unik menggambarkan komit berdasarkan tag. Begini cara kerjanya:

  • Jika komit saat ini ditandai, output nama tag.
  • Jika tidak, berjalan mundur sejarah sampai Anda menemukan tag dan kemudian output deskripsi dalam format berikut: <tag>-<number of commits since the tag>-g<abbreviated commit hash>.
  • Jika ada perubahan yang tidak dikomit di pohon kerja, tambahkan -dirty.

Jadi, jika Anda melakukan rilis build, dan memiliki tag yang ditandai 1.2.3, itu akan ditampilkan 1.2.3. Jika saat ini Anda mengerjakan 1.2.4 dan Anda membuat 4 komitmen sejak 1.2.3, dan memiliki perubahan yang tidak dikomit di pohon, itu akan ditampilkan 1.2.3-4-gdeadbee-dirty.

Ini dijamin unik dan monoton, serta dapat dibaca oleh manusia, dan dengan demikian dapat digunakan secara langsung sebagai string versi. Satu-satunya hal yang harus Anda pastikan adalah konvensi penamaan yang tepat untuk tag.

Jörg W Mittag
sumber
Saya sangat menyukai ide ini, tetapi ini tampaknya sulit untuk dikelola dengan JIRA + Bamboo. Bambu hanya berfungsi pada cabang, bukan tag, jadi Anda harus memastikan tag didorong sebelum build dibuat. Ini rentan kesalahan.
void.pointer
1
git describejuga bekerja dengan cabang: " --semua - Alih-alih hanya menggunakan tag beranotasi, gunakan referensi apa pun yang ditemukan di refs/namespace. Opsi ini memungkinkan pencocokan cabang yang dikenal, cabang pelacakan jarak jauh, atau tag ringan." Namun, tidak yakin bagaimana cara kerjanya dengan Bambu. (Ini tentu saja membutuhkan penamaan cabang yang hati-hati, sama seperti mode normal dengan tag.)
Jörg W Mittag
1
Saya tahu beberapa orang yang melakukan rilis sepenuhnya otomatis dari Git. String versi dibangun oleh git describe, ChangeLog dihasilkan dari git shortlog(yah, sebenarnya dari skrip yang mem-parsing output git log --pretty=tformat:<some custom format string>), dan catatan rilis dihasilkan dari deskripsi tag dan git notesdilampirkan ke komitmen tonggak penting.
Jörg W Mittag
Maksud saya adalah, bahwa tag harus dibuat sebelum rilis sehingga dilakukan setelah itu benar versi dengan nomor basis. Ini bertentangan dengan prinsip pemberian tag selama atau pada saat rilis. Mengambil bambu membangun secara otomatis berdasarkan komit ke master(dari develop, ingat saya menggunakan gitflow). Bagaimana jika seseorang mendorong penggabungan mastertanpa tag? Itu tidak akan menggunakan versi yang tepat (sebenarnya itu akan menggunakan versi rilis terakhir )
void.pointer
Jika Anda menggunakan skema seperti ini, penandaan sedang dirilis. Ah, saya mengerti apa maksud Anda. Jadi, saat ini, server CI Anda adalah driver rilis, dan dengan perubahan ini, SCM adalah driver rilis, tetapi Anda ingin tetap seperti itu?
Jörg W Mittag
8

Iya nih. Ini adalah praktik yang baik untuk menjaga sebagian besar nomor versi dalam vcs. Jika kita mempertimbangkan versi semantik semver.org di mana kita memiliki major.minor.patch.build, tiga yang pertama harus hidup dalam vcs. Yang terakhir bisa berupa angka tambahan dari server build Anda yang digunakan untuk melacak komit spesifik tempat biner dibuat.

Untuk memfasilitasi ini dalam. NET kami telah membuat exe garis cmd kecil yang berkomitmen untuk git. Dengan acara pra-build, ia mengambil nomor build yang ditandai oleh teamcity selama build. Alat garis cmd ini secara otomatis menghasilkan kelas dengan satu konstanta berisi nomor build. Sisa nomor versi: major.minor.patch hanyalah konstanta normal di file lain. Dua file bersama ini disertakan dalam setiap unit dalam solusi sebagai tautan (alt + shift-drag).

Pendekatan ini cukup kuat sehingga kita dapat membuat tim membangun dan menguji kode kita. Dorong ke biru dan minta kudu membangunnya lagi tetapi dengan nomor teamcity build sebagai versi dll.

Esben Skov Pedersen
sumber