Utiliser SVN Revision pour étiqueter la construction dans CCNET
-
08-06-2019 - |
Question
J'utilise CCNET sur un exemple de projet avec SVN comme contrôle de code source.CCNET est configuré pour créer une build à chaque enregistrement.CCNET utilise MSBuild pour créer le code source.
Je souhaite utiliser le dernier numéro de révision pour générer AssemblyInfo.cs
lors de la compilation.Comment puis-je récupérer la dernière révision de Subversion et utiliser la valeur dans CCNET ?
Modifier:Je n'utilise pas NAnt - uniquement MSBuild.
La solution
CruiseControl.Net 1.4.4 dispose désormais d'un Étiqueteuse de version d'assemblage, qui génère des numéros de version compatibles avec les propriétés de l'assembly .Net.
Dans mon projet, je l'ai configuré comme :
<labeller type="assemblyVersionLabeller" incrementOnFailure="true" major="1" minor="2"/>
(Mise en garde: assemblyVersionLabeller
ne commencera pas à générer des étiquettes basées sur la révision svn jusqu'à ce qu'une véritable construction déclenchée par une validation se produise.)
puis consommez-le à partir de mes projets MSBuild avec MSBuildCommunityTasks.AssemblyInfo :
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<Target Name="BeforeBuild">
<AssemblyInfo Condition="'$(CCNetLabel)' != ''" CodeLanguage="CS" OutputFile="Properties\AssemblyInfo.cs"
AssemblyTitle="MyTitle" AssemblyCompany="MyCompany" AssemblyProduct="MyProduct"
AssemblyCopyright="Copyright © 2009" ComVisible="false" Guid="some-random-guid"
AssemblyVersion="$(CCNetLabel)" AssemblyFileVersion="$(CCNetLabel)"/>
</Target>
Par souci d'exhaustivité, c'est tout aussi simple pour les projets utilisant NAnt au lieu de MSBuild :
<target name="setversion" description="Sets the version number to CruiseControl.Net label.">
<script language="C#">
<references>
<include name="System.dll" />
</references>
<imports>
<import namespace="System.Text.RegularExpressions" />
</imports>
<code><![CDATA[
[TaskName("setversion-task")]
public class SetVersionTask : Task
{
protected override void ExecuteTask()
{
StreamReader reader = new StreamReader(Project.Properties["filename"]);
string contents = reader.ReadToEnd();
reader.Close();
string replacement = "[assembly: AssemblyVersion(\"" + Project.Properties["CCNetLabel"] + "\")]";
string newText = Regex.Replace(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", replacement);
StreamWriter writer = new StreamWriter(Project.Properties["filename"], false);
writer.Write(newText);
writer.Close();
}
}
]]>
</code>
</script>
<foreach item="File" property="filename">
<in>
<items basedir="..">
<include name="**\AssemblyInfo.cs"></include>
</items>
</in>
<do>
<setversion-task />
</do>
</foreach>
</target>
Autres conseils
Vous avez essentiellement deux options.Soit vous écrivez un script simple qui démarrera et analysera la sortie de
informations svn.exe --révision HEAD
pour obtenir le numéro de révision (la génération de AssemblyInfo.cs est alors assez simple) ou utilisez simplement le plugin pour CCNET.C'est ici:
Étiqueteur de révision SVN est un plugin pour CruiseControl.net qui vous permet de générer des étiquettes CruiseControl pour vos versions, en fonction du numéro de révision de votre copie de travail de la subversion.Cela peut être personnalisé avec un préfixe et / ou des numéros de version majeure / mineure.
Je préfère la première option car elle ne contient qu'environ 20 lignes de code :
using System;
using System.Diagnostics;
namespace SvnRevisionNumberParserSample
{
class Program
{
static void Main()
{
Process p = Process.Start(new ProcessStartInfo()
{
FileName = @"C:\Program Files\SlikSvn\bin\svn.exe", // path to your svn.exe
UseShellExecute = false,
RedirectStandardOutput = true,
Arguments = "info --revision HEAD",
WorkingDirectory = @"C:\MyProject" // path to your svn working copy
});
// command "svn.exe info --revision HEAD" will produce a few lines of output
p.WaitForExit();
// our line starts with "Revision: "
while (!p.StandardOutput.EndOfStream)
{
string line = p.StandardOutput.ReadLine();
if (line.StartsWith("Revision: "))
{
string revision = line.Substring("Revision: ".Length);
Console.WriteLine(revision); // show revision number on screen
break;
}
}
Console.Read();
}
}
}
J'ai écrit un fichier de construction NAnt qui gère l'analyse des informations SVN et la création de propriétés.J'utilise ensuite ces valeurs de propriété pour diverses tâches de construction, notamment la définition de l'étiquette sur la construction.J'utilise cette cible combinée avec le SVN Revision Labeller mentionné par Lubos Hasko avec d'excellents résultats.
<target name="svninfo" description="get the svn checkout information">
<property name="svn.infotempfile" value="${build.directory}\svninfo.txt" />
<exec program="${svn.executable}" output="${svn.infotempfile}">
<arg value="info" />
</exec>
<loadfile file="${svn.infotempfile}" property="svn.info" />
<delete file="${svn.infotempfile}" />
<property name="match" value="" />
<regex pattern="URL: (?'match'.*)" input="${svn.info}" />
<property name="svn.info.url" value="${match}"/>
<regex pattern="Repository Root: (?'match'.*)" input="${svn.info}" />
<property name="svn.info.repositoryroot" value="${match}"/>
<regex pattern="Revision: (?'match'\d+)" input="${svn.info}" />
<property name="svn.info.revision" value="${match}"/>
<regex pattern="Last Changed Author: (?'match'\w+)" input="${svn.info}" />
<property name="svn.info.lastchangedauthor" value="${match}"/>
<echo message="URL: ${svn.info.url}" />
<echo message="Repository Root: ${svn.info.repositoryroot}" />
<echo message="Revision: ${svn.info.revision}" />
<echo message="Last Changed Author: ${svn.info.lastchangedauthor}" />
</target>
j'ai trouvé ce projet sur le code Google.C'est CCNET
plugin pour générer l'étiquette dans CCNET
.
Le DLL
est testé avec CCNET 1.3
mais ça marche avec CCNET 1.4
pour moi.J'utilise avec succès ce plugin pour étiqueter ma build.
Passons maintenant à le transmettre à MSBuild
...
Si vous préférez le faire sur MSBuild
côté sur le CCNet
config, ressemble au MSBuild
Extension des tâches communautaires SvnVersion
la tâche pourrait faire l’affaire.
Je suis actuellement en train de le faire "manuellement" via une tâche d'exécution préalable, en utilisant mon cmdnetsvnrev outil, mais si quelqu'un connaît une meilleure façon de le faire intégrée à ccnet, je serais heureux de l'entendre :-)
Personnalisation des fichiers csproj pour générer automatiquement AssemblyInfo.cs
http://www.codeproject.com/KB/dotnet/Customizing_csproj_files.aspxChaque fois que nous créons un nouveau projet C #, Visual Studio y met le fichier assemblyinfo.cs pour nous.Le fichier définit les méta-données d'assemblage comme sa version, sa configuration ou son producteur.
J'ai trouvé la technique ci-dessus pour générer automatiquement AssemblyInfo.cs à l'aide de MSBuild.Je publierai un échantillon sous peu.
Je ne sais pas si cela fonctionne avec CCNET ou non, mais j'ai créé un Plug-in version SVN pour le Incrément de version de construction projet sur CodePlex.Cet outil est assez flexible et peut être configuré pour créer automatiquement un numéro de version pour vous à l'aide de la révision svn.Cela ne nécessite pas d'écrire de code ni de modifier du XML, alors oui !
J'espère que cela aide!
Mon approche consiste à utiliser le plugin susmentionné pour ccnet et une tâche d'écho nant pour générer un VersionInfo.cs
fichier ne contenant rien d'autre que les attributs de version.Je dois seulement inclure le VersionInfo.cs
déposer dans la build
La tâche echo génère simplement la chaîne que je lui donne dans un fichier.
S'il existe une tâche MSBuild similaire, vous pouvez utiliser la même approche.Voici la petite tâche nant que j'utilise :
<target name="version" description="outputs version number to VersionInfo.cs">
<echo file="${projectdir}/Properties/VersionInfo.cs">
[assembly: System.Reflection.AssemblyVersion("$(CCNetLabel)")]
[assembly: System.Reflection.AssemblyFileVersion("$(CCNetLabel)")]
</echo>
</target>
Essaye ça:
<ItemGroup>
<VersionInfoFile Include="VersionInfo.cs"/>
<VersionAttributes>
[assembly: System.Reflection.AssemblyVersion("${CCNetLabel}")]
[assembly: System.Reflection.AssemblyFileVersion("${CCNetLabel}")]
</VersionAttributes>
</ItemGroup>
<Target Name="WriteToFile">
<WriteLinesToFile
File="@(VersionInfoFile)"
Lines="@(VersionAttributes)"
Overwrite="true"/>
</Target>
Veuillez noter que je ne suis pas très familier avec MSBuild, donc mon script ne fonctionnera probablement pas immédiatement et nécessitera des corrections...
Sur la base de la solution skolimas, j'ai mis à jour le script NAnt pour mettre également à jour AssemblyFileVersion.Merci à skolima pour le code !
<target name="setversion" description="Sets the version number to current label.">
<script language="C#">
<references>
<include name="System.dll" />
</references>
<imports>
<import namespace="System.Text.RegularExpressions" />
</imports>
<code><![CDATA[
[TaskName("setversion-task")]
public class SetVersionTask : Task
{
protected override void ExecuteTask()
{
StreamReader reader = new StreamReader(Project.Properties["filename"]);
string contents = reader.ReadToEnd();
reader.Close();
// replace assembly version
string replacement = "[assembly: AssemblyVersion(\"" + Project.Properties["label"] + "\")]";
contents = Regex.Replace(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", replacement);
// replace assembly file version
replacement = "[assembly: AssemblyFileVersion(\"" + Project.Properties["label"] + "\")]";
contents = Regex.Replace(contents, @"\[assembly: AssemblyFileVersion\("".*""\)\]", replacement);
StreamWriter writer = new StreamWriter(Project.Properties["filename"], false);
writer.Write(contents);
writer.Close();
}
}
]]>
</code>
</script>
<foreach item="File" property="filename">
<in>
<items basedir="${srcDir}">
<include name="**\AssemblyInfo.cs"></include>
</items>
</in>
<do>
<setversion-task />
</do>
</foreach>
</target>
Aucune idée d'où j'ai trouvé ça.Mais j'ai trouvé ça sur Internet "quelque part".
Cela met à jour tous les fichiers AssemblyInfo.cs avant la construction.
Fonctionne à merveille.Tous mes exe et dll s'affichent comme 1.2.3.333 (si "333" était la révision SVN à l'époque.) (Et la version originale dans le fichier AssemblyInfo.cs était répertoriée comme "1.2.3.0")
$(ProjectDir) (Où réside mon fichier .sln)
$(SVNToolPath) (pointe vers svn.exe)
sont mes variables personnalisées, leurs déclarations/définitions ne sont pas définies ci-dessous.
http://msbuildtasks.tigris.org/et/ouhttps://github.com/loresoft/msbuildtasksa les tâches ( FileUpdate et SvnVersion ).
<Target Name="SubVersionBeforeBuildVersionTagItUp">
<ItemGroup>
<AssemblyInfoFiles Include="$(ProjectDir)\**\*AssemblyInfo.cs" />
</ItemGroup>
<SvnVersion LocalPath="$(MSBuildProjectDirectory)" ToolPath="$(SVNToolPath)">
<Output TaskParameter="Revision" PropertyName="MySubVersionRevision" />
</SvnVersion>
<FileUpdate Files="@(AssemblyInfoFiles)"
Regex="(\d+)\.(\d+)\.(\d+)\.(\d+)"
ReplacementText="$1.$2.$3.$(MySubVersionRevision)" />
</Target>
MODIFIER ------------------------------------------------- -
Ce qui précède peut commencer à échouer une fois que votre numéro de révision SVN atteint 65534 ou supérieur.
Voir:
Désactiver l'avertissement CS1607
Voici la solution de contournement.
<FileUpdate Files="@(AssemblyInfoFiles)"
Regex="AssemblyFileVersion\("(\d+)\.(\d+)\.(\d+)\.(\d+)"
ReplacementText="AssemblyFileVersion("$1.$2.$3.$(SubVersionRevision)" />
Le résultat devrait être :
Dans Windows/Explorateur//Fichier/Propriétés…….
La version d'assemblage sera 1.0.0.0.
La version du fichier sera 1.0.0.333 si 333 est la révision SVN.
Sois prudent.La structure utilisée pour les numéros de build n'est que courte, vous avez donc un plafond sur la hauteur que peut atteindre votre révision.
Dans notre cas, nous avons déjà dépassé la limite.
Si vous essayez de saisir le numéro de build 99.99.99.599999, la propriété de version du fichier sera en réalité 99.99.99.10175.