Java projelerinde sistematik yapı numaralandırma ve sürüm numarası yönetimi için mevcut en iyi uygulamalar nelerdir? özellikle:
Dağıtılmış geliştirme ortamında yapı sayılarını sistematik olarak yönetme
Sürüm numaralarını kaynakta tutma / çalışma zamanı uygulaması için kullanılabilir
Kaynak havuzla düzgün bir şekilde nasıl entegre edilir
Sürüm numaralarının depo etiketlerine karşı daha otomatik olarak yönetilmesi
Sürekli yapı altyapısı ile entegrasyon
Oldukça fazla sayıda araç var ve karınca (kullandığımız inşa sistemi) bir inşa numarasını koruyacak bir göreve sahip, ancak CVS, svn veya benzeri kullanan birden çok, eşzamanlı geliştirici ile bunun nasıl yönetileceği açık değil .
[DÜZENLE]
Aşağıda birkaç iyi ve yararlı kısmi veya özel cevap ortaya çıktı, bu yüzden birkaçını özetleyeceğim. Bana öyle geliyor ki, bu konuda gerçekten güçlü bir “en iyi uygulama” değil, örtüşen fikirlerin bir koleksiyonu. Aşağıda, özetlerimi ve insanların takip olarak cevaplamaya çalışabilecekleri bazı soruları bulabilirsiniz. [Stackoverflow'da yeni… Bunu yanlış yapıyorsam lütfen yorum sağlayın.]
SVN kullanıyorsanız, sürüş için belirli bir kasanın sürümlendirilmesi gelir. Yapı numaralandırması, belirli bir ödeme / revizyonu tanımlayan benzersiz bir yapı numarası oluşturmak için bundan yararlanabilir. [Eski nedenlerden dolayı kullandığımız CVS, bu düzeyde bir içgörü sağlamaz ... etiketlere manuel müdahale sizi oraya kısmen götürür.]
Oluşturma sisteminiz olarak maven kullanıyorsanız, SCM'den bir sürüm numarası üretmenin yanı sıra otomatik olarak sürümleri üretmek için bir serbest bırakma modülü de vardır. [Biz maven'i çeşitli nedenlerle kullanamayız, ancak bu yapabileceklerine yardımcı olur. [ Marcelo-morales sayesinde ]]
Derleme sisteminiz olarak karınca kullanıyorsanız , aşağıdaki görev açıklaması derleme bilgilerini yakalayan bir Java .properties dosyası oluşturmanıza yardımcı olabilir, bu da derlemenize birkaç şekilde katlanabilir. [Bu fikri hudson kaynaklı bilgileri içerecek şekilde genişlettik, teşekkürler şehit-kuzu ].
Ant ve maven (ve hudson ve cruise control) yapı numaralarını bir .properties dosyasına veya .txt / .html dosyasına almak için kolay araçlar sağlar. Bu, kasıtlı olarak veya yanlışlıkla değiştirilmesini önleyecek kadar "güvenli" midir? Oluşturma zamanında bir "sürüm oluşturma" sınıfında derlemek daha mı iyi?
Onaylama: Yapı numaralandırması, hudson gibi sürekli bir entegrasyon sisteminde tanımlanmalı / yürürlüğe konmalıdır . [ Marcelo-morales sayesinde ] Bu öneriyi aldık, ancak sürüm mühendisliği sorusunu açıyor: Bir sürüm nasıl oluyor? Bir sürümde birden fazla yapı numarası var mı? Farklı sürümlerden yapı oluşturucuları arasında anlamlı bir ilişki var mı?
Soru: Yapı numarasının ardındaki amaç nedir? KG için kullanılıyor mu? Nasıl? Öncelikle geliştiriciler tarafından geliştirme sırasında birden çok yapı arasında ayrım yapmak için mi yoksa bir QA için son kullanıcının hangi yapının varlığını belirlemek için daha fazla mı kullanılır? Hedef tekrarlanabilirlik ise, teorik olarak bir sürüm sürüm numarası budur - neden olmasın? (lütfen aşağıdaki cevaplarınızın bir parçası olarak cevaplayın, yaptığınız / önerdiğiniz seçimlerin aydınlatılmasına yardımcı olacaktır ...)
Soru: Manuel yapılarda yapı numaraları için bir yer var mı? Bu HERKES'in bir CI çözümü kullanması gerektiği kadar sorunlu mu?
Soru: Yapı numaraları SCM'de kontrol edilmeli mi? Hedef, belirli bir yapıyı güvenilir ve açık bir şekilde tanımlamaksa, çökme / yeniden başlatma / vb.Gibi çeşitli sürekli veya manuel oluşturma sistemleriyle nasıl başa çıkılacağı ...
Soru: Bir yapı numarası kısa ve tatlı olmalı (yani, monoton olarak artan tamsayı), böylece arşiv için dosya adlarına kolayca yapışabilir, iletişimde referans verilebilir, vb ... veya uzun ve kullanıcı adlarıyla dolu olmalıdır tarih damgaları, makine adları, vb?
Soru: Lütfen yapı numaralarının atanmasının daha büyük otomatik yayınlama işleminize nasıl uyduğuyla ilgili ayrıntıları sağlayın. Evet, maven severler, bunun yapıldığını ve yapıldığını biliyoruz, ancak hepimiz kool yardımını henüz sarmadık ...
Bunu en azından cvs / ant / hudson kurulumumuzun somut örneği için tam bir cevaba dönüştürmek istiyorum, böylece birisi bu soruya dayanarak tam bir strateji oluşturabilir. Bu özel durum için çorba-fındık açıklaması verebilen herkes "Cevap" olarak işaretleyeceğim (cvs etiketleme şeması, ilgili CI yapılandırma öğeleri ve sürüm numarasını sürüm olarak programa katlanacak şekilde sürüme katlayan sürüm yordamı Başka bir belirli yapılandırma istemek / yanıtlamak istiyorsanız (örneğin, svn / maven / cruise control) soruyu buradan bağlayacağım. --JA
[EDIT 23 Eki 09] En çok oy alan yanıtı kabul ediyorum, çünkü bunun makul bir çözüm olduğunu düşünüyorum, diğer cevapların bazıları da iyi fikirler içeriyor. Birisi bunlardan bazılarını şehit kuzu ile sentezlemek için bir çatlak almak istiyorsa , farklı bir tane kabul etmeyi düşüneceğim. Şehit kuzu ile ilgili tek endişe, güvenilir bir şekilde seri hale getirilmiş bir yapı numarası üretmemesidir - büyük olmayan açık yapı numaraları sağlamak için inşaatçının sistemindeki yerel bir saate bağlıdır.
[10 Temmuz'u Düzenle]
Şimdi aşağıdaki gibi bir sınıf ekliyoruz. Bu, sürüm numaralarının son yürütülebilir dosyada derlenmesini sağlar. Günlüğe kaydetme verilerinde, uzun vadeli arşivlenmiş çıktı ürünlerinde farklı sürüm bilgisi formları yayınlanır ve çıktı ürünlerinin (bazen yıllar sonra) analizini belirli bir yapıya izlemek için kullanılır.
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();
}
}
Bu bir wiki tartışması olmayı hak ediyorsa yorum bırakın.
gradle
Ve / veya kullanırken benzer yaklaşımlar olup olmadığını merak ediyorum git
?