Visual Studio 2017 (.NET Core)의 자동 버전 관리


112

.NETCoreApp 1.1 (Visual Studio 2017)에서 버전을 자동으로 늘리는 방법을 찾는 데 몇 시간 중 더 많은 시간을 보냈습니다.

AssemblyInfo.cs가 폴더에 동적으로 생성된다는 것을 알고 있습니다. obj/Debug/netcoreapp1.1/

다음과 같은 이전 방법은 허용되지 않습니다. [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.*")]

프로젝트를 패키지로 설정하면 거기에서 버전을 설정할 수 있지만 AssemblyInfo.cs 파일을 빌드하는 데 사용되는 것 같습니다.

내 질문은 누구든지 .NET Core (또는 .NETStandard) 프로젝트에서 버전을 제어하는 ​​방법을 알아 낸 것입니다.


나는 당신이 이것으로 얼마나 멀리 왔는지 모르지만 거의 같은 질문을 다른 방식으로 물은 것처럼 보입니다 ( stackoverflow.com/a/43280282/685341)- 아마도이 질문에 대한 대답이 도움이 될 것입니다. 빌드 스크립트에 /p:플래그를 전달하고 dotnet msbuild버전, 회사, 저작권 등을 설정할 수 있습니다.
Jay

2
정보 주셔서 감사합니다. 추가 옵션이 열립니다.
Jason H

이전에 *는 AssemblyFileVersion이 아닌 AssemblyVersion에 대해 지원되었습니다. Visual Studio를 사용할 때 파일 빌드 버전을 자동으로 증가시킬 수 있습니까?를
Michael Freidgeim

4
FWIW 어셈블리 버전의 와일드 카드는 이러한 새 프로젝트의 경우 컴파일러의 "결정적"모드가 기본적으로 활성화되기 때문에 지원되지 않습니다. 자동 증가는 결정론을 깨기 때문에 (동일한 입력> 동일한 출력) 해당 모드에서는 허용되지 않습니다. <Deterministic>False</Deterministic>csproj에서 설정 하여 사용할 수 있습니다. (또는 계산하는 다른 MSBUILD의 논리를 사용 <VersionPrefix>/ <Version>)
마틴 울리히에게

답변:


23

csproj 구성 형식을 사용하는 VS2017의 Net Core 앱에 대한 버전 증분기를 찾고 있습니다.

project.json 형식에서 작동했지만 .csproj 형식에 대한 솔루션을 찾는 데 어려움을 겪은 dotnet bump라는 프로젝트를 찾았습니다. 작가 인 dotnet bump는 실제로 .csproj 형식에 대한 솔루션을 제시했으며 MSBump라고합니다.

GitHub에 대한 프로젝트가 있습니다.

https://github.com/BalassaMarton/MSBump

Nuget에서도 코드와 해당 코드를 볼 수 있습니다. Nuget에서 MSBump를 검색하십시오.


1
MSBump의 최신 2.1.0 릴리스를 사용하는 것이 좋습니다. 구성 전환을 더 잘 지원하며 이전 버전과 같이 다음 빌드가 아닌 현재 빌드의 버전을 설정합니다.
Márton Balassa

이제 Visual Studio가 필요하기 전에 MSBuild도 지원합니다.
ravetroll

2
예, 다중 타겟팅 프로젝트도 지원합니다.
Márton Balassa

4
GitVersioning 사용을 고려하십시오. CI 환경에서 실행하는 것이 적합 할 수 있습니다. github.com/AArnott/Nerdbank.GitVersioning
Henrique

1
MSBump는 아무것도 변경하지 않았더라도 모든 빌드에서 버전을 증가 시키므로 장기적으로 많은 문제가 발생합니다. 때로는 버전이 동기화되지 않고 한 버전이 다른 버전보다 뒤처집니다.
Konrad

68

<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   

감사합니다! 보물 방을 열 수있는 숨겨진 레버가 있다는 걸 알았어요! 이전 프로젝트를 새 .NET SDK로 마이그레이션하고 있는데 자동화 된 버전 증가 솔루션을 찾는 번거 로움없이이 작업을 빠르게 수행하고 싶었습니다. 사실, 예전 방식과 더 잘 호환 될수록 제 경우에는 더 좋습니다.
Ivaylo Slavov

이것이 IMO의 베스트 답변입니다. 빌드 도구가 제대로 작동 할 수 있습니다. 적어도 외부 메커니즘을 사용하여 빌드에 번호를 입력 할 수 있습니다.
Michael Yanni

답변을 조금 더 확장하십시오. 제안 된 추가 사항은 .csproj의 <PropertyGroup> 섹션으로 이동해야합니다. 이 훌륭한 답변에 감사드립니다.
GerardV

1
@gerardv은 수행하지만 사용자가 직접 편집을 개선 할 수 stackoverflow.com/help/editing
마이클 Freidgeim

62

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하고 로컬 머신에서 빌드를 수행하는 경우 대체하도록 지시 합니다.


좋습니다. 환경 변수는 빌드 서버에서 설정할 수 있지만 이러한 조건은 바이너리의 어셈블리 집합을 결정하기 때문에이 방법을 좋아합니다.
jbooker

TFS 2010에서 작동하지 않는 것 같지만 곧 그만두기를 바랍니다!
Mark Adamson

나쁜 솔루션은 아니지만 솔루션에 많은 프로젝트가있는 경우 약간의 작업이 될 수 있습니다.
tofutim

좋은 솔루션입니다. 그래도 빌드 예외가 발생했습니다. 나는 그것을 고치기 위해 구성을 약간 변경해야했다. stackoverflow.com/a/59858009/106227
Stu Harper

.NET Core 2.1.2 및 TFS2017U3
Dave Johnson에서

16

별표 (*)- AssemblyVersion ( "1.0. ") *이있는 이전 AssemblyVersion 속성과 거의 동일하게 작동하는 솔루션을 생각해 냈습니다 .

AssemblyVersionAssemblyFileVersion 값 은 MSBuild 프로젝트 .csproj 파일 ( AssemblyInfo.cs가 아님)에 FileVersion 속성 ( AssemblyFileVersionAttribute 생성 ) 및 AssemblyVersion ( AssemblyVersionAttribute 생성 )이 있습니다. MSBuild 프로세스에서 사용자 지정 MSBuild 작업을 사용하여 버전 번호를 생성 한 다음 이러한 FileVersionAssemblyVersion 속성의 값을 작업의 새 값으로 재정의합니다 .

따라서 먼저 사용자 지정 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();
    }
}

에서 작업 클래스 상속 Microsoft.Build.Utilities.Task의 에서 클래스 Microsoft.Build.Utilities.Core NuGet 패키지의 됩니다. 입력시 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 에서도 사용할 수 있습니다.

이제이 작업을 사용하고 FileVersionAssemblyVersion 속성을 설정하도록 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의 수동 빌드에서도 작동한다는 것 입니다.


4
특히 코드가 자동화 된 빌드 머신에서 실행되는 경우 메서드 DateTime.UtcNow대신 사용 하는 것이 좋습니다 . 컴퓨터가 일광 절약 시간으로 전환 될 때 오전 2시 또는 오전 3시에 실행될 수 있습니다. 로 그 시나리오에서 당신은 버전의 관점에서 거꾸로 갈 수 있습니다. 사실, 이것은 코너 케이스이며, 내가 까다 롭다는 것도 인정합니다. :-) 또한 모든 빌드 시스템에서 동일한 시간대를 구성하고 일광 절약 시간을 조정하지 않으면 문제가 사라집니다. DateTime.NowGetCurrentBuildVersionString()DateTime.Now
Manfred

아직 NuGet 패키지가 있습니까?
Jonathan Allen

@Jonathan Allen 아니요, 각 프로젝트의 이름이 다르기 때문에 nuget 패키지에 대한 계획이 없습니다. 컴파일 된 빌드 작업 어셈블리는 github.com/holajan/DC.Build.Tasks/tree/master/dist 폴더 에서 다운로드 할 수 있습니다
HolaJan dec

사용자 지정 콘솔 앱을 사용하여 서버에서 버전을 가져오고 빌드 전에 AssemblyInfo.cs 파일을 생성했습니다. 이 접근 방식은 우리가하는 일에 완벽합니다. 이 방법을 사용하여 새 프로젝트의 팩 기능 "버전"에서 버전을 푸시 할 수 있었습니까? 좋겠지 만 게시 할 때도 필요하므로 nuget.exe를 사용하여 패키징 할 수도 있습니다.
David Ritchie

15

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

Version의 조합을 형성 VersionPrefix하고 VersionSuffix, 또는 경우는 VersionSuffix, 비어 있습니다 VersionPrefix만.

<PropertyGroup>
  <VersionPrefix>1.0.0</VersionPrefix>
</PropertyGroup>

이건 정말 편리합니다
제리 닉슨

12

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

10

dotnet 빌드 /p:AssemblyVersion=1.2.3.4

저는 "누군가 .NET Core (또는 .NETStandard) 프로젝트에서 버전을 제어하는 ​​방법을 알아 낸 사람이 있습니까?" CI 빌드의 맥락 에서이 문제를 해결하려는이 질문을 발견했습니다. 어셈블리 버전을 CI 빌드 번호로 설정하고 싶었습니다.


1
제목은 "Visual Studio 2017 (.NET Core)의 자동 버전 관리"입니다. 정확히 어디에서 수동으로 "Visual Studio 2017"을 준수합니까?
JCKödel

4
저는 "누군가 .NET Core (또는 .NETStandard) 프로젝트에서 버전을 제어하는 ​​방법을 알아 낸 사람이 있습니까?" CI 빌드의 맥락 에서이 문제를 해결하려는이 질문을 발견했습니다. 어셈블리 버전을 CI 빌드 번호로 설정하고 싶었습니다. 이것이 당면한 질문과 관련이 없다고 생각하시면 죄송합니다.
Chris McKenzie

저에게 도움이되는 구성 요소입니다. 감사합니다. 나는 CI 솔루션의 일부로이 사용됩니다
마크 아담 슨에게

1
@ChrisMcKenzie는 : 귀하의 의견은 당신의 의도를 명확하게하기 위해 당신의 대답에 포함되어야한다
마이클 Freidgeim

** assemblyinfo.cs가 지정되지 않고 버전이 csproj에있을 때 netstandard 프로젝트에서이 기능이 작동하지 않습니다.
tofutim

9

이제 다음 값이 .csproj파일에 설정 됩니다.

<PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
    <AssemblyVersion>1.0.6.0</AssemblyVersion>
    <FileVersion>1.0.6.0</FileVersion>
    <Version>1.0.1</Version>
</PropertyGroup>

이는 프로젝트 설정 의 패키지 탭에서 볼 수있는 것과 동일한 값 입니다. *버전을 자동 증분하는 데 사용할 수 없다고 생각하지만 , 할 수있는 일은 버전을 대체하는 사후 처리 단계를 도입하는 것입니다 (예 : 지속적인 통합의 일부로).


6
이것이 답이 될까 두려웠습니다. 이를 증가시키기 위해 사전 빌드 단계를 수행 할 수 있는지 확인합니다.
Jason H

3
다른 스레드에서 지적했듯이 새로운 csproj 형식을 사용하면 assemblyinfo 파일의 자동 생성을 끄고 직접 지정할 수 있습니다. 나는 여기 natemcmaster의 대답의 조언을 따랐고 표준 AssemblyInfo.cs 파일을 사용했습니다 : stackoverflow.com/questions/42138418/…
James Eby

5
자동 증가를 제거한 이유는 무엇입니까? 몇 년 동안 정말 잘 작동했습니다. 마스터, CI 빌드 및 증분을 푸시 한 다음 일부 PS 스크립트를 사용하여 빌드 된 DLL에서 직접 버전을 읽은 다음 NuGet으로 푸시 할 때 해당 버전을 인수로 사용합니다. 아주 간단합니다. 이제 깨졌습니다.
Luke Puplett 2017-08-30

1
@LukePuplett 같은 여기. 너무 답답 해요!
Shimmy Weitzhandler

@LukePuplett : [ ".Net Core # 22660의 AssemblyVersion의 와일드 카드에 대한 혼동 오류 메시지"] ( github.com/dotnet/roslyn/issues/22660 ), blog.paranoidcoding.com에 설명 된 결정적 빌드가 유익하다고 생각하는 이유 참조 / 2016 / 04 / 05 /… 컴파일러는 결정적이어야합니다. 동일한 입력이 동일한 출력을 생성합니다. # 372 < github.com/dotnet/roslyn/issues/372 >
Michael Freidgeim

5

여기서 .csproj .NET Core 버전 문자열을 설정하기위한 간단한 CLI 도구를 만들었습니다 . CI 빌드 중 자동 버전 범핑을 위해 GitVersion과 같은 도구와 결합 할 수 있습니다.


@JasonH 감사합니다. 문제가 있으면 알려주세요.
Tagc 2011

젠장 할 천재. 그것을 사랑하십시오!
pms1969

4

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)

대신


좋은! VersionSuffix가 설정되거나 사용됩니까? 될 것 같지 않습니다
마크 아담 슨에게

4

csproj 파일 내에서 다음을 수행 할 수 있습니다. 나는 수학을 이해하지 못했습니다. 나는 stackoverflow의 다른 곳에서 그것을 발견했습니다. 그러나 이것은 작동하며 버전에 대해 1.0. *과 유사한 것을 제공합니다.

<PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <FileVersion>1.0.$([System.DateTime]::UtcNow.Date.Subtract($([System.DateTime]::Parse("2000-01-01"))).TotalDays).$([System.Math]::Floor($([MSBuild]::Divide($([System.DateTime]::UtcNow.TimeOfDay.TotalSeconds), 1.32))))</FileVersion>
    <Version>1.0.$([System.DateTime]::UtcNow.Date.Subtract($([System.DateTime]::Parse("2000-01-01"))).TotalDays)</Version>
</PropertyGroup>

3

Visual Studio 용 자동 버전 확장은 이제 간단한 사용자 인터페이스에서 .Net Core 및 .Net Standard 자동 증가를 지원합니다.

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


1
데모 솔루션 (Windows 앱)으로 빠른 테스트를 수행했으며 .net 표준 프로젝트에서도 작동합니다. 빠른 테스트 였으므로 우리가 원하는 모든 것을 수행하는지 확인하려면 더 깊이 들어가야합니다. 그러나 당신은 확실히 이것을 시도 할 수 있습니다.
ArieKanarie

3

나를 올바른 방향으로 안내 해준 @joelsand에게 감사드립니다.

DevOps Build가 실행될 때 다음 예외가 발생했기 때문에 그의 대답을 약간 변경해야했습니다.

The specified version string does not conform to the recommended format - major.minor.build.revision

major.minor.build 섹션 끝에 $ (BUILD_BUILDNUMBER)를 추가해야했습니다. 실제 버전을 중복 제거하기 위해 버전 접두사도 사용합니다.

<PropertyGroup>
    <VersionPrefix>1.0.3</VersionPrefix>
    <Version Condition=" '$(BUILD_BUILDNUMBER)' == '' ">$(VersionPrefix)-local</Version>
    <Version Condition=" '$(BUILD_BUILDNUMBER)' != '' ">$(VersionPrefix)-$(BUILD_BUILDNUMBER)</Version>
</PropertyGroup>

나는 똑같은 문제가 있었고 당신의 대답은 그것을 고쳤습니다. 감사합니다.
회의 참석자

2

특수 매개 변수를 사용할 수 있습니다. dotnet publish -- version-suffix 1.2.3

파일 버전 :

<AssemblyVersion Condition=" '$(VersionSuffix)' == '' ">0.0.1.0</AssemblyVersion>
<AssemblyVersion Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)</AssemblyVersion>

버전 :

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

1

나는이 대답을 생각한다@joelsand의 VSTS에서 실행되는 dotnet 코어의 버전 번호 설정에 대한 정답

이 답변에 대한 정보를 더 추가하려면

BUILD_BUILDNUMBER실제로 미리 정의 된 변수입니다. 입니다.

미리 정의 된 변수에는 두 가지 버전이 있습니다.

하나는 build.xxxx이고 다른 하나는 BUILD_XXXX입니다.

Environment Variable Namecproj 에서만 사용할 수 있습니다 .


build.xxxx파이프 라인 내에서 참조하기 위해 프런트 엔드에서 사용 되지 않고 BUILD_XXXX동일한 값이지만 PS에서 변수를 참조하기 위해 약간 수정 된 구문이 필요합니까?
dst3p
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.