Jakie są aktualne najlepsze praktyki dotyczące systematycznego numerowania kompilacji i zarządzania numerami wersji w projektach Java? Konkretnie:
Jak systematycznie zarządzać numerami kompilacji w rozproszonym środowisku programistycznym
Jak zachować numery wersji w źródle / dostępne dla aplikacji uruchomieniowej
Jak poprawnie zintegrować się z repozytorium źródeł
Jak bardziej automatycznie zarządzać numerami wersji a znacznikami repozytorium
Jak zintegrować się z infrastrukturą ciągłego budowania
Dostępnych jest wiele narzędzi, a ant (system kompilacji, którego używamy) ma zadanie, które będzie utrzymywać numer kompilacji, ale nie jest jasne, jak zarządzać tym z wieloma współbieżnymi programistami używającymi CVS, svn lub podobnych .
[EDYTOWAĆ]
Poniżej pojawiło się kilka dobrych i pomocnych odpowiedzi częściowych lub szczegółowych, więc podsumuję kilka z nich. Wydaje mi się, że nie ma w tej kwestii mocnej „najlepszej praktyki”, a raczej zbiór pokrywających się pomysłów. Poniżej znajdują się moje podsumowania i niektóre wynikające z nich pytania, na które ludzie mogą spróbować odpowiedzieć w ramach dalszych działań. [Nowość w stackoverflow… Jeśli robię to źle, podaj komentarze.]
Jeśli korzystasz z SVN, podczas jazdy pojawia się wersja konkretnego zamówienia. Numeracja kompilacji może to wykorzystać do stworzenia unikalnego numeru kompilacji, który identyfikuje konkretną kasę / wersję. [CVS, którego używamy ze starszych powodów, nie zapewnia takiego poziomu wglądu… ręczna interwencja przy użyciu tagów prowadzi do częściowego celu.]
Jeśli używasz maven jako systemu kompilacji, istnieje wsparcie dla tworzenia numeru wersji z SCM, a także moduł wydania do automatycznego tworzenia wydań. [Nie możemy używać mavena z różnych powodów, ale to pomaga tym, którzy mogą. [Podziękowania dla Marcelo-Morales ]]
Jeśli używasz ant jako systemu budowania, poniższy opis zadania może pomóc w utworzeniu pliku Java .properties przechwytującego informacje o kompilacji, które można następnie złożyć w kompilacji na wiele sposobów. [Rozszerzyliśmy ten pomysł, aby uwzględnić informacje pochodzące z hudsona , dzięki marty-lamb ].
Ant i maven (oraz hudson i cruise control) zapewniają łatwe sposoby pobierania numerów kompilacji do pliku .properties lub do pliku .txt / .html. Czy jest to wystarczająco „bezpieczne”, aby zapobiec celowej lub przypadkowej manipulacji? Czy lepiej skompilować go do klasy „wersjonowania” w czasie kompilacji?
Asercja: numeracja kompilacji powinna być zdefiniowana / uchwalona w systemie ciągłej integracji, takim jak Hudson . [Dzięki marcelo-morales ] Podjęliśmy się tej sugestii, ale otwiera ona pytanie dotyczące inżynierii wydania: Jak następuje wydanie? Czy w wydaniu jest wiele numerów kompilacji? Czy istnieje znacząca zależność między numerami kompilacji z różnych wersji?
Pytanie: Jaki jest cel numeru kompilacji? Czy jest używany do kontroli jakości? W jaki sposób? Czy jest używany głównie przez programistów do rozróżniania wielu kompilacji podczas programowania, czy też bardziej do kontroli jakości w celu ustalenia, jaką kompilację otrzymał użytkownik końcowy? Jeśli celem jest powtarzalność, teoretycznie to właśnie powinien zapewniać numer wersji wydania - dlaczego nie? (proszę odpowiedzieć na to jako część swoich odpowiedzi poniżej, pomoże to oświetlić wybory, których dokonałeś / zasugerowałeś ...)
Pytanie: Czy jest miejsce na numery kompilacji w kompilacjach ręcznych? Czy jest to tak problematyczne, że WSZYSCY powinni używać rozwiązania CI?
Pytanie: Czy numery kompilacji należy wpisywać do SCM? Jeśli celem jest niezawodne i jednoznaczne zidentyfikowanie konkretnej kompilacji, jak radzić sobie z różnymi systemami kompilacji ciągłej lub ręcznej, które mogą ulec awarii / ponownym uruchomieniu / itp.
Pytanie: Czy numer kompilacji powinien być krótki i przyjemny (tj. Monotonicznie rosnąca liczba całkowita), aby można go było łatwo umieścić w nazwach plików w celu archiwizacji, łatwo się do nich odwoływać w komunikacji itp. Lub powinien być długi i pełen nazw użytkowników, datowniki, nazwy maszyn itp.?
Pytanie: podaj szczegółowe informacje o tym, jak przypisanie numerów kompilacji pasuje do Twojego większego automatycznego procesu wydawania. Tak, kochankowie maven, wiemy, że to jest zrobione i zrobione, ale nie wszyscy z nas jeszcze wypili kool-aid ...
Naprawdę chciałbym przekształcić to w kompletną odpowiedź, przynajmniej dla konkretnego przykładu naszej konfiguracji cvs / ant / hudson, aby ktoś mógł zbudować kompletną strategię w oparciu o to pytanie. Oznaczę jako „The Answer” każdego, kto może podać opis zupy do orzechów dla tego konkretnego przypadku (w tym schemat znakowania CVS, odpowiednie elementy konfiguracji CI i procedurę wydania, która składa numer kompilacji w wydaniu tak, że jest to programowo dostępne.) Jeśli chcesz zapytać / odpowiedzieć na inną konkretną konfigurację (powiedzmy, svn / maven / cruise control), podam link do pytania tutaj. - JA
[EDYCJA 23 października 09] Przyjąłem odpowiedź, która została najwyżej oceniona, ponieważ uważam, że jest to rozsądne rozwiązanie, podczas gdy kilka innych odpowiedzi zawiera również dobre pomysły. Jeśli ktoś chce spróbować zsyntetyzować niektóre z nich z owieczkami martyrologicznymi , rozważę wybór innego. Jedynym problemem, jaki mam w przypadku marty-lamb's, jest to, że nie generuje on niezawodnie zserializowanego numeru kompilacji - zależy to od lokalnego zegara w systemie konstruktora, który zapewnia jednoznaczne numery kompilacji, co nie jest świetne.
[Edytuj 10 lipca]
Teraz dołączamy klasę taką jak poniżej. Pozwala to skompilować numery wersji do ostatecznego pliku wykonywalnego. Różne formy informacji o wersji są emitowane w danych logowania, długoterminowych zarchiwizowanych produktach wyjściowych i wykorzystywane do śledzenia naszej (czasami po latach) analizy produktów wyjściowych do określonej wersji.
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();
}
}
Zostaw komentarze, jeśli zasługuje na to, aby stać się dyskusją na wiki.
źródło
gradle
i / lubgit
?Odpowiedzi:
W przypadku kilku moich projektów przechwytuję numer wersji subversion, czas, użytkownika, który uruchomił kompilację i niektóre informacje o systemie, umieszczam je w pliku .properties, który jest dołączany do pliku jar aplikacji i czytam ten plik w czasie wykonywania.
Kod mrówki wygląda następująco:
Można to łatwo rozszerzyć, aby uwzględnić wszelkie informacje, które chcesz dodać.
źródło
Twój plik build.xml
Twój kod java
źródło
META-INF/maven/<project group>/<project id>/pom.properties
. Plik .properties będzie zawierał właściwość wersji.źródło
Oprogramowanie:
Hudson ma trzy kompilacje / zadania: ciągłe, nocne i wydanie.
W przypadku kompilacji ciągłej / nocnej: numer kompilacji to wersja SVN, znaleziona za pomocą svntask.
W przypadku kompilacji / zadania wydania: Numer kompilacji to numer wersji odczytany przez Anta z pliku Właściwości. Plik właściwości można również rozpowszechniać wraz z wydaniem w celu wyświetlania numeru kompilacji w czasie wykonywania.
Skrypt budujący Ant umieszcza numer kompilacji w pliku manifestu plików jar / war, które są tworzone podczas kompilacji. Dotyczy wszystkich kompilacji.
Czynność po kompilacji dla kompilacji wydania, którą można łatwo wykonać za pomocą wtyczki Hudson: oznacz SVN numerem kompilacji.
Korzyści:
Mam nadzieję że to pomoże.
źródło
Używam również Hudsona, chociaż scenariusz jest znacznie prostszy:
Mój skrypt Ant zawiera cel, który wygląda następująco:
Hudson ustawia dla mnie te zmienne środowiskowe za każdym razem, gdy moja praca jest wykonywana.
W moim przypadku ten projekt jest aplikacją internetową i umieszczam ten
build-number.txt
plik w folderze głównym aplikacji internetowej - nie obchodzi mnie, kto go widzi.Nie oznaczamy kontroli źródła, gdy jest to zrobione, ponieważ mamy już skonfigurowane zadanie Hudson, aby oznaczyć je numerem kompilacji / sygnaturą czasową, gdy kompilacja się powiedzie.
Moje rozwiązanie obejmuje tylko przyrostowe numery kompilacji na potrzeby programowania, nie zaszliśmy wystarczająco daleko w projekcie, w którym zajmujemy się jeszcze numerami wersji.
źródło
Możesz również rzucić okiem na wtyczkę BuildNumber Maven i zadanie Ant w jednym słoiku znalezionym pod adresem http://code.google.com/p/codebistro/wiki/BuildNumber . Starałem się, aby było to proste i nieskomplikowane. Jest to bardzo mały plik jar, który zależy tylko od zainstalowanej linii poleceń Subversion.
źródło
Oto jak to rozwiązałem:
Oto plik java przechowujący informacje o wersji:
A oto anttask „versioninfo”:
źródło
Oto moje 2 centy:
Mój skrypt kompilacji tworzy numer kompilacji (z sygnaturą czasową!) Za każdym razem, gdy buduję aplikację. Tworzy to zbyt wiele liczb, ale nigdy za mało. Jeśli mam zmianę w kodzie, numer kompilacji zmieni się przynajmniej raz.
Wersję numer kompilacji wykonuję z każdym wydaniem (choć nie pomiędzy). Kiedy aktualizuję projekt i otrzymuję nowy numer kompilacji (ponieważ ktoś inny wydał wydanie), nadpisuję moją lokalną wersję i zaczynam od nowa. Może to prowadzić do niższego numeru kompilacji, dlatego dołączyłem sygnaturę czasową.
Po wydaniu numer kompilacji jest zatwierdzany jako ostatni element w pojedynczym zatwierdzeniu z komunikatem „kompilacja 1547”. Następnie, gdy jest to oficjalne wydanie, całe drzewo jest oznaczane. W ten sposób plik kompilacji zawsze zawiera wszystkie tagi i istnieje proste mapowanie 1: 1 między tagami i numerami kompilacji.
[EDYTUJ] Wdrażam plik version.html z moimi projektami, a następnie mogę użyć skrobaka, aby po prostu zebrać dokładną mapę, która jest zainstalowana i gdzie. Jeśli używasz Tomcata lub podobnego, umieść numer kompilacji i znacznik czasu w
description
elemencie web.xml . Pamiętaj: nigdy nie zapamiętuj niczego, jeśli komputer może zrobić to za Ciebie.źródło
Uruchamiamy naszą kompilację za pośrednictwem CruiseControl (wstaw tutaj swojego ulubionego menedżera kompilacji) i wykonujemy główną kompilację i testy.
Następnie zwiększamy numer wersji za pomocą Ant i BuildNumber i tworzymy plik właściwości z tymi informacjami oraz datą kompilacji i innymi metadanymi.
Mamy klasę poświęconą czytaniu tego i dostarczaniu go do GUI / logów itp.
Następnie pakujemy to wszystko i tworzymy możliwą do wdrożenia, łączącą razem numer kompilacji i odpowiednią kompilację. Wszystkie nasze serwery zrzucają te metainformacje podczas uruchamiania. Możemy wrócić do dzienników CruiseControl i powiązać numer kompilacji z datą i zameldowaniami.
źródło