14

I have a Visual Studio project which is built as a NuGet lib package. But every time I publish the package, I have to change the version number manually. That's a prone-to-error work. I'd like to generate and increase the package version number automatically.


I found GitVersion tool to solve this problem. And I also found some semantic versioning blogs to explain the package version of continuous delivery.


But unfortunately, The GitVersion package does not work correctly for me.

  • It gives me an error that AssemblyVersionAttribute is duplicated.
  • If I add <GenerateAssemblyInfo>false</GenerateAssemblyInfo> into the csproj file, It will do nothing and the package version will be 0.0.0.0.

Maybe the reason is that I'm using the new csproj format. See here to view the csproj file and the file looks like this:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net45;net47;netstandard2.0</TargetFrameworks>
  </PropertyGroup>
</Project>

Any reply is appreciated.


UPDATE:

I find that there is an issue to mention my problem: Gitversion Task for VS2017-style csproj · Issue #1349 · GitTools/GitVersion. I'm trying the new solution.

walterlv
  • 2,366
  • 13
  • 73
  • Is this only for local use? Generally, it should be the job of the remote builder (Jenkins/Travis etc.) to do it – information_interchange Apr 11 '18 at 02:57
  • @information_interchange It is mainly used to be used via Jenkins. – walterlv Apr 11 '18 at 03:09
  • There is a useful tool called GitVersion that computes versioning based on git tags – Aluan Haddad Apr 11 '18 at 03:19
  • @AluanHaddad As I mentioned in my question, I've tried GitVersion but it doesn't work correctly. I guess that it may not support the new *.csproj file format of .NET Core. – walterlv Apr 11 '18 at 03:25
  • @walterlv sorry missed that – Aluan Haddad Apr 11 '18 at 03:27
  • There is a Jenkins plugin called "change assembly version", have you taken a look? – information_interchange Apr 11 '18 at 03:45
  • @information_interchange Thanks, I'm reading it. https://wiki.jenkins.io/display/JENKINS/Change+Assembly+Version – walterlv Apr 11 '18 at 06:24
  • 3
    @AluanHaddad GitVersion worked! Sorry about that I used an incorrect config file. (I'll contribute to the official document to mention it.) – walterlv Apr 11 '18 at 09:51
  • @walterlv, you can convert your comment to the answer with more details info and post an [answer](https://stackoverflow.com/help/self-answer) below. so this can be beneficial to other community members reading this thread. – Leo Liu Apr 11 '18 at 09:56
  • @LeoLiu-MSFT Thanks for your tip and I've found an official article here https://stackoverflow.com/help/self-answer. I'm doing more to confirm my solving and will post my answer later. – walterlv Apr 11 '18 at 10:38
  • Note that that csproj needs to have `TargetFrameworks`, not `TargetFramework`, to target multiple environments. – Zastai Apr 12 '18 at 15:26
  • @Zastai Yahhh, that's a mistake only for this question. thx. And I've fixed it. – walterlv Apr 12 '18 at 15:33

3 Answers3

3

Not sure about Jenkins, but it should be able to generate an incremental number or timestamp by itself that can be accessed via an environment variable on your build pipeline.

I think the most flexible way is to add a PackageVersion tag with a placeholder to your csproj that your build pipeline can then change:

  <PropertyGroup>
    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
    <PackageVersion>$(PackageVersion)</PackageVersion>
  </PropertyGroup>

So, on your build pipeline, you just pass the version, for example:

dotnet build -p:PackageVersion=$(BUILD_TIMESTAMP)
thepirat000
  • 12,362
  • 4
  • 46
  • 72
  • If all the version values come from build pipeline, how can it be built correctly in every developer's PC? – walterlv Apr 12 '18 at 20:18
  • @walterlv It works because the version of the nupkg defaults to the tag when the <[PackageVersion](https://learn.microsoft.com/en-us/dotnet/core/tools/csproj#packageversion)> tag is empty. The will appear as empty on the dev PC and it will default to the number, and if there is no tag it will default to 1.0.0 – thepirat000 Apr 13 '18 at 05:00
3

We can trigger the GitHub Action by Git tag pushed and we can read the Git tag name as the version. And then we can generate the NuGet package with this version.

There is a dotnet tool that can read Git tags as a version and write it to the version file.

Before using it, we should create the version file and import the version file.

We should use dotnet to install the dotnetCampus.TagToVersion tool and use the tool to write the Git tag to version file.

The step 1:

Adding the Directory.Build.props file to repo folder.

Writing the code to the Directory.Build.props file.

<Project>
  <Import Project="build\Version.props" />
</Project>

The step 2:

Making a folder named build and adding the Version.props file to this folder.

Writing the code to the build\Version.props file.

<Project>
  <PropertyGroup>
    <Version>1.0.5</Version>
  </PropertyGroup>
</Project>

The step 3:

Writing a GitHub Action configuration file in .github\workflows folder, for example create the .github\workflows\push tag and pack nuget.yml file

Making the Action trigger by tag push.

on:
  push:
    tags:
    - '*' 

Writing the tag as version by dotnet tool.

    - name: Install dotnet tool
      run: dotnet tool install -g dotnetCampus.TagToVersion

    - name: Set tag to version  
      run: dotnet TagToVersion -t ${{ github.ref }}

Building the package

# Build and publish

    - name: Build with dotnet
      run: dotnet build --configuration Release

    - name: Install Nuget
      uses: nuget/setup-nuget@v1
      with:        
        nuget-version: '5.x'

    - name: Add private GitHub registry to NuGet
      run: |
        nuget sources add -name github -Source https://nuget.pkg.github.com/ORGANIZATION_NAME/index.json -Username ORGANIZATION_NAME -Password ${{ secrets.GITHUB_TOKEN }}
    - name: Push generated package to GitHub registry
      run: |
        nuget push .\bin\release\*.nupkg -Source github -SkipDuplicate
        nuget push .\bin\release\*.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NugetKey }} -NoSymbols 

See https://github.com/dotnet-campus/dotnetCampus.TagToVersion

lindexi
  • 4,182
  • 3
  • 19
  • 65
2

Actually GitVersionTask is not hard to use. All that you should do is these things below:

  1. Install GitVersionTask from NuGet.
  2. Add a configuration file named GitVersion.yml with some key-values.
  3. Add a tag to your branch.
  4. Build.

After doing that, you can find your output dll file contains a semantic version.


I'm answering my own question because I just wrote the wrong config file name. So it did not work correctly.


This is my configuration file:

mode: ContinuousDelivery
increment: Inherit
tag-prefix: '[vV]'
source-branches: ['master', 'develop', 'hotfix']
branches:
    master:
        regex: master$
        mode: ContinuousDelivery
        tag: ''
        increment: Patch
        prevent-increment-of-merged-branch-version: true
        track-merge-target: false
        tracks-release-branches: false
        is-release-branch: true
    release:
        regex: r(elease$|(eleases)?[-/])
        mode: ContinuousDelivery
        tag: beta
        increment: Patch
        prevent-increment-of-merged-branch-version: true
        track-merge-target: false
        tracks-release-branches: false
        is-release-branch: true
    feature:
        regex: f(eatures)?[-/]
        mode: ContinuousDeployment
        tag: alpha
        increment: Minor
        prevent-increment-of-merged-branch-version: false
        track-merge-target: false
        tracks-release-branches: false
        is-release-branch: false

I've posted this configuration file content here: Automatically increase the semantic version using GitVersion - walterlv

walterlv
  • 2,366
  • 13
  • 73