Apa praktik terbaik saat ini untuk penomoran bangun sistematis dan manajemen nomor versi dalam proyek Java? Secara khusus:
Bagaimana mengelola angka membangun secara sistematis dalam lingkungan pengembangan terdistribusi
Cara mempertahankan nomor versi dalam sumber / tersedia untuk aplikasi runtime
Cara mengintegrasikan dengan benar dengan repositori sumber
Cara mengelola nomor versi secara lebih otomatis vs. tag repositori
Bagaimana mengintegrasikan dengan infrastruktur pembangunan berkelanjutan
Ada cukup banyak alat yang tersedia, dan semut (sistem build yang kami gunakan) memiliki tugas yang akan mempertahankan nomor build, tetapi tidak jelas bagaimana mengelola ini dengan beberapa, pengembang bersamaan menggunakan CVS, svn, atau serupa .
[EDIT]
Beberapa jawaban parsial atau spesifik yang baik dan bermanfaat telah muncul di bawah, jadi saya akan meringkas beberapa di antaranya. Bagi saya, sepertinya tidak ada "praktik terbaik" yang kuat dalam hal ini, melainkan kumpulan ide yang tumpang tindih. Di bawah, temukan rangkuman saya dan beberapa pertanyaan yang mungkin orang coba jawab sebagai tindak lanjut. [Baru di stackoverflow ... berikan komentar jika saya melakukan ini salah.]
Jika Anda menggunakan SVN, versi checkout tertentu datang untuk perjalanan. Penomoran build dapat mengeksploitasi ini untuk membuat nomor build unik yang mengidentifikasi checkout / revisi tertentu. [CVS, yang kami gunakan untuk alasan warisan, tidak cukup memberikan tingkat wawasan ini ... intervensi manual dengan tag membuat Anda berpisah di sana.]
Jika Anda menggunakan maven sebagai sistem build Anda, ada dukungan untuk menghasilkan nomor versi dari SCM, serta modul rilis untuk secara otomatis menghasilkan rilis. [Kita tidak bisa menggunakan pakar, karena berbagai alasan, tetapi ini membantu mereka yang bisa. [Terima kasih kepada marcelo-morales ]]
Jika Anda menggunakan semut sebagai sistem build Anda, deskripsi tugas berikut ini dapat membantu menghasilkan file Java .properties yang mengambil informasi build, yang kemudian dapat dilipat ke build Anda dalam sejumlah cara. [Kami memperluas gagasan ini untuk memasukkan informasi yang diturunkan dari hudson, terima kasih marty-lamb ].
Semut dan pakar (dan hudson serta kontrol jelajah) menyediakan cara mudah untuk mendapatkan nomor build ke file .properties, atau ke file .txt / .html. Apakah ini "aman" cukup agar tidak dirusak dengan sengaja atau tidak sengaja? Apakah lebih baik mengkompilasinya menjadi kelas "versi" pada waktu pembuatan?
Pernyataan: Nomor penomoran harus didefinisikan / diberlakukan dalam sistem integrasi berkelanjutan seperti hudson . [Terima kasih kepada marcelo-morales ] Kami telah mengambil saran ini, tetapi itu membuka pertanyaan rekayasa rilis: Bagaimana rilis bisa terjadi? Apakah ada beberapa buildnumber dalam rilis? Apakah ada hubungan yang bermakna antara buildnumber dengan rilis yang berbeda?
Pertanyaan: Apa tujuan di balik angka membangun? Apakah ini digunakan untuk QA? Bagaimana? Apakah ini digunakan terutama oleh pengembang untuk disambiguasi antara beberapa build selama pengembangan, atau lebih untuk QA untuk menentukan build apa yang didapatkan pengguna akhir? Jika tujuannya adalah reproduktifitas, secara teori inilah yang harus disediakan oleh nomor versi rilis - mengapa tidak? (tolong jawab ini sebagai bagian dari jawaban Anda di bawah, ini akan membantu menerangi pilihan yang telah Anda buat / sarankan ...)
Pertanyaan: Apakah ada tempat untuk membuat angka dalam pembuatan manual? Apakah ini sangat bermasalah sehingga SEMUA ORANG harus menggunakan solusi CI?
Pertanyaan: Haruskah nomor gedung diperiksa di SCM? Jika tujuannya secara andal dan tidak ambigu mengidentifikasi bangunan tertentu, bagaimana cara mengatasi berbagai sistem pembangunan berkelanjutan atau manual yang mungkin macet / restart / dll ...
Pertanyaan: Haruskah nomor build pendek dan manis (mis., Bilangan bulat meningkat secara monoton) sehingga mudah untuk memasukkan nama file untuk arsip, mudah untuk merujuk dalam komunikasi, dll ... atau harus panjang dan penuh dengan nama pengguna, stempel data, nama mesin, dll?
Pertanyaan: Harap berikan perincian tentang bagaimana penugasan nomor build sesuai dengan proses rilis otomatis Anda yang lebih besar. Ya, pecinta maven, kita tahu ini dilakukan dan dilakukan, tetapi tidak semua dari kita sudah minum kool-bantuan ...
Saya benar-benar ingin menyempurnakan ini menjadi jawaban yang lengkap, setidaknya untuk contoh nyata dari pengaturan cvs / semut / hudson kami, sehingga seseorang dapat membangun strategi lengkap berdasarkan pertanyaan ini. Saya akan menandai sebagai "The Answer" siapa pun yang dapat memberikan deskripsi sup-ke-kacang untuk kasus khusus ini (termasuk skema penandaan cvs, item konfigurasi CI yang relevan, dan prosedur pelepasan yang melipat nomor build ke dalam rilis sedemikian rupa sehingga secara terprogram dapat diakses.) Jika Anda ingin bertanya / menjawab untuk konfigurasi tertentu lainnya (misalnya, svn / maven / cruise control) saya akan menautkan ke pertanyaan dari sini. --JA
[EDIT 23 Okt 09] Saya menerima jawaban terpilih karena saya pikir itu solusi yang masuk akal, sementara beberapa jawaban lain juga termasuk ide bagus. Jika seseorang ingin mengambil celah dalam mensintesis beberapa dari ini dengan marty-lamb 's, saya akan mempertimbangkan untuk menerima yang berbeda. Satu-satunya masalah yang saya miliki dengan marty-lamb's adalah tidak menghasilkan nomor build bersambung yang andal - tergantung pada jam lokal di sistem builder untuk memberikan angka build yang jelas, yang tidak bagus.
[Edit 10 Jul]
Kami sekarang menyertakan kelas seperti di bawah ini. Ini memungkinkan nomor versi untuk dikompilasi ke dalam executable akhir. Berbagai bentuk info versi dipancarkan dalam data logging, produk-produk keluaran jangka panjang yang diarsipkan, dan digunakan untuk melacak analisis produk-produk keluaran kami (terkadang bertahun-tahun kemudian) ke bangunan tertentu.
public final class AppVersion
{
// SVN should fill this out with the latest tag when it's checked out.
private static final String APP_SVNURL_RAW =
"$HeadURL: svn+ssh://user@host/svnroot/app/trunk/src/AppVersion.java $";
private static final String APP_SVN_REVISION_RAW = "$Revision: 325 $";
private static final Pattern SVNBRANCH_PAT =
Pattern.compile("(branches|trunk|releases)\\/([\\w\\.\\-]+)\\/.*");
private static final String APP_SVNTAIL =
APP_SVNURL_RAW.replaceFirst(".*\\/svnroot\\/app\\/", "");
private static final String APP_BRANCHTAG;
private static final String APP_BRANCHTAG_NAME;
private static final String APP_SVNREVISION =
APP_SVN_REVISION_RAW.replaceAll("\\$Revision:\\s*","").replaceAll("\\s*\\$", "");
static {
Matcher m = SVNBRANCH_PAT.matcher(APP_SVNTAIL);
if (!m.matches()) {
APP_BRANCHTAG = "[Broken SVN Info]";
APP_BRANCHTAG_NAME = "[Broken SVN Info]";
} else {
APP_BRANCHTAG = m.group(1);
if (APP_BRANCHTAG.equals("trunk")) {
// this isn't necessary in this SO example, but it
// is since we don't call it trunk in the real case
APP_BRANCHTAG_NAME = "trunk";
} else {
APP_BRANCHTAG_NAME = m.group(2);
}
}
}
public static String tagOrBranchName()
{ return APP_BRANCHTAG_NAME; }
/** Answers a formatter String descriptor for the app version.
* @return version string */
public static String longStringVersion()
{ return "app "+tagOrBranchName()+" ("+
tagOrBranchName()+", svn revision="+svnRevision()+")"; }
public static String shortStringVersion()
{ return tagOrBranchName(); }
public static String svnVersion()
{ return APP_SVNURL_RAW; }
public static String svnRevision()
{ return APP_SVNREVISION; }
public static String svnBranchId()
{ return APP_BRANCHTAG + "/" + APP_BRANCHTAG_NAME; }
public static final String banner()
{
StringBuilder sb = new StringBuilder();
sb.append("\n----------------------------------------------------------------");
sb.append("\nApplication -- ");
sb.append(longStringVersion());
sb.append("\n----------------------------------------------------------------\n");
return sb.toString();
}
}
Tinggalkan komentar jika ini layak menjadi diskusi wiki.
gradle
dan / atau git
?