Search code examples
azure-devopsazure-pipelinescicd

DevOps .NET 6 Library AutoVersion using Major/Minor from csproj but auto-generate patch


I am currently using DevOps pipeline. Our project file versions start with 6.1.x but I have to manually increment the patch version so that it appears as an update within the 'Manage NuGet packages for Solution' after a Pull Request.

I'm hoping that there is a way to use the same Major and Minor version from the csproj file (6.1) but then auto-generate the patch version.

I've tried various tweaks using the guide below but to no avail.

https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/nuget-command-v2?view=azure-pipelines

CSPROJ File

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup Label="Globals">
        <SccProjectName>SAK</SccProjectName>
        <SccProvider>SAK</SccProvider>
        <SccAuxPath>SAK</SccAuxPath>
        <SccLocalPath>SAK</SccLocalPath>
    </PropertyGroup>

    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>

        <PackageId>MyProject.Libraries.Azure</PackageId>
        <Version>6.1.3</Version>
        <Authors>Me</Authors>
        <Company>MyCompany</Company>
        <Product>MyProject.Libraries.Azure</Product>
    </PropertyGroup>

    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
        <NoWarn>1701;1702;NU1701;</NoWarn>
        <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
        <WarningsAsErrors>NU1605</WarningsAsErrors>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Azure.Storage.Blobs" Version="12.18.0" />
        <PackageReference Include="Azure.Storage.Files.Shares" Version="12.16.0" />
        <PackageReference Include="Microsoft.Azure.Storage.Blob" Version="11.2.3" />
    </ItemGroup>

</Project>

YAML

trigger:
- main
- feature/*
- bugfix/*

pool:
  vmImage: 'windows-latest'

- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

- task: DotNetCoreCLI@2
  displayName: Generate Package
  inputs:
    command: 'pack'
    packagesToPack: '**/*.csproj'
    versioningScheme: 'off'
    arguments: '-c Release -o $(Build.ArtifactStagingDirectory)'

Solution

  • The automatic package versioning feature of DotNetCoreCli@2task doesn't support appending patch version to PackageVersion, but overwrites its value by /p:PacakageVersion like /p:PackageVersion=2023.10.12. See the introduction below on DotNetCoreCLI@2 - .NET Core v2 task .

    versioningScheme - Automatic package versioning

    string. Required when command = pack. Allowed values: off, byPrereleaseNumber (Use the date and time), byEnvVar (Use an environment variable), byBuildNumber (Use the build number). Default value: off.

    This task cannot be used with included referenced projects. If you choose Use the date and time, this will generate a SemVer-compliant version formatted as X.Y.Z-ci-datetime where you choose X, Y, and Z.

    If you choose Use an environment variable, you must select an environment variable and ensure it contains the version number you want to use.

    If you choose Use the build number, this will use the build number to version your package. Note: Under Options, set the build number format to $(BuildDefinitionName)_$(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r)

    Instead of automatically generating patch version, would you consider specifying VersionPrefix not Version in the project file and generating version-suffix in pipeline as introduced in dotnet pack command - .NET CLI? The package version would be $(VersionPrefix)-$(VersionSuffix)

    Kindly also note that the arguments input currently only accepts arguments for build, publish, run, test, and custom. If you would like to add arguments for a command not listed, use custom.

    Here is a sample for your reference.

    
    <Project Sdk="Microsoft.NET.Sdk.Web">
      <PropertyGroup>
          <TargetFramework>net6.0</TargetFramework>
          <ImplicitUsings>enable</ImplicitUsings>
          <IsPackable>true</IsPackable>
          <Nullable>enable</Nullable>
          <PackageId>MyProject.Libraries.Azure</PackageId>
          <VersionPrefix>6.1.3</VersionPrefix>
          <Authors>Me</Authors>
          <Company>MyCompany</Company>
          <Product>MyProject.Libraries.Azure</Product>
      </PropertyGroup>
        
    </Project>
    
    
    - task: DotNetCoreCLI@2
      inputs:
        command: 'custom'
        projects: '**/*.csproj'
        custom: 'pack'
        arguments: '-c Release -o $(Build.ArtifactStagingDirectory) --version-suffix $(Build.BuildId)'
    
    

    In case defining/replacing the value of Package Version that includes major, minor or patch versions is not an option for you, you might try and use Replace Tokens marketplace task to modify the .csproj file before packing.

    
    <Project Sdk="Microsoft.NET.Sdk.Web">
      <PropertyGroup>
          <Version>6.1.#{Build.BuildId}#</Version>
      </PropertyGroup>
    …    
    </Project>
    
    
    - task: replacetokens@5
      inputs:
        targetFiles: '**/*.csproj'
        encoding: 'auto'
        tokenPattern: 'default'
        writeBOM: true
        actionOnMissing: 'warn'
        keepToken: false
        actionOnNoFiles: 'continue'
        enableTransforms: false
        enableRecursion: false
        useLegacyPattern: false
        enableTelemetry: true
    - task: DotNetCoreCLI@2
      inputs:
        command: 'pack'
        packagesToPack: '**/*.csproj'
        versioningScheme: 'off'
    

    enter image description here

    Hope the information would be helpful.