GitVersion: [BUG] GitVersion calculating wrong version when building a tag

I am running GitVersion 5.1.3 on Windows Server 2019 connecting to BitBucket Cloud, and using TeamCity and its GitVersion metarunner to generate version numbers.

With a particular GitFlow repo that I have, I am building on support/12.4 and everything is great, GitVersion calculates the version number as e.g. 12.4.11-beta0003. However, when I tag that commit which I have just built as e.g. 12.4.12, then GitVersion completely ignores that tag and grabs the version number from develop, giving me a tag something like 13.4.0-tags-12-4-11.1+8.

It only does this on the build agent; when I run GitVersion on my desktop then it calculates the version correctly.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 8
  • Comments: 38 (24 by maintainers)

Commits related to this issue

Most upvoted comments

The Fix for #1743 introduced a check wherein if the tagged version is semantically less than the pre-release version, it will use the pre-release version instead.

This normally wouldn’t trigger, except that when the detached head is normalized by the build server code, it will create a branch called tags/v1.0.2 which doesn’t have a matching configuration, and causes a pre-release version to be created.

This is ONLY an issue if your build automation triggers on the tag creation and tries to build the tag directly, not when you build the commit directly. The difference is the setting of the source branch through the environment variable, that then gets picked up by the build server adapter, overriding the current branch name.

I have found another solution which is less invasive. TaggedCommitVersionStrategy now prefers to return only the versions of tags on the current commit. If there aren’t any, it will return the tags from history. That makes all tests (incl the new one) pass for me locally. PR #2413 updated.

I think I have found the root cause. Here are my smallest steps to reproduce (powershell script):

git init remote
cd remote
git commit --allow-empty -m "init master"
git checkout -b develop
git commit --allow-empty -m "new feature"
git checkout master
git tag -a -m "Release 1.0" v1.0
git commit --allow-empty -m "hotfix"
git tag -a -m "Release 1.0.1" v1.0.1

cd ..
git clone remote local
cd local
git checkout v1.0.1
$Env:TF_BUILD=$true
$Env:BUILD_SOURCEBRANCH="refs/tags/v1.0.1"
gitversion.exe /nocache /output buildserver

Because the branch ‘tags/v1.0.1’ or headless checkout do not have branch configuration in GitVersion.yml, it will try to inherit the configuration from a parent branch. But the log output shows:

WARN [09/28/20 21:47:15:05] Failed to inherit Increment branch configuration, no branches found.

Now, GitVersion tries to find the first branch in the set of {develop, master}:

var chosenBranch = repository.Branches.FirstOrDefault(b =>
    Regex.IsMatch(b.FriendlyName, developBranchRegex, RegexOptions.IgnoreCase) ||
    Regex.IsMatch(b.FriendlyName, masterBranchRegex, RegexOptions.IgnoreCase));

Repository branches are sorted and the ‘d’ comes before the ‘m’ so develop configuration is selected. And the default increment for develop is Minor. Next GitVersion will find all tags that are in the history of the commit. Every version tag is checked if it should be incremented, based on whether HEAD itself is tagged or not.

var shouldUpdateVersion = version.Commit.Sha != context.CurrentCommit.Sha;

There are 2 tags in the history, where 1.0.1 is pointing to the same commit as HEAD and the older 1.0 to a previous commit. This means that 1.0 is marked for increment, effectively a Minor increment based on the develop configuration, so it becomes a set of {1.1, 1.0.1}. Now GitVersion takes the max

var maxVersion = baseVersions.Aggregate((v1, v2) => v1.IncrementedVersion > v2.IncrementedVersion ? v1 : v2);

And version 1.1 is selected.

As far as I can see, GitVersion should first try to find the max from the tag(s) that are directly pointing to the same commit as HEAD. If there are none, then find the max of the remaining tags.

I am having the same issue. The tag 1.0.1-beta.1 build is creating a version 1.1.0-tags-1-0-1-beta-1.1.

@gerwinjansen, to answer your questions:

  1. No, this is a bug in the normalization code that needs to be fixed. To isolate and make it easier to avoid such bugs in the future, we are going to make normalize an explicit command that needs to be run in GitVersion v6.
  2. Until #2411 is merged, GitVersion expects a branch to be checked out regardless of other repository metadata. That should now change, though, so the tag is just used directly and no further calculation is performed.

Here’s a log for a GitHub Actions build for refs/tags/v19.2.1 that got versioned 19.3.0-tags-v19-2-1.1+1. I have edited the log to remove business information; hopefully this has not harmed its usefulness.

https://gist.github.com/wjrogers/45a7c8699c36fd429a864906bcd6fe95

It would be interesting to find which commit or PR introduced this change, because it means we don’t have tests that cover this use-case, again meaning the fact that this used to work might have been more by accident than by explicit design. I agree that checking out a tagged commit should give the build the version number of the tag, though. A PR with a RepositoryFixture test that proves this is a problem would be helpful. Even more helpful would be fixing the same problem in the PR. 😅