Автоматическое ведение версий в Visual Studio 2017 (.NET Core)

Я потратил большую часть нескольких часов, пытаясь найти способ автоинкрементных версий в .NETCoreApp 1.1 (Visual Studio 2017).

Я знаю, что AssemblyInfo.cs создается динамически в папке: obj/Debug/netcoreapp1.1/

Он не принимает старый метод: [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.*")]

Если я устанавливаю проект в пакет, я могу установить версии там, но это, похоже, используется для сборки файла AssemblyInfo.cs.

Мой вопрос: кто-нибудь понял, как управлять версией в .NET Core (или .NETStandard в этом отношении).

Я искал инкремент версии для приложения Net Core в VS2017, используя формат конфигурации csproj.

Я нашел проект под названием dotnet bump, который работал в формате project.json, но изо всех сил пытался найти решение для формата .csproj. Писатель – это то, что dotnet bump действительно придумал решение для формата .csproj и называется MSBump.

Для GitHub есть проект для:

https://github.com/BalassaMarton/MSBump

где вы можете увидеть код и его ansible на Nuget тоже. Просто найдите MSBump на Nuget.

Если вы используете Visual Studio Team Services / TFS или какой-либо другой процесс сборки CI, чтобы иметь встроенное управление версиями, вы можете использовать атрибут Condition msbuild, например:

   0.0.1-local $(BUILD_BUILDNUMBER) netcoreapp1.1           

Это скажет компилятору .NET Core использовать все, что есть в BUILD_BUILDNUMBER среды BUILD_BUILDNUMBER если оно присутствует, или вернуться к 0.0.1-local если вы делаете сборку на своей локальной машине.

Добавить False в .csproj

Обходной путь для работы AssemblyVersion * описан в «Confusing сообщении об ошибке для шаблона в [AssemblyVersion] на .Net Core # 22660″

Подстановочные знаки разрешены только в том случае, если assembly не является детерминированной, что является стандартом для проектов .Net Core. Добавление False в csproj устраняет проблему.

Причины, по которым .Net Core Developers считают, что детерминированные сборки полезны, описанные в http://blog.paranoidcoding.com/2016/04/05/deterministic-builds-in-roslyn.html, а компиляторы должны быть детерминированными: одни и те же входы генерируют одинаковые результаты # 372

Однако, если вы используете TeamCity, TFS или другой инструмент CI / CD, вероятно, лучше сохранить номер версии, контролируемый и увеличенный ими, и перейти к созданию в качестве параметра (как это было предложено в других ответах), например

 msbuild /t:build /p:Version=YourVersionNumber /p:AssemblyVersion=YourVersionNumber 

Номер пакета для пакетов NuGet

 msbuild /t:pack /p:Version=YourVersionNumber 

Я придумал решение, которое работало почти так же, как старый атрибут AssemblyVersion со звездочкой (*) – AssemblyVersion («1.0. ») *

Значения для AssemblyVersion и AssemblyFileVersion находятся в файле .csproj проекта MSBuild (не в AssemblyInfo.cs ) как свойство FileVersion (генерирует AssemblyFileVersionAttribute ) и AssemblyVersion (генерирует AssemblyVersionAttribute ). В процессе MSBuild мы используем нашу задачу MSBuild для генерации номеров версий, а затем переопределяем значения этих свойств FileVersion и AssemblyVersion с новыми значениями из задачи.

Итак, сначала мы создаем нашу собственную задачу MSBuild GetCurrentBuildVersion :

 public class GetCurrentBuildVersion : Task {    [Output]    public string Version { get; set; }    public string BaseVersion { get; set; }    public override bool Execute()    {        var originalVersion = System.Version.Parse(this.BaseVersion ?? "1.0.0");        this.Version = GetCurrentBuildVersionString(originalVersion);        return true;    }    private static string GetCurrentBuildVersionString(Version baseVersion)    {        DateTime d = DateTime.Now;        return new Version(baseVersion.Major, baseVersion.Minor,            (DateTime.Today - new DateTime(2000, 1, 1)).Days,            ((int)new TimeSpan(d.Hour, d.Minute, d.Second).TotalSeconds) / 2).ToString();    } } 

Класс задачи наследуется от classа Microsoft.Build.Utilities.Task из пакета Microsoft.Build.Utilities.Core NuGet. Требуется свойство BaseVersion (необязательно) для ввода и возвращает сгенерированную версию в свойствах вывода Version. Логика получения номеров версий такая же, как и для автоматического автоматического управления версиями .NET (номер сборки – количество дней с 1 января 2000 года, а версия – половина секунд с полуночи).

Чтобы создать эту задачу MSBuild, мы используем тип проекта библиотеки classов .NET Standard 1.3 с этим classом.

Файл .csproj может выглядеть следующим образом:

       netstandard1.3    DC.Build.Tasks    DC.Build.Tasks    DC.Build.Tasks    DC.Build.Tasks                

Этот целевой проект также доступен в моем GitHub holajan / DC.Build.Tasks

Теперь мы настраиваем MSBuild для использования этой задачи и устанавливаем свойства FileVersion и AssemblyVersion . В файле .csproj это выглядит так:

         ...    1.0.0.0    1.0.0.0    ...                          $(FileVersion)        

Импортные вещи здесь:

  • Упомянутый UseTask импортирует задачу GetCurrentBuildVersion из файла DC.Build.Tasks.dll . Предполагается, что этот DLL-файл находится в родительском каталоге из вашего .csproj-файла.
  • Наша задача BeforeBuildActionsProject1, которая вызывает задачу, должна иметь уникальное имя для каждого проекта, если у нас больше проектов в решении, которое вызывает задачу GetCurrentBuildVersion.

Преимущество этого решения заключается в том, что он работает не только из сборки на сервере сборки, но также и в ручных assemblyх из сборки dotnet или Visual Studio.

Эти значения теперь заданы в файле .csproj :

  netcoreapp1.1 1.0.6.0 1.0.6.0 1.0.1  

Это те же значения, которые вы видите, если вы заходите на вкладку « Пакет » в настройках проекта. Хотя я не думаю, что вы можете использовать * для автоматического обновления версии, что вы можете сделать, это ввести шаг пост-обработки, который заменяет версии для вас (например, как часть вашей непрерывной интеграции).

dotnet build /p:AssemblyVersion=1.2.3.4

Я отвечал: «Кто-нибудь понял, как управлять версией в проектах .NET Core (или .NETStandard в этом отношении)». Я нашел этот вопрос, пытаясь решить эту проблему в контексте сборки CI. Я хотел установить версию сборки на номер сборки CI.

Я создал простой инструмент CLI для установки строк .csproj .NET Core. Вы можете объединить его с инструментами, такими как GitVersion, для автоматического перебора версий во время сборки CI, если это то, что вам нужно.

Я принял вышеупомянутый ответ, потому что @Gigi прав (на данный момент), но я был раздражен и придумал следующие сценарии PowerShell.

Сначала у меня есть сценарий в папке моего решения (UpdateBuildVersion.ps1):

 #Get Path to csproj $path = "$PSScriptRoot\src\ProjectFolder\ProjectName.csproj" #Read csproj (XML) $xml = [xml](Get-Content $path) #Retrieve Version Nodes $assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion $fileVersion = $xml.Project.PropertyGroup.FileVersion #Split the Version Numbers $avMajor, $avMinor, $avBuild = $assemblyVersion.Split(".") $fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".") #Increment Revision $avBuild = [Convert]::ToInt32($avBuild,10)+1 $fvBuild = [Convert]::ToInt32($fvBuild,10)+1 #Put new version back into csproj (XML) $xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild" $xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild" #Save csproj (XML) $xml.Save($path) 

Я добавил это в файл csproj:

   0.0.1 0.0.1 powershell.exe –NonInteractive –ExecutionPolicy Unrestricted -command "& {$(SolutionDir)UpdateBuildVersion.ps1}"   

Даже через свой набор, который является PreBuildEvent, факт: номера версий не обновляются, пока ПОСЛЕ того, как файл был загружен в память, поэтому номер версии не будет отображаться до следующей сборки. Фактически, вы можете изменить его на PostBuildEvent, и он будет иметь тот же эффект.

Я также создал следующие два сценария: (UpdateMinorVersion.ps1)

 #Get Path to csproj $path = "$PSScriptRoot\src\ProjectFolder\ProjectName.csproj" #Read csproj (XML) $xml = [xml](Get-Content $path) #Retrieve Version Nodes $assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion $fileVersion = $xml.Project.PropertyGroup.FileVersion #Split the Version Numbers $avMajor, $avMinor, $avBuild = $assemblyVersion.Split(".") $fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".") #Increment Minor Version - Will reset all sub nodes $avMinor = [Convert]::ToInt32($avMinor,10)+1 $fvMinor = [Convert]::ToInt32($fvMinor,10)+1 $avBuild = 0 $fvBuild = 0 #Put new version back into csproj (XML) $xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild" $xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild" #Save csproj (XML) $xml.Save($path) 

(UpdateMajorVersion.ps1)

 #Get Path to csproj $path = "$PSScriptRoot\src\ProjectFolder\ProjectName.csproj" #Read csproj (XML) $xml = [xml](Get-Content $path) #Retrieve Version Nodes $assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion $fileVersion = $xml.Project.PropertyGroup.FileVersion #Split the Version Numbers $avMajor, $avMinor, $avBuild = $assemblyVersion.Split(".") $fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".") #Increment Major Version - Will reset all sub nodes $avMajor = [Convert]::ToInt32($avMajor,10)+1 $fvMajor = [Convert]::ToInt32($fvMajor,10)+1 $avMinor = 0 $fvMinor = 0 $avBuild = 0 $fvBuild = 0 #Put new version back into csproj (XML) $xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild" $xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild" #Save csproj (XML) $xml.Save($path) 

Чтобы включить управление версиями вашего .Net Core / .Net Независимо от проекта, основанного на настройке GIT, используя tags / описывайте функциональность GIT.

Я использовал файл Prebuild.targets.xml, который находится в корневой папке для проекта и включен в файл csproj, например:

   ...  false 

Используйте тег «GenerateAssembyInfo», чтобы отключить автоматическую сборку информации о сборке.

Затем Prebuild.targets.xml будет генерировать файл CommonAssemblyInfo.cs, где вы можете включить tags версии, которые вы хотите, на основе вашей версии GIT

ПРИМЕЧАНИЕ. Я нашел файл Prebuilds.targets.xml где-то в другом месте, поэтому он не хотел его очищать.)

Файл Prebuild.targets.xml:

                 \d+)\.(?\d+)(\.?(?\d+))?-(?\d+)-(?[a-z0-9-]+)$"); int major, minor, patch, revision; Int32.TryParse(match.Groups["major"].Value, out major); Int32.TryParse(match.Groups["minor"].Value, out minor); Int32.TryParse(match.Groups["patch"].Value, out patch); Int32.TryParse(match.Groups["revision"].Value, out revision); _Version = new Version(major, minor, patch, revision).ToString(); _Commit = match.Groups["commit"].Value; ]]>                                      0.0.0.0      

EDIT: если вы создаете MSBUILD,

  $(SolutionDir) 

Может возникнуть проблема, используйте

  $(ProjectDir) 

вместо

Расширение «Автоматические версии» для Visual Studio теперь поддерживает автоматическое автообновление .Net Core и .Net в простом пользовательском интерфейсе.

https://marketplace.visualstudio.com/items?itemName=PrecisionInfinity.AutomaticVersions

Вы можете использовать функцию свойства MSBuild для установки суффикса версии на основе текущей даты:

  pre$([System.DateTime]::UtcNow.ToString(yyyyMMdd-HHmm))  

Это выведет пакет с таким именем, как: PackageName.1.0.0-pre20180807-1711.nupkg .

Дополнительные сведения о функциях свойств MSBuild: https://docs.microsoft.com/en-us/visualstudio/msbuild/property-functions

Я думаю, что этот ответ от @joelsand является правильным ответом на установку номера версии для ядра dotnet, работающего на VSTS

Чтобы добавить дополнительную информацию для этого ответа,

BUILD_BUILDNUMBER – фактически предопределенная переменная .

Оказывается, есть две версии предопределенной переменной.

Один из них – build.xxxx, другой – BUILD_XXXX.

Вы можете использовать только Environment Variable Name в cproj.

  • Может ли он игнорировать / отключать первый шаг? Получить источник в vNext Build?
  • Давайте будем гением компьютера.