Quelles sont les meilleures pratiques actuelles pour la numérotation systématique des builds et la gestion des numéros de version dans les projets Java? Plus précisément:
Comment gérer systématiquement les numéros de build dans un environnement de développement distribué
Comment gérer les numéros de version dans la source / disponibles pour l'application d'exécution
Comment s'intégrer correctement au référentiel source
Comment gérer plus automatiquement les numéros de version par rapport aux balises de référentiel
Comment s'intégrer à une infrastructure de construction continue
Il existe un certain nombre d'outils disponibles, et ant (le système de construction que nous utilisons) a une tâche qui maintiendra un numéro de version, mais on ne sait pas comment gérer cela avec plusieurs développeurs simultanés utilisant CVS, svn ou similaire. .
[ÉDITER]
Plusieurs bonnes et utiles réponses partielles ou spécifiques sont apparues ci-dessous, je vais donc en résumer quelques-unes. Il me semble qu'il n'y a pas vraiment de «bonnes pratiques» solides à ce sujet, mais plutôt une collection d'idées qui se chevauchent. Ci-dessous, retrouvez mes résumés et quelques questions qui en découlent auxquelles les gens pourraient essayer de répondre en guise de suivi. [Nouveau dans stackoverflow ... veuillez fournir des commentaires si je fais cela mal.]
Si vous utilisez SVN, la gestion des versions d'une extraction spécifique est fournie pour le trajet. La numérotation de build peut exploiter cela pour créer un numéro de build unique qui identifie l'extraction / révision spécifique. [CVS, que nous utilisons pour des raisons héritées, ne fournit pas tout à fait ce niveau de perspicacité ... une intervention manuelle avec des balises vous permet d'y arriver.]
Si vous utilisez maven comme système de construction, il existe un support pour la production d'un numéro de version à partir du SCM, ainsi qu'un module de publication pour produire automatiquement des versions. [Nous ne pouvons pas utiliser maven, pour diverses raisons, mais cela aide ceux qui le peuvent. [Merci à marcelo-morales ]]
Si vous utilisez ant comme système de construction, la description de tâche suivante peut vous aider à produire un fichier Java .properties capturant les informations de construction, qui peuvent ensuite être intégrées à votre construction de différentes manières. [Nous avons développé cette idée pour inclure des informations dérivées de Hudson , merci marty-lamb ].
Ant et maven (et hudson et régulateur de vitesse) fournissent des moyens simples pour obtenir des numéros de build dans un fichier .properties, ou dans un fichier .txt / .html. Est-ce suffisamment «sûr» pour l'empêcher d'être falsifié intentionnellement ou accidentellement? Est-il préférable de le compiler dans une classe de «gestion des versions» au moment de la construction?
Assertion: la numérotation des builds doit être définie / mise en œuvre dans un système d'intégration continue comme hudson . [Merci à marcelo-morales ] Nous avons pris cette suggestion, mais cela permet d'ouvrir la question de l'ingénierie de publication: comment une publication se produit-elle? Existe-t-il plusieurs numéros de build dans une version? Existe-t-il une relation significative entre les numéros de build de différentes versions?
Question: Quel est l'objectif derrière un numéro de build? Est-il utilisé pour l'assurance qualité? Comment? Est-il principalement utilisé par les développeurs pour lever l'ambiguïté entre plusieurs builds pendant le développement, ou plus pour le contrôle qualité afin de déterminer quelle build un utilisateur final a? Si l'objectif est la reproductibilité, c'est en théorie ce que devrait fournir un numéro de version - pourquoi pas? (veuillez répondre à cela dans le cadre de vos réponses ci-dessous, cela aidera à éclairer les choix que vous avez faits / suggérés ...)
Question: Y a-t-il une place pour les numéros de build dans les builds manuels? Est-ce si problématique que TOUT LE MONDE devrait utiliser une solution CI?
Question: Les numéros de build doivent-ils être enregistrés dans le SCM? Si l'objectif est d'identifier de manière fiable et sans ambiguïté une construction particulière, comment faire face à une variété de systèmes de construction continue ou manuelle qui peuvent planter / redémarrer / etc ...
Question: Si un numéro de build doit être court et doux (c'est-à-dire, un nombre entier croissant de manière monotone) afin qu'il soit facile de s'en tenir aux noms de fichiers pour l'archivage, de s'y référer facilement dans la communication, etc ... ou devrait-il être long et plein de noms d'utilisateur, horodatages, noms de machines, etc.?
Question: Veuillez fournir des détails sur la manière dont l'attribution des numéros de build s'intègre dans votre processus de publication automatisé plus large. Oui, amateurs de maven, nous savons que c'est fait et fait, mais nous n'avons pas tous encore bu le kool-aid ...
Je voudrais vraiment donner une réponse complète, au moins pour l'exemple concret de notre configuration cvs / ant / hudson, afin que quelqu'un puisse construire une stratégie complète basée sur cette question. Je marquerai comme "La réponse" toute personne qui peut donner une description de la soupe aux noix pour ce cas particulier (y compris le schéma de balisage cvs, les éléments de configuration CI pertinents et la procédure de publication qui replie le numéro de build dans la version de sorte qu'il soit programmé accessible.) Si vous voulez demander / répondre pour une autre configuration particulière (par exemple, svn / maven / régulateur de vitesse), je vais créer un lien vers la question à partir d'ici. --JA
[EDIT 23 octobre 09] J'ai accepté la réponse la plus votée parce que je pense que c'est une solution raisonnable, alors que plusieurs des autres réponses incluent également de bonnes idées. Si quelqu'un veut essayer de synthétiser certains d'entre eux avec des marty-lambs, j'envisagerai d'en accepter un autre. Le seul souci que j'ai avec marty-lamb's est qu'il ne produit pas de numéro de build sérialisé de manière fiable - cela dépend d'une horloge locale du système du constructeur pour fournir des numéros de build sans ambiguïté, ce qui n'est pas génial.
[Modifier le 10 juillet]
Nous incluons maintenant une classe comme ci-dessous. Cela permet aux numéros de version d'être compilés dans l'exécutable final. Différentes formes d'informations de version sont émises dans les données de journalisation, les produits de sortie archivés à long terme et utilisées pour retracer notre analyse (parfois des années plus tard) des produits de sortie jusqu'à une version spécifique.
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();
}
}
Laissez des commentaires si cela mérite de devenir une discussion wiki.
la source
gradle
et / ougit
?Réponses:
Pour plusieurs de mes projets, je capture le numéro de révision de subversion, l'heure, l'utilisateur qui a exécuté la construction et certaines informations système, je les remplis dans un fichier .properties qui est inclus dans le fichier jar de l'application, et je lis ce fichier au moment de l'exécution.
Le code de la fourmi ressemble à ceci:
Il est simple d'étendre cela pour inclure toutes les informations que vous souhaitez ajouter.
la source
Votre build.xml
Votre code java
la source
META-INF/maven/<project group>/<project id>/pom.properties
. Le fichier .properties contiendra la propriété version.la source
Logiciel:
Hudson a trois builds / jobs: Continuous, Nightly et Release.
Pour une build Continuous / Nightly: le numéro de build est la révision SVN, trouvée en utilisant svntask.
Pour une version / un travail de version: le numéro de version est le numéro de version, lu par Ant, à partir d'un fichier de propriétés. Le fichier de propriétés peut également être distribué avec la version pour afficher le numéro de build au moment de l'exécution.
Le script de build Ant place le numéro de build dans le fichier manifeste des fichiers jar / war créés lors de la build. S'applique à toutes les versions.
Action post-build pour les builds Release, réalisée facilement à l'aide d'un plug-in Hudson: balisez SVN avec le numéro de build.
Avantages:
J'espère que cela t'aides.
la source
J'utilise également Hudson, bien que dans un scénario beaucoup plus simple:
Mon script Ant contient une cible qui ressemble à:
Hudson définit ces variables d'environnement pour moi chaque fois que mon travail s'exécute.
Dans mon cas, ce projet est une application Web et j'inclus ce
build-number.txt
fichier dans le dossier racine de l'application Web - je me fiche de savoir qui le voit.Nous ne marquons pas le contrôle de source lorsque cela est fait, car nous avons déjà configuré notre travail Hudson pour le marquer avec le numéro de build / l'horodatage lorsque la construction est réussie.
Ma solution ne couvre que les numéros de build incrémentiels pour le développement, nous ne sommes pas allés assez loin dans le projet où nous couvrons encore les numéros de version.
la source
Vous pouvez également jeter un œil au plugin BuildNumber Maven et à la tâche Ant dans un fichier jar disponible à l' adresse http://code.google.com/p/codebistro/wiki/BuildNumber . J'ai essayé de le rendre simple et direct. C'est un très petit fichier jar qui ne dépend que de la ligne de commande installée par Subversion.
la source
Voici comment j'ai résolu ceci:
Voici le fichier java stockant les informations de version:
Et voici l'anttask "versioninfo":
la source
Voici mes 2 cents:
Mon script de build crée un numéro de build (avec horodatage!) À chaque fois que je crée l'application. Cela crée trop de nombres mais jamais trop peu. Si j'ai un changement dans le code, le numéro de build changera au moins une fois.
Je version le numéro de version avec chaque version (mais pas entre les deux). Lorsque je mets à jour le projet et que j'obtiens un nouveau numéro de version (parce que quelqu'un d'autre a publié une version), j'écrase ma version locale et je recommence. Cela peut conduire à un numéro de build inférieur, c'est pourquoi j'ai inclus l'horodatage.
Lorsqu'une version se produit, le numéro de build est validé comme dernier élément d'une seule validation avec le message "build 1547". Après cela, lorsqu'il s'agit d'une version officielle, l'arbre entier est étiqueté. De cette façon, le fichier de construction a toujours toutes les balises et il existe un simple mappage 1: 1 entre les balises et les numéros de build.
[EDIT] Je déploie une version.html avec mes projets et ensuite, je peux utiliser un grattoir pour simplement collecter une carte précise ce qui est installé où. Si vous utilisez Tomcat ou similaire, placez le numéro de build et l'horodatage dans l'
description
élément de web.xml . N'oubliez pas: ne mémorisez jamais rien lorsque vous pouvez demander à un ordinateur de le faire pour vous.la source
Nous exécutons notre build via CruiseControl (insérez votre gestionnaire de build préféré ici), et effectuons le build principal et les tests.
Nous incrémentons ensuite le numéro de version à l'aide de Ant et BuildNumber et créons un fichier de propriétés avec ces informations plus la date de construction et d'autres métadonnées.
Nous avons une classe dédiée à la lecture et à la fourniture aux interfaces graphiques / journaux, etc.
Nous emballons ensuite tout cela et construisons un déployable liant le numéro de build et la build correspondante. Tous nos serveurs vident ces méta-informations au démarrage. Nous pouvons parcourir les journaux CruiseControl et lier le numéro de build à la date et aux enregistrements.
la source