Auto Versioning in Visual Studio 2017 (.NET Core)

后端 未结 16 1346
一整个雨季
一整个雨季 2020-11-28 18:45

I have spent the better part of a few hours trying to find a way to auto-increment versions in a .NETCoreApp 1.1 (Visual Studio 2017).

I know the the AssemblyInfo.cs

相关标签:
16条回答
  • 2020-11-28 19:03

    You can use a MSBuild property function to set the version suffix based on current date:

    <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
      <VersionSuffix>pre$([System.DateTime]::UtcNow.ToString(yyyyMMdd-HHmm))</VersionSuffix>
    </PropertyGroup>
    

    This will output a package with a name like: PackageName.1.0.0-pre20180807-1711.nupkg.

    More details about MSBuild property functions: https://docs.microsoft.com/en-us/visualstudio/msbuild/property-functions

    The Version is formed from the combination of VersionPrefix and VersionSuffix, or if VersionSuffix is blank, VersionPrefix only.

    <PropertyGroup>
      <VersionPrefix>1.0.0</VersionPrefix>
    </PropertyGroup>
    
    0 讨论(0)
  • 2020-11-28 19:04

    I accepted the above answer because @Gigi is correct (as of now) but I was annoyed and came up with the following PowerShell Scripts.

    First I have the script in my solution folder (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)
    

    I added this to csproj file:

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

    Even through its set to be a PreBuildEvent, the fact is the version numbers do not get updated until AFTER the file has been loaded into memory so the version number will not reflect until the next build. In fact, you could change it to a PostBuildEvent and it would have the same effect.

    I also created the following two scripts: (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)
    
    0 讨论(0)
  • 2020-11-28 19:04

    You could do it like below, within the csproj file. I didn't figure out the math. I found that somewhere else on Stack Overflow, but this works and will give you something similiar to 1.0.* for version.

    <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>
    
    0 讨论(0)
  • 2020-11-28 19:07

    These values are now set in the .csproj file:

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

    These are the same values you see if you go in the Package tab in the project settings. While I don't think you can use * to autoincrement the version, what you can do is introduce a post-processing step that replaces the versions for you (e.g. as part of your continuous integration).

    0 讨论(0)
  • 2020-11-28 19:08

    I made a simple CLI tool for setting .csproj .NET Core version strings here. You can combine it with tools like GitVersion for automatic version bumping during CI builds, if that's what you're after.

    0 讨论(0)
  • 2020-11-28 19:13

    What worked for me was to define Patch and Revision using a PropertyGroup, then you can just use this variables for version (and prefix if needed). Version numbers must be short numbers so I use YearMonth for Patch, and MinutesOfDay for Revision. Add this lines to your csproj file:

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    
        <PropertyGroup>
            <VersionMajor>0</VersionMajor>
            <VersionMinor>9</VersionMinor>
            <VersionPatch Condition="'$(VersionPatch)' == ''">$([System.DateTime]::UtcNow.ToString("yyMM"))</VersionPatch>
            <VersionRevision Condition="'$(VersionRevision)' == ''">$([System.DateTime]::UtcNow.TimeOfDay.TotalMinutes.ToString("0"))</VersionRevision>
        </PropertyGroup>
    
        <PropertyGroup>
            <OutputType>...</OutputType>
            <TargetFramework>net5.0</TargetFramework>
            <Title>Software Title</Title>
            <Description>...</Description>
            <Authors>...</Authors>
            <Version>$(VersionMajor).$(VersionMinor).$(VersionPatch).$(VersionRevision)</Version>
        </PropertyGroup>
    
        ....
    
    </Project>
    

    It can be achive in a generic way making use of Directory.build.props file. More info here: https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build?view=vs-2019

    Just add a file with this name in the project folder and place there these lines.


    I came across here searching for a solution for shared projects. In my case, I solved it adding a Version.build.props file in my shared project with the structure shown above, and just one new line at any csproj file for projects using my shared code:

    <!-- Shared project import -->
    <Import Project="..\Shared\Shared.projitems" Label="Shared" /> 
    <!-- Version number generator -->
    <Import Project="$([MSBuild]::GetPathOfFileAbove('Version.Build.props', '$(MSBuildThisFileDirectory)../Shared/'))" />
    

    I'll left this code here just in case someone needs it.

    *Solution tested for .Net5 but should works for earlier versions.

    0 讨论(0)
提交回复
热议问题