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) 프로젝트에서 버전을 제어하는 방법을 알아 낸 것입니다.
csproj 구성 형식을 사용하는 VS2017의 Net Core 앱에 대한 버전 증분기를 찾고 있습니다.
project.json 형식에서 작동했지만 .csproj 형식에 대한 솔루션을 찾는 데 어려움을 겪은 dotnet bump라는 프로젝트를 찾았습니다. 작가 인 dotnet bump는 실제로 .csproj 형식에 대한 솔루션을 제시했으며 MSBump라고합니다.
GitHub에 대한 프로젝트가 있습니다.
https://github.com/BalassaMarton/MSBump
Nuget에서도 코드와 해당 코드를 볼 수 있습니다. Nuget에서 MSBump를 검색하십시오.
<Deterministic>False</Deterministic>
<PropertyGroup>
.csproj 섹션 내부에 추가
AssemblyVersion * 작동을위한 해결 방법은 ".Net Core # 22660의 [AssemblyVersion]에서 와일드 카드에 대한 혼동 오류 메시지"에 설명되어 있습니다.
.Net Core 프로젝트의 기본값 인 빌드가 결정적이지 않은 경우에만 와일드 카드가 허용됩니다.
<Deterministic>False</Deterministic>
csproj에 추가 하면 문제가 해결됩니다.
.Net Core 개발자가 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
Visual Studio Team Services / TFS 또는 기타 CI 빌드 프로세스를 사용하여 버전 관리가 기본 제공되는 경우 msbuild의 Condition
특성을 사용할 수 있습니다 . 예를 들면 다음과 같습니다.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<Version Condition=" '$(BUILD_BUILDNUMBER)' == '' ">0.0.1-local</Version>
<Version Condition=" '$(BUILD_BUILDNUMBER)' != '' ">$(BUILD_BUILDNUMBER)</Version>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="1.1.2" />
</ItemGroup>
</Project>
이렇게하면 .NET Core 컴파일러에 BUILD_BUILDNUMBER
환경 변수 가있는 경우 무엇이든지 사용 0.0.1-local
하고 로컬 머신에서 빌드를 수행하는 경우 대체하도록 지시 합니다.
별표 (*)- AssemblyVersion ( "1.0. ") *이있는 이전 AssemblyVersion 속성과 거의 동일하게 작동하는 솔루션을 생각해 냈습니다 .
AssemblyVersion 및 AssemblyFileVersion 값 은 MSBuild 프로젝트 .csproj 파일 ( 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();
}
}
Task 클래스 는 Microsoft.Build.Utilities.Core NuGet 패키지의 Microsoft.Build.Utilities.Task 클래스에서 상속 됩니다. 입력시 BaseVersion 속성 (선택 사항)을 취하고 Version 출력 속성에 생성 된 버전을 반환합니다. 버전 번호를 가져 오는 논리는 .NET 자동 버전 관리와 동일합니다 (빌드 번호는 2000 년 1 월 1 일 이후 일 수이고 수정 버전은 자정 이후 30 초입니다).
이 MSBuild 작업을 빌드하기 위해이 클래스와 함께 .NET Standard 1.3 클래스 라이브러리 프로젝트 유형을 사용합니다.
.csproj 파일은 다음과 같습니다.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.3</TargetFramework>
<AssemblyName>DC.Build.Tasks</AssemblyName>
<RootNamespace>DC.Build.Tasks</RootNamespace>
<PackageId>DC.Build.Tasks</PackageId>
<AssemblyTitle>DC.Build.Tasks</AssemblyTitle>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build.Framework" Version="15.1.1012" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.1.1012" />
</ItemGroup>
</Project>
이 작업 프로젝트는 내 GitHub holajan / DC.Build.Tasks 에서도 사용할 수 있습니다.
이제이 작업을 사용하고 FileVersion 및 AssemblyVersion 속성을 설정하도록 MSBuild를 설정 합니다. .csproj 파일에서는 다음과 같습니다.
<Project Sdk="Microsoft.NET.Sdk">
<UsingTask TaskName="GetCurrentBuildVersion" AssemblyFile="$(MSBuildThisFileFullPath)\..\..\DC.Build.Tasks.dll" />
<PropertyGroup>
...
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
</PropertyGroup>
...
<Target Name="BeforeBuildActionsProject1" BeforeTargets="BeforeBuild">
<GetCurrentBuildVersion BaseVersion="$(FileVersion)">
<Output TaskParameter="Version" PropertyName="FileVersion" />
</GetCurrentBuildVersion>
<PropertyGroup>
<AssemblyVersion>$(FileVersion)</AssemblyVersion>
</PropertyGroup>
</Target>
</Project>
여기서 중요한 것은 :
- 언급 UsingTask는 에서 GetCurrentBuildVersion 작업을 가져 DC.Build.Tasks.dll . 이 dll 파일이 .csproj 파일의 상위 디렉토리에 있다고 가정합니다.
- 우리 BeforeBuildActionsProject1 대상 통화의 작업은 우리가 GetCurrentBuildVersion 작업을 호출하는 솔루션에 더 많은 프로젝트를해야하는 경우에 프로젝트마다 고유 한 이름이 있어야합니다.
이 솔루션의 장점은 빌드 서버의 빌드뿐만 아니라 dotnet 빌드 또는 Visual Studio의 수동 빌드에서도 작동한다는 것 입니다.
MSBuild 속성 함수를 사용하여 현재 날짜를 기반으로 버전 접미사를 설정할 수 있습니다.
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<VersionSuffix>pre$([System.DateTime]::UtcNow.ToString(yyyyMMdd-HHmm))</VersionSuffix>
</PropertyGroup>
그러면 다음과 같은 이름의 패키지가 출력됩니다. PackageName.1.0.0-pre20180807-1711.nupkg .
MSBuild 속성 함수에 대한 자세한 내용 : https://docs.microsoft.com/en-us/visualstudio/msbuild/property-functions
이제 다음 값이 .csproj
파일에 설정 됩니다.
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
<AssemblyVersion>1.0.6.0</AssemblyVersion>
<FileVersion>1.0.6.0</FileVersion>
<Version>1.0.1</Version>
</PropertyGroup>
이는 프로젝트 설정 의 패키지 탭에서 볼 수있는 것과 동일한 값 입니다. *
버전을 자동으로 늘리는 데 사용할 수 없다고 생각하지만 할 수있는 것은 버전을 대체하는 사후 처리 단계를 도입하는 것입니다 (예 : 지속적인 통합의 일부로).
dotnet 빌드 /p:AssemblyVersion=1.2.3.4
저는 "누군가 .NET Core (또는 .NETStandard) 프로젝트에서 버전을 제어하는 방법을 알아 낸 사람이 있습니까?" CI 빌드의 맥락 에서이 문제를 해결하려는이 질문을 발견했습니다. 어셈블리 버전을 CI 빌드 번호로 설정하고 싶었습니다.
여기서 .csproj .NET Core 버전 문자열을 설정하기위한 간단한 CLI 도구를 만들었습니다 . CI 빌드 중 자동 버전 범핑을 위해 GitVersion과 같은 도구와 결합 할 수 있습니다.
@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 파일에 추가했습니다.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyVersion>0.0.1</AssemblyVersion>
<FileVersion>0.0.1</FileVersion>
<PreBuildEvent>powershell.exe –NonInteractive –ExecutionPolicy Unrestricted -command "& {$(SolutionDir)UpdateBuildVersion.ps1}"</PreBuildEvent>
</PropertyGroup>
</Project>
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)
GIT의 태그 / 설명 기능을 사용하여 GIT 설정을 기반으로 .Net Core / .Net Whatever 프로젝트의 버전 관리를 활성화합니다.
프로젝트의 루트 폴더에 있고 다음과 같이 csproj 파일에 포함 된 Prebuild.targets.xml 파일을 사용하고 있습니다.
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="PreBuild.targets.xml" />
...
<PropertyGroup>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
자동 어셈블리 정보 생성을 비활성화하려면 "GenerateAssembyInfo"태그를 사용하십시오.
그런 다음 Prebuild.targets.xml은 GIT 버전에 따라 원하는 버전 태그를 포함 할 수있는 CommonAssemblyInfo.cs 파일을 생성합니다.
참고 : 다른 곳에서 Prebuilds.targets.xml을 찾았으므로 정리하지 않았습니다.)
Prebuild.targets.xml 파일 :
<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask
TaskName="GetVersion"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup>
<VersionString ParameterType="System.String" Required="true" />
<Version ParameterType="System.String" Output="true" />
<Commit ParameterType="System.String" Output="true" />
<VersionSuffix ParameterType="System.String" Output="true" />
</ParameterGroup>
<Task>
<!--<Reference Include="" />-->
<Using Namespace="System"/>
<Using Namespace="System.IO"/>
<Using Namespace="System.Text.RegularExpressions" />
<Code Type="Fragment" Language="cs">
<![CDATA[
var match = Regex.Match(VersionString, @"^(?<major>\d+)\.(?<minor>\d+)(\.?(?<patch>\d+))?-(?<revision>\d+)-(?<commit>[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;
]]>
</Code>
</Task>
</UsingTask>
<UsingTask
TaskName="GitExistsInPath"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup>
<Exists ParameterType="System.Boolean" Output="true" />
</ParameterGroup>
<Task>
<!--<Reference Include="" />-->
<Using Namespace="System"/>
<Using Namespace="System.IO"/>
<Using Namespace="System.Text.RegularExpressions" />
<Code Type="Fragment" Language="cs">
<![CDATA[
var values = Environment.GetEnvironmentVariable("PATH");
foreach (var path in values.Split(';')) {
var exeFullPath = Path.Combine(path, "git.exe");
if (File.Exists(exeFullPath)) {
Exists = true;
return true;
}
var cmdFullPath = Path.Combine(path, "git.cmd");
if (File.Exists(cmdFullPath)) {
Exists = true;
return true;
}
}
Exists = false;
]]>
</Code>
</Task>
</UsingTask>
<Target Name="CreateCommonVersionInfo" BeforeTargets="CoreCompile">
<Message Importance="high" Text="CreateCommonVersionInfo" />
<GitExistsInPath>
<Output TaskParameter="Exists" PropertyName="GitExists"/>
</GitExistsInPath>
<Message Importance="High" Text="git not found!" Condition="!$(GitExists)"/>
<Exec Command="git describe --tags --long --dirty > $(ProjectDir)version.txt" Outputs="$(ProjectDir)version.txt" WorkingDirectory="$(SolutionDir)" IgnoreExitCode="true" Condition="$(GitExists)">
<Output TaskParameter="ExitCode" PropertyName="ExitCode" />
</Exec>
<Message Importance="high" Text="Calling git failed with exit code $(ExitCode)" Condition="$(GitExists) And '$(ExitCode)'!='0'" />
<ReadLinesFromFile File="$(ProjectDir)version.txt" Condition="$(GitExists) And '$(ExitCode)'=='0'">
<Output TaskParameter="Lines" ItemName="OutputLines"/>
</ReadLinesFromFile>
<Message Importance="High" Text="Tags: @(OutputLines)" Condition="$(GitExists) And '$(ExitCode)'=='0'"/>
<Delete Condition="Exists('$(ProjectDir)version.txt')" Files="$(ProjectDir)version.txt"/>
<GetVersion VersionString="@(OutputLines)" Condition="$(GitExists) And '$(ExitCode)'=='0'">
<Output TaskParameter="Version" PropertyName="VersionString"/>
<Output TaskParameter="Commit" PropertyName="Commit"/>
</GetVersion>
<PropertyGroup>
<VersionString Condition="'$(VersionString)'==''">0.0.0.0</VersionString>
</PropertyGroup>
<Message Importance="High" Text="Creating CommonVersionInfo.cs with version $(VersionString) $(Commit)" />
<WriteLinesToFile Overwrite="true" File="$(ProjectDir)CommonAssemblyInfo.cs" Encoding="UTF-8" Lines='using System.Reflection%3B
// full version: $(VersionString)-$(Commit)
[assembly: AssemblyVersion("$(VersionString)")]
[assembly: AssemblyInformationalVersion("$(VersionString)")]
[assembly: AssemblyFileVersion("$(VersionString)")]' />
</Target>
</Project>
편집 : MSBUILD를 사용하여 빌드하는 경우
$(SolutionDir)
문제를 일으킬 수 있습니다.
$(ProjectDir)
대신
Visual Studio 용 자동 버전 확장은 이제 간단한 사용자 인터페이스에서 .Net Core 및 .Net Standard 자동 증가를 지원합니다.
https://marketplace.visualstudio.com/items?itemName=PrecisionInfinity.AutomaticVersions
@joelsand의 답변 이 VSTS에서 실행되는 dotnet 코어의 버전 번호 설정에 대한 정답 이라고 생각합니다.
이 답변에 대한 정보를 더 추가하려면
BUILD_BUILDNUMBER
실제로 미리 정의 된 변수 입니다.
It turns out there are 2 versions of predefined variable.
One is build.xxxx, the other is BUILD_XXXX.
You can only use Environment Variable Name
in cproj.
We can use special parameter for dotnet publish -- version-suffix 1.2.3
For file version:
<AssemblyVersion Condition=" '$(VersionSuffix)' == '' ">0.0.1.0</AssemblyVersion>
<AssemblyVersion Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)</AssemblyVersion>
For version:
<Version Condition=" '$(VersionSuffix)' == '' ">0.0.1</Version>
<Version Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)</Version>
https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?tabs=netcore21
--version-suffix <VERSION_SUFFIX> Defines the value for the $(VersionSuffix) property in the project.
참고URL : https://stackoverflow.com/questions/43019832/auto-versioning-in-visual-studio-2017-net-core
'program story' 카테고리의 다른 글
"%를 사용할 수 없음 : 대신 truncatingRemainder 사용"은 무엇을 의미합니까? (0) | 2020.09.05 |
---|---|
adb 명령을 사용하여 SD 카드없이 기기에 파일을 푸시하는 방법 (0) | 2020.09.05 |
Or 대 OrElse (0) | 2020.09.05 |
Python에서 사용되는 python-memcache (memcached)의 좋은 예? (0) | 2020.09.05 |
UserControl을 Visual Studio 도구 상자에 넣는 방법 (0) | 2020.09.05 |