Bagaimana kita bisa melacak versi kode kita di setiap lingkungan?

14

Tim saya saat ini menggunakan proses percabangan / penyebaran yang cukup sederhana yang terlihat seperti ini:

                ┌────────┐ ┌────┐ ┌──────┐
 Environments:  │  DEV   │ │ QA │ │ PROD │
                └────────┘ └────┘ └──────┘

                     ▲       ▲       ▲
                     │       │       │

                ┌────────┐ ┌────┐ ┌──────┐
 Builds:        │  DEV   │ │ QA │ │ PROD │
                └────────┘ └────┘ └──────┘

                     ▲       ▲       ▲
                     │       │       │

                ┌────────┐ ┌────┐ ┌──────┐
 Branches:      │ master │ │ qa │ │ prod │
                └────────┘ └────┘ └──────┘

Setiap lingkungan memiliki cabang sendiri (kami menggunakan git ) dan bangunannya sendiri yang menggunakan cabang itu. Ketika kami ingin mempromosikan dari satu lingkungan ke lingkungan lain, misalnya, dari DEV ke QA, kami menggabungkan mastercabang ke dalam qadan memulai bangunan QA baru (yang kemudian secara otomatis digunakan untuk lingkungan QA).

Kami sedang mempertimbangkan untuk pindah ke proses baru yang akan dilakukan dengan memiliki cabang khusus dan membangun untuk setiap lingkungan. Sebagai gantinya, satu rilis build akan menciptakan "paket penempatan" yang kemudian dapat digunakan untuk lingkungan apa pun. Kami membayangkan alur kerja yang khas akan terlihat seperti ini:

                ┌────────┐     ┌────┐     ┌──────┐
 Environments:  │  DEV   │ ──► │ QA │ ──► │ PROD │
                └────────┘     └────┘     └──────┘

                      ▲ 
                       \ 

                        ┌───────────────┐
 Builds:                │ release build │
                        └───────────────┘

                                ▲
                                │

                ┌────────┐ ┌─────────┐
 Branches:      │ master │ │ release │
                └────────┘ └─────────┘

Promosi dari satu lingkungan ke lingkungan yang lain tidak akan lagi ditangani dalam kendali sumber; alih-alih, kami hanya akan mengambil binari yang sudah dibangun ("paket penempatan") dan meletakkannya di lingkungan baru.

Sistem baru ini akan memungkinkan kami untuk menyebarkan bangunan apa pun ke lingkungan apa pun, yang memiliki beberapa keunggulan. Misalnya, sangat mudah untuk menguji perbaikan bug PROD di DEV dan QA. Sistem kami saat ini tidak menyediakan cara mudah untuk melakukan ini tanpa memutar kembali cabang, yang jelas ingin kami hindari.

Kelemahan terbesar dengan sistem baru ini adalah kita tidak lagi memiliki cara otomatis untuk melacak kode apa yang ada di lingkungan mana. Jika kami perlu memperbaiki di PROD, kami tidak lagi memiliki cabang khusus yang disinkronkan dengan basis kode produksi saat ini. Hal yang sama berlaku untuk QA - jika kita ingin mendorong perubahan cepat ke QA tanpa mengeruk pekerjaan dalam proses darimaster , kita tidak lagi memiliki cabang yang mencerminkan keadaan lingkungan QA saat ini.

Bagaimana kita bisa melacak kode apa yang ada di setiap lingkungan?

Beberapa opsi yang kami pertimbangkan:

  • menggunakan tag git untuk melacak komit di lingkungan mana
  • menanamkan komit git yang digunakan oleh build ke dalam setiap paket penempatan
Nathan Friend
sumber
Apakah Anda memiliki sistem CI seperti Hudson atau Jenkins? Apakah ini mampu mendorong tag dari apa yang dibangunnya kembali ke git? (Saya tahu ada plugin untuk Hudson dan Jenkins yang dapat ... - tidak begitu yakin tentang yang lain).
@MichaelT Kami menggunakan MSBuild untuk build kami dan Octopus Deploy untuk penyebaran kami. Saya cukup yakin kami dapat membuat Octopus memanipulasi repositori git kami dengan skrip penyebaran Powershell kustom.
Nathan Friend

Jawaban:

14

Tag git adalah apa yang benar-benar ingin Anda gunakan untuk menunjuk rilis. Alasannya adalah bahwa mereka memiliki arti bagi Anda dan dapat digunakan untuk dengan cepat mengenali hubungan antara kode yang digunakan negara dan informasi apa pun yang mungkin dimiliki oleh server build (seperti nomor build).

Meskipun itu adalah jawaban yang Anda cari, itu hanya memecahkan setengah dari masalah. Yang lainnya adalah "hei, ini yang digunakan.[wje]ar di server, apa membangun asalnya?" Kami tahu bahwa Anda tidak akan pernah memiliki versi aplikasi yang berbeda yang digunakan pada dev dan qa atau prod. Baik?

Solusi untuk bagian pertanyaan itu adalah membuat server memasukkan informasi ke manifes. Berasal dari pakar dan contoh yang saya miliki di depan saya:

<manifestEntries>
    <Specification-Title>${project.name}</Specification-Title>
    <Specification-Version>${project.version}</Specification-Version>
    <Build-Number>${build.number}</Build-Number>
    <Build-Id>${build.id}</Build-Id>
    <Svn-Revison>${svn.revision}</Svn-Revison>
</manifestEntries>

Itu dalam konfigurasi arsip maven-war-plugin. Tetapi Anda dapat menemukannya di plugin lain juga. Kemudian di Hudson, bagian dari doa membangun maven adalah:

-Dbuild.number=${BUILD_NUMBER}
-Dsvn.revision=${SVN_REVISION}
-Dbuild.id=${BUILD_ID}

yang menetapkan definisi itu yang kemudian diangkat. Dan kemudian hanya masalah mencari di file MANIFEST.MF yang telah digunakan di server untuk melihat versi apa itu.

Ada plugin git , yang menawarkan serangkaian variabel lingkungan yang serupa termasuk:

  • GIT_COMMIT - SHA dari arus
  • GIT_BRANCH - Nama repositori jarak jauh (default ke asal), diikuti oleh nama cabang yang sedang digunakan, misalnya "asal / master" atau "asal / foo"

Kombinasi dari dua praktik ini memungkinkan Anda untuk dengan mudah mengidentifikasi build (karena angka build maju, dan memiliki makna, tidak seperti shum checksums) dan git commit spesifik yang menjadi asal dibangunnya.


sumber
3

Pendekatan yang benar-benar berbeda adalah dengan mengabaikan ide versionssepenuhnya. Anda hanya memiliki "satu versi" yang memiliki perilaku yang dapat dikonfigurasi yang berbeda. Satu-satunya perbedaan adalah, bahwa Anda memiliki basis kode yang sama - bahkan dalam produksi Anda akan menyebarkan pekerjaan yang sedang berjalan : tetapi tidak diaktifkan.

Perbedaannya hanya bermuara pada serangkaian fitur yang diaktifkan pada produk Anda.

De / aktivasi dilakukan melalui fitur toggle .

Terbalik: seluruh proses rilis disederhanakan: Anda selalu memberikan versi terintegrasi dari perangkat lunak Anda. Setiap fitur selalu tersedia dimaster . Tidak diperlukan cabang tambahan.

Tidak ada rasa sakit dengan fitur penggabungan bersama, karena: tidak ada cabang tidak perlu untuk bergabung. Tidak ada kebingungan fitur apa pada cabang mana dan mungkin bergantung atau berbenturan dengan fitur dari cabang lain. Setiap bagian dapat diaktifkan sesuka hati. Bahkan rollback tidak diperlukan lagi: itu hanya flip switch .

Saya tidak tahu, jika itu berfungsi untuk basis kode Anda: prasyarat dalam hal kualitas kode dan disiplin pengembang cukup tinggi - Anda harus berurusan dengan "pembersihan" setelah fitur menjadi fungsi inti dan Anda harus mengelola banyak toggle mencegah kekacauan yang lebih besar .

Mungkin itu berhasil untuk Anda.

Thomas Junk
sumber
Tetapi bagaimana dengan memiliki status repositori yang berbeda yang digunakan untuk server yang berbeda? Apakah kode yang berjalan pada kotak QA sama dengan kode yang berjalan pada produksi untuk dapat mereproduksi bug? Apakah kode yang pengembang mendorong ke kotak pengembang mereka sama dengan kode yang dijalankan QA?
1
Pertanyaannya harus ditanyakan berbeda: apakah bug dengan konfigurasi khusus dapat direproduksi "sekarang" jika ya, Anda dapat memperbaikinya. Jika tidak - apakah masalah bug? Anda selalu mendorong kerja (dan kode terintegrasi).
Thomas Junk
-1

Kami menggunakan pakar untuk memasukkan versi ke file manifes. Kemudian mintalah aplikasi menampilkan versi jika itu adalah aplikasi web, atau memiliki titik akhir / versi untuk layanan web.

Josh Chappelle
sumber