Используйте версию SVN для маркировки сборки в CCNET

Я использую CCNET в образце проекта с SVN в качестве системы управления версиями. CCNET настроен на создание сборки при каждой регистрации. CCNET использует MSBuild для сборки исходного кода.

Я хотел бы использовать номер последней версии для генерации AssemblyInfo.cs во время компиляции. Как я могу получить последнюю версию из Subversion и использовать значение в CCNET?

Изменить: я не использую NAnt - только MSBuild.


person hitec    schedule 04.08.2008    source источник


Ответы (12)


CruiseControl.Net 1.4.4 теперь имеет Маркировщик версии сборки, который генерирует номера версий, совместимые со свойствами сборки .Net.

В моем проекте он настроен как:

<labeller type="assemblyVersionLabeller" incrementOnFailure="true" major="1" minor="2"/>

(Предостережение: assemblyVersionLabeller не начнет генерировать метки на основе ревизий svn до тех пор, пока не произойдет сборка, запускаемая фиксацией.)

а затем использовать это из моих проектов MSBuild с помощью 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>

Для полноты картины это так же просто для проектов, использующих NAnt вместо 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>
person skolima    schedule 10.06.2009
comment
+1 Замечательно, мне это очень помогло. Я обновил вашу версию для NAnt, чтобы также обновить AssemblyFileVersion и некоторые мелочи. Он включен в качестве еще одного ответа здесь, в этой теме. Спасибо! - person galaktor; 12.09.2009
comment
Другие не должны сбрасывать со счетов эту оговорку; это очень важно. В результате в сети появляется множество ответов о том, что это не работает. По-прежнему кажется ошибочным, но запускайте это после проверки один раз, и после этого все работает так, как ожидалось. -- Огромное спасибо - person Chuck; 10.05.2012
comment
Ссылка на этикетировщик версии сборки не работает. - person stephen; 29.10.2015

У вас есть два основных варианта. Либо вы пишете простой скрипт, который будет запускать и анализировать вывод из

svn.exe info --revision HEAD

чтобы получить номер версии (тогда создание AssemblyInfo.cs довольно просто) или просто используйте плагин для CCNET. Вот:

SVN Revision Labeller - это плагин для CruiseControl.NET, который позволяет вам создавать ярлыки CruiseControl для ваших сборок на основе номера версии вашей рабочей копии Subversion. Это можно настроить с помощью префикса и / или основных / дополнительных номеров версии.

http://code.google.com/p/svnrevisionlabeller/

Я предпочитаю первый вариант, потому что это всего около 20 строк кода:

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();
        }
    }
}
person lubos hasko    schedule 04.08.2008

Я написал файл сборки NAnt, который обрабатывает информацию SVN и создает свойства. Затем я использую эти значения свойств для множества задач сборки, включая установку метки на сборке. Я использую эту цель в сочетании с SVN Revision Labeller, упомянутым lubos hasko, с отличными результатами.

<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>
person Justin Walgran    schedule 04.08.2008

Я нашел этот проект в коде Google. Это CCNET плагин для создания метки в CCNET.

DLL протестирован с CCNET 1.3, но у меня он работает с CCNET 1.4. Я успешно использую этот плагин для маркировки своей сборки.

Теперь перейдем к _6 _...

person hitec    schedule 04.08.2008

Если вы предпочитаете делать это на стороне MSBuild, а не CCNet config, это выглядит как задача SvnVersion расширения MSBuild Community Tasks может сделать свое дело.

person Rytmis    schedule 04.08.2008

В настоящее время я делаю это «вручную» с помощью задачи prebuild-exec, используя мои cmdnetsvnrev, но если кто-то знает способ сделать это лучше, интегрированный в ccnet, я был бы рад услышать :-)

person Michael Stum    schedule 04.08.2008

Настройка файлов csproj для автоматического создания AssemblyInfo.cs
http://www.codeproject.com/KB/dotnet/Customizing_csproj_files.aspx

Каждый раз, когда мы создаем новый проект C #, Visual Studio помещает туда файл AssemblyInfo.cs. Файл определяет метаданные сборки, такие как ее версия, конфигурация или производитель.

Обнаружил описанный выше метод автоматического создания AssemblyInfo.cs с помощью MSBuild. Вскоре отправлю образец.

person hitec    schedule 04.08.2008

Я не уверен, работает ли это с CCNET или нет, но я создал подключаемый модуль версии для версии SVN для проекта Build Version Increment на CodePlex. Этот инструмент довольно гибкий и может быть настроен на автоматическое создание номера версии для вас с помощью ревизии svn. Это не требует написания кода или редактирования xml, так что ура!

Надеюсь, это поможет!

person grimus    schedule 12.04.2010

Мой подход состоит в том, чтобы использовать вышеупомянутый плагин для ccnet и задачу nant echo для создания файла VersionInfo.cs, не содержащего ничего, кроме атрибутов версии. Мне нужно только включить VersionInfo.cs файл в сборку

Задача эха просто выводит строку, которую я передаю в файл.

Если есть похожая задача MSBuild, вы можете использовать тот же подход. Вот небольшая задача, которую я использую:

<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>

Попробуй это:

<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>

Обратите внимание, что я не очень близок с MSBuild, поэтому мой скрипт, вероятно, не будет работать из коробки и потребует исправлений ...

person R. Martinho Fernandes    schedule 03.02.2009

На основе решения skolimas я обновил скрипт NAnt, чтобы также обновить AssemblyFileVersion. Спасибо skolima за код!

<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>
person galaktor    schedule 12.09.2009

Не знаю, где я это нашел. Но я нашел это в Интернете "где-то".

Это обновит все файлы AssemblyInfo.cs перед сборкой.

Работает как шарм. Все мои exe и dll отображаются как 1.2.3.333 (если в то время SVN-версия была «333».) (А исходная версия в файле AssemblyInfo.cs была указана как «1.2.3.0»)


$ (ProjectDir) (Где находится мой файл .sln)

$ (SVNToolPath) (указывает на svn.exe)

являются моими пользовательскими переменными, их объявления / определения ниже не определены.


http://msbuildtasks.tigris.org/ и / или https://github.com/loresoft/msbuildtasks содержит задачи (FileUpdate и 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>

РЕДАКТИРОВАТЬ ------------------------------------------------- -

Вышеупомянутое может перестать работать после того, как ваш номер версии SVN достигнет 65534 или выше.

Видеть:

Отключить предупреждение CS1607

Вот обходной путь.

<FileUpdate Files="@(AssemblyInfoFiles)"
Regex="AssemblyFileVersion\(&quot;(\d+)\.(\d+)\.(\d+)\.(\d+)"
ReplacementText="AssemblyFileVersion(&quot;$1.$2.$3.$(SubVersionRevision)" />

Результатом этого должно быть:

В Windows / Проводнике // Файл / Свойства …….

Версия сборки будет 1.0.0.0.

Версия файла будет 1.0.0.333, если 333 - это версия SVN.

person granadaCoder    schedule 18.09.2012
comment
Думаю, я нашел исходное место, где нашел: geekswithblogs.net/mnf/archive/2009/07/03/ - person granadaCoder; 10.10.2012

Будь осторожен. Структура, используемая для номеров сборки, очень короткая, поэтому у вас есть предел того, насколько высока ваша ревизия.

В нашем случае мы уже превысили лимит.

Если вы попытаетесь ввести номер сборки 99.99.99.599999, свойство версии файла фактически выйдет как 99.99.99.10175.

person Dan    schedule 03.02.2009
comment
это не тот случай, когда System.Version указывает .Revision, который является int32, и поэтому вы можете прочитать это, а не Minor и Major, которые представляют собой замаскированное преобразование Int32 в short. - person krystan honour; 16.03.2010