I'm developing a number of .NET Core applications and I've met my current sprint commitments early. Until my next sprint begins, I'm using the slack to look into setting up a CI pipeline for my projects (this hasn't been hugely necessary as I'm the only person working on these projects, but it would be helpful to automate some of the stuff I'm currently doing manually).

However, I'm confused about the version numbering scheme I should adopt to support this.


In case it's helpful information, I'm attempting to set up this workflow using the following tools:

  • Visual Studio for code development
  • BitBucket to use as a remote repository
  • BitBucket Pipelines to use for CI builds
  • MyGet to use as the package feed and the location to push packages to during builds


All the technical setup for this has gone pretty smoothly so far but I'm stumped trying to figure out what version numbers I should assign to builds on different branches while still complying with semantic versioning and a GitFlow-style workflow.

Let's say that my previous release of some project X is 1.1.0. If I commit some change on develop and publish it to my repository (triggering a build), what version should be assigned to the NuGet package produced from that code?

Quoting nvie's recommendation here:

It is exactly at the start of a release branch that the upcoming release gets assigned a version number—not any earlier. Up until that moment, the develop branch reflected changes for the “next release”, but it is unclear whether that “next release” will eventually become 0.3 or 1.0, until the release branch is started. That decision is made on the start of the release branch and is carried out by the project’s rules on version number bumping.

This makes sense to me and would suggest that - until I create a release branch - I should stick with version numbering like e.g. 1.1.0-unstable0023. However, in semantic versioning schemes a version like this is taken to represent a release leading up to v1.1.0 i.e. an earlier build, which is not what I want.

To further complicate things, the dotnet CLI lets you assign the version suffix (e.g. during a CI build) but not any other parts of the version (the major, minor or patch number) - these are determined strictly from the project.json file corresponding to the project that's being built.

For what it's worth, here's what my bitbucket-pipelines.yml looks like for my first adapted project so far:

image: microsoft/dotnet:onbuild

      - step:

            # Generate build number
            # Note: may adapt this to use GitVersion.exe instead 
            - BUILD_NUMBER=`git log --oneline | wc -l`
            - echo "Build number':' ${BUILD_NUMBER} (will be appended to the generated NuGet package version)"

            # Install NuGet
            - apt-get update && apt-get install -y nuget

            # Add credentials
            - nuget setapikey $MYGET_API_KEY -source https://www.myget.org/F/company/api/v3/index.json -configFile NuGet.Config
            - nuget sources update -name "Company MyGet Feed" -source https://www.myget.org/F/company/api/v3/index.json -user $MYGET_USER -pass $MYGET_PASS -StorePasswordInClearText -configFile NuGet.Config

            # Restore and test projects
            - dotnet restore
            - dotnet test test/<<Company>>.<<Product>>Web.BaseTypes.Tests
            - dotnet test test/<<Company>>.<<Product>>Web.DeviceComponents.Tests
            - dotnet test test/<<Company>>.<<Product>>Web.Utility.Tests

            # Pack projects
            - dotnet pack --configuration $BUILD_CONFIGURATION --version-suffix=build$BUILD_NUMBER project.json src/<<Company>>.<<Product>>Web.BaseTypes
            - dotnet pack --configuration $BUILD_CONFIGURATION --version-suffix=build$BUILD_NUMBER project.json src/<<Company>>.<<Product>>Web.DeviceComponents
            - dotnet pack --configuration $BUILD_CONFIGURATION --version-suffix=build$BUILD_NUMBER project.json src/<<Company>>.<<Product>>Web.Utility
            - dotnet pack --configuration $BUILD_CONFIGURATION --version-suffix=build$BUILD_NUMBER project.json src/<<Company>>.<<Product>>Web.Utility.JsonPathGrammar

            # Push generated packages
            # TODO

Current versioning strategy

At the moment, I assign version numbers following this format for release builds:


I bump the version number as soon as I start a release branch, so any pre-release builds from a release branch will be generated just by appending a -betaxxxx suffix:

<major>.<minor>.<patch>-beta0000, <major>.<minor>.<patch>-beta0001, ...

If I need to produce a pre-release version and I haven't started a release branch yet, I will manually bump the version numbers in the relevant project.json files and produce builds like this:


Where xxxx is the padded number of commits on develop since the previous release.

If anyone has suggestions on a good version numbering scheme that works for .NET Core projects being adapted for a CI/CD workflow, I'd appreciate that a lot.

  • What are your specific requirements? Microsoft uses Major.Minor.Build.Revision. Would that satisfy your CI/CD workflow? – Robert Harvey Feb 14 '17 at 16:27
  • @RobertHarvey I've updated my post to describe my current versioning scheme. I generally stick with Major.Minor.Patch for release versions. – Tagc Feb 14 '17 at 16:34
  • Alright. Looks like your scheme is very close to the Microsoft scheme (except for the beta suffix, which I would argue is not really necessary). What problems remain? – Robert Harvey Feb 14 '17 at 16:36
  • @RobertHarvey That reference is quite old and isn't relevant for .NET Core projects. It also doesn't answer my question about what the version number for builds on the develop branch should be. – Tagc Feb 14 '17 at 16:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.