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 속성과 거의 동일하게 작동하는 솔루션을 생각해 냈습니다 .

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();
    }
}

에서 작업 클래스 상속 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 에서도 사용할 수 있습니다.

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


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.