Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] GitVersion no longer calculates version correctly for mainline mode #2441

Closed
techgeek03 opened this issue Oct 29, 2020 · 25 comments
Closed
Labels

Comments

@techgeek03
Copy link

techgeek03 commented Oct 29, 2020

Describe the bug
Since version 5.5 when using Mainline mode GitVersion is not calculating the version at all and it gives ether the value in next-version or the version from the last tag.

Expected Behavior

To have correct version

Actual Behavior

Version is stacked at next-version or the version from the last tag

Steps to Reproduce

Here is a simple GitVersion.yaml file I have been using

mode: Mainline
next-version: 1.0.0
branches:
  feature:
    tag: beta.{BranchName}
ignore:
  sha: []
merge-message-formats: {}

After many commits in master branch this is the output of GitVersion

INFO [10/29/20 23:06:38:48] Dumping commit graph:
INFO [10/29/20 23:06:38:64] *   3cdb26c 23 minutes ago  (HEAD -> master)
|\
| * 41f9c14 24 minutes ago  (feature/y2)
|/
*   9367673 73 minutes ago
|\
| * eb5c77a 76 minutes ago  (feature/test)
|/
* f957b18 78 minutes ago  (tag: 1.1.0)
* 318e307 79 minutes ago

INFO [10/29/20 23:06:38:98] Using latest commit on specified branch
INFO [10/29/20 23:06:39:02] Running against branch: master (3cdb26cf21767b34a3ecc65662fa00717857100a)
INFO [10/29/20 23:06:39:02] Begin: Calculating base versions
  INFO [10/29/20 23:06:39:07] NextVersion in GitVersion configuration file: 1.0.0 with commit count source External Source
  INFO [10/29/20 23:06:39:16] Git tag '1.1.0': 1.1.0 with commit count source f957b18b8557ba7d40a4e7a1a72f160c250e386f
  INFO [10/29/20 23:06:39:18] Found multiple base versions which will produce the same SemVer (1.1.1), taking oldest source for commit counting (Git tag '1.1.0')
  INFO [10/29/20 23:06:39:18] Base version used: Git tag '1.1.0': 1.1.0 with commit count source f957b18b8557ba7d40a4e7a1a72f160c250e386f
  INFO [10/29/20 23:06:39:18] End: Calculating base versions (Took: 158.30ms)
  INFO [10/29/20 23:06:39:18] Begin: Using mainline development mode to calculate current version
    INFO [10/29/20 23:06:39:20] Found possible mainline branches: master
    INFO [10/29/20 23:06:39:20] Mainline for current branch is master
    INFO [10/29/20 23:06:39:20] 4 commits found between f957b18b8557ba7d40a4e7a1a72f160c250e386f and 3cdb26cf21767b34a3ecc65662fa00717857100a
  INFO [10/29/20 23:06:39:21] End: Using mainline development mode to calculate current version (Took: 23.36ms)
{
  "Major":1,
  "Minor":1,
  "Patch":0,
  "PreReleaseTag":4,
  "PreReleaseTagWithDash":"",
  "PreReleaseLabel":"",
  "PreReleaseNumber":"",
  "WeightedPreReleaseNumber":60000,
  "BuildMetaData":"",
  "BuildMetaDataPadded":"",
  "FullBuildMetaData":"Branch.master.Sha.3cdb26cf21767b34a3ecc65662fa00717857100a",
  "MajorMinorPatch":"1.1.0",
  "SemVer":"1.1.0",
  "LegacySemVer":"1.1.0",
  "LegacySemVerPadded":"1.1.0",
  "AssemblySemVer":"1.1.0.0",
  "AssemblySemFileVer":"1.1.0.0",
  "FullSemVer":"1.1.0",
  "InformationalVersion":"1.1.0+Branch.master.Sha.3cdb26cf21767b34a3ecc65662fa00717857100a",
  "BranchName":"master",
  "EscapedBranchName":"master",
  "Sha":"3cdb26cf21767b34a3ecc65662fa00717857100a",
  "ShortSha":"3cdb26c",
  "NuGetVersionV2":"1.1.0",
  "NuGetVersion":"1.1.0",
  "NuGetPreReleaseTagV2":"",
  "NuGetPreReleaseTag":"",
  "VersionSourceSha":"f957b18b8557ba7d40a4e7a1a72f160c250e386f",
  "CommitsSinceVersionSource":4,
  "CommitsSinceVersionSourcePadded":"0004",
  "UncommittedChanges":1,
  "CommitDate":"2020-10-29"
}
  INFO [10/29/20 23:06:39:26] Done writing

I tried using main as default branch as well but it had the same problem.

Context

We are using GitVersion in all our Azure DevOps pipelines and we have configured the pipeline task to use the latest version of GitVersion, so currently all our pipelines are reporting wrong versions.

Your Environment

  • Version Used: 5.5
  • Operating System and version (Windows 10, Ubuntu 18.04): Windows, OS X, Ubuntu 18.04
@techgeek03 techgeek03 added the bug label Oct 29, 2020
@techgeek03 techgeek03 changed the title [Bug] GitVersion no longer calculates version correctly for mainline [Bug] GitVersion no longer calculates version correctly for mainline mode Oct 29, 2020
@asbjornu
Copy link
Member

Thanks for the bug report. Are you able to submit a failing test in a pull request that reproduces this behaviour?

@techgeek03
Copy link
Author

Sure, I will try to set up something :)

@techgeek03
Copy link
Author

techgeek03 commented Oct 31, 2020

While setting up the test's to verify the bug I actually found the actual cause of this bug. It is the use of next-version. It looks like, when using next-version, the version is wrongly calculated.
However this was not the case in the previous version 5.3.7.
Navigating in the NextVersionCalculatorTests there is actually a test MergeIntoMainline that confirm the behaviour I'm explaining. And it looks like is introduced with #2356 that relates to #2335

So, my question now is this the actual behaviour? And if yes then maybe the documentation needs to be more explicit and explain better.

@asbjornu
Copy link
Member

asbjornu commented Nov 1, 2020

If you remove next-version, do you get the expected version number? I think #2356 was correct in introducing support for next-version, but if our documentation needs adjustment to reflect this fact, we would highly appreciate a PR that does so.

@techgeek03
Copy link
Author

If you remove next-version, do you get the expected version number?
Yes, when next-version is not in the config file then the version is calculated correctly.

I can update the documentation but I first want to confirm the behaviour of next-version in context of Mainline mode.

At present, to me, it looks like next-version should only be used when you want the code coming from a branch into the main branch to have the value of next-version but you don't want to use the commit message to do that. However, and this is very importnat, the next commit coming in the main branch must remove next-version from config, otherwise it will again get the same next-version value. Am I correct? :)

If that is the case, I don't see much value in next-version in Mainline mode since it could lead to potential confusion. I would then rather just use the commit message. :)

@hallgeirl
Copy link

hallgeirl commented Nov 2, 2020

I can confirm this issue as well - this is a clear change in behavior from 5.3.x and earlier. We had to continue using the older versions since we use next-version.

Was it a conscious choice, or is it a bug? :-)

@asbjornu
Copy link
Member

asbjornu commented Nov 2, 2020

I was of the impression that until 5.5, next-version wasn't really supported with mode: Mainline at all and thus don't understand how the addition could break anything. I'm sorry for not being more knowledgeable about this, but I don't use either next-version, Mainline or commit message counting myself, so please bear with me.

@techgeek03, how were you using next-version in combination with mode: Mainline before 5.5?

At present, to me, it looks like next-version should only be used when you want the code coming from a branch into the main branch to have the value of next-version but you don't want to use the commit message to do that. However, and this is very importnat, the next commit coming in the main branch must remove next-version from config, otherwise it will again get the same next-version value. Am I correct? :)

Yes, this sounds like how next-version works regardless of mode.

If that is the case, I don't see much value in next-version in Mainline mode since it could lead to potential confusion. I would then rather just use the commit message. :)

Then don't use next-version? 🤷‍♂️

@clawrenceks
Copy link

There is a definite change in behaviour with regards to main mode here. Currently affecting all of my (over 100) pipelines. For now, the only choice for me is a downgrade back to version 5.3.7

@asbjornu
Copy link
Member

asbjornu commented Nov 3, 2020

Can you please explain how you used next-version in combination with mode: Mainline before 5.5, @clawrenceks?

@clawrenceks
Copy link

clawrenceks commented Nov 3, 2020

@asbjornu Sure - for us the next-version property serves a single purpose, we use it as part of initializing a repo into our GitVersion process. When we on board a new repo, the first version used by GitVersion will come from the next-version property.

From then on in, the next-version property has been ignored in our experience. At the end of our build pipeline we tag the commit using the version calculated by GitVersion, this then becomes the base version detected the next time the build is run. We squash all commits into master from PRs and allow the semver to be incremented by merge message only. When there is no specific merge message, we expect patch to be incremented, otherwise we use +semver: minor or +semver: major to bump a major or minor version on merge.

Since the change to 5.5, I am now seeing that when committing with no merge message, the version was not actually incremented at all - the version remained as per the last tag in the repo.

Our very simple config, which we have been using for a long time, is shown below.

mode: Mainline
commit-message-incrementing: MergeMessageOnly
next-version: 0.1.0
branches:
  feature:
    regex: feature(s)?[/-]
    mode: ContinuousDeployment
    tag: useBranchName
    increment: None
    prevent-increment-of-merged-branch-version: true
    track-merge-target: false
  pull-request:
    regex: (pull|pull\-requests|pr)[/-]
    mode: ContinuousDeployment
    tag: PullRequest
    increment: None
    prevent-increment-of-merged-branch-version: true
    track-merge-target: false
    track-merge-target: false
  hotfix:
    regex: (hotfix(es)?|config)[/-]
    mode: ContinuousDeployment
    tag: useBranchName
    increment: None
    prevent-increment-of-merged-branch-version: true
    track-merge-target: false
ignore:
  sha: []

@asbjornu
Copy link
Member

asbjornu commented Nov 3, 2020

Thanks, @clawrenceks. From my understanding, the old behaviour seems like an oversight in the initial implementation of Mainline, then. next-version is not the same as initial-base-version (which doesn't exist). next-version and git tag are interchangeable and semantically means almost the same for GitVersion. That should apply regardless of which mode you use.

For everyone having problems with next-version in combination with mode: Mainline I would suggest to just remove next-version from GitVersion.yml and potentially add a tag indicating the same version at an old commit just to get the base version for computation correct.

@techgeek03
Copy link
Author

@asbjornu In our case we used next-version only as a starting point for new repos to get a default base version and be aligned across the team. Yes we decided to remove next-version but having 50+ repo's makes this issue annoying :)

Intentionally or unintentionally it is a clear change of behaviour and in my view this constitutes as a breaking change, but since there is a workaround it is fine :)

@clawrenceks
Copy link

clawrenceks commented Nov 3, 2020

I have to agree on the breaking change. For now, I am going to test on one repo and if it works, I will go and update the other 100+ repos that have a GitVersion configuration. Seems like the version number of GitVersion should be bumped to 6.0.0 if this change is going to remain and the docs updated accordingly though.

@asbjornu
Copy link
Member

asbjornu commented Nov 3, 2020

If we knew beforehand that next-version combined with mode: Mainline was in use and a change in their combined behavior would break things, we would of course have postponed #2356 to 6.0. But we didn't, so we didn't.

What we can do now is either document the new behavior and discourage the use of next-version as a "base version" (which it was never intended to mean, regardless of mode) or revert #2356 in a 5.5.1 release. Seeing how the existing use of next-version combined with Mainline in my opinion is wrong, I prefer the former.

@clawrenceks
Copy link

clawrenceks commented Nov 3, 2020

That won't do anything to mitigate this issue causing problems for potentially many other people. At least if you bump the version, it could prevent peoples pipelines from automatically using a broken version - giving them chance to read about the breaking change before they move to the next major version.

@FISHMANPET
Copy link
Contributor

Just discovering this, as the author of the change that wrecked all this havoc.

The reason I wrote this change is that, as far as I could figure out, next-version didn't work in Mainline mode. My use case was the same as @clawrenceks: boot strap a project with an initial version before it had any tags in Git to reference. You can see in #2335 the behavior I was seeing before. I wanted the next released version to be 1.0.0, and so I wanted my prerelease versions to be 1.0.0-branch01, 1.0.0-branch02, etc. But it was generated 1.0.1-branch01, 1.0.1-branch02, etc. I believe that when I would run against master with next-version set to 1.0.0 that it would properly generate 1.0.0, but I needed those pre-release versions to be correct. The code was treating next-version as the current version when doing prerelease builds, which would produce an incorrect version (by incrementing that next-version rather than using it directly).

Walking through the code, I reasoned that, well, if you're specifying a next-version, then it must because you want the next-version to be that, and if you didn't want the next version to be the version specified, then you wouldn't include it.

Maybe it would have made more sense to introduce something like initial-base-version and only use that value if a tag can't be found, but ultimately as I walked through the code it was pretty clear that the existing behavior was incorrect in the default case. Sorry for all the trouble I've caused 😁

@asbjornu
Copy link
Member

The fact that next-version behaved like initial-base-version was a bug and it's good that it is now fixed. 👍🏼

@ghost
Copy link

ghost commented Feb 25, 2021

@asbjornu I just came across this issue (after spending 2h of debugging this), and we pretty much have the same issue where the version gets reset to whatever next-version is set to. We also used it as a base version for all the projects with mainline, much like @clawrenceks. Swapping to tags isn't an option for us, since the repository contains more than one project with independent versions, and the fact that we build and may release after every PR makes tagging them a horrible experience for many individual projects.

I was under the impression that this combination of mainline and next-version was how it was supposed to work. Can we get @FISHMANPET's suggestion to have an initial-base-version or something similar?

@asbjornu
Copy link
Member

@b10-dslappendel sorry, but next-version should never have been base-version or else we would have named the property base-version. Since Git has the appropriate mechanisms to fix this by introducing a tag I see no reason to do anything about this in GitVersion, with configuration or otherwise. I'm therefore closing this as it's not a current bug in GitVersion.

@ghost
Copy link

ghost commented Feb 25, 2021

I'm very sorry to hear that, but as I said, tags are just not reasonable to us. Since mainline is used where the master branch is the release branch, and the versions are calculated based on a base version, I don't see how next-version is even remotely usable anymore.

Please consider this a feature request for a base-version, because we're now forced to change a lot of internal projects, or stay on 5.3.7. However, that version seems to also have a bug related to Error: AssemblyInfoFilename file not found at AssemblyInfo.cs, so we cannot use that version either (and even 5.6.6 still seems to have that issue as well, only the older Azure DevOps task doesn't have it, which I believe is 5.0.1?).

@asbjornu
Copy link
Member

@b10-dslappendel, why is adding base-version: <base-version> to GitVersion.yml (a feature that does not exist) more reasonable than doing git tag <base-version> $(git rev-list --max-parents=0 HEAD)? Both options involve the same number of operations, with git tag doing it in a canonical, best-practice manner native to Git, while relying on base-version or next-version inside GitVersion.yml is doing it in a proprietary way with the former based on a non-existing feature and the latter based on a bug that is now fixed.

@ghost
Copy link

ghost commented Feb 25, 2021

Alright, I probably let my frustration go too far because of the wasted hours I had today, and therefore didn't notice that you're saying that a single tag can serve as a base version. I noticed that the deprecated GitVersion DevOps task somehow started failing this week on the Ubuntu agent, whereas it still worked last week, started trying to fix it, noticed that the task had been deprecated and had been renamed, installed that, still didn't work, came across another (this time Windows) agent issue that I already mentioned, and also somehow had this versioning change. Forgive me.

So, can you confirm that using a tag on a commit somewhere in history will allow the version calculation to work again, in a monorepo with projects that have independent versioning, combined with Azure DevOps that auto-tags builds with a project-prefixed version tag with the version that GitVersion puts out? For context, we're using git-filter-repo to strip out commits that have nothing to do with a specific project folder, otherwise we would end up similar versions.
So as an example, we may have tags like:

  • ProjectA/2.1.2
  • ProjectA/2.1.3
  • ProjectA/2.1.4-some-branch.1
  • ProjectB/1.0.0
  • ProjectB/1.1.0

Because if that works, we don't have to tag stuff ourselves manually. That's the main reason why I asked for a base-version, because having to do that is really a blocker.

@asbjornu
Copy link
Member

Alright, I probably let my frustration go too far because of the wasted hours I had today, and therefore didn't notice that you're saying that a single tag can serve as a base version.

Okay, no problem.

So, can you confirm that using a tag on a commit somewhere in history will allow the version calculation to work again, in a monorepo

No, sorry, GitVersion doesn't support monorepo.

Because if that works, we don't have to tag stuff ourselves manually. That's the main reason why I asked for a base-version, because having to do that is really a blocker.

For monorepo, I can see how base-version in several GitVersion.yml files would be useful. But monorepo itself is something GitVersion explicitly does not support, so implementing features that makes GitVersion more usable for monorepo is a slippery slope.

Catering to monorepo features eventually leads us into having to explicitly support every monorepo feature, something that in the end will require a massive rearchitecture and rewrite of GitVersion for a use-case none of the current maintainers of GitVersion use themselves. Unless someone with monorepo requirements invests the time required to both do the initial work and commit to maintaining it "forever", GitVersion can't support it. Sorry.

@ejdre-vestas
Copy link

Hi,

Just wanted to mention that the documentation on https://gitversion.net/docs/reference/configuration reflects what was mentioned here but the documentation on https://gitversion.net/docs/reference/version-increments still says next-version serves as a base version.

@asbjornu
Copy link
Member

asbjornu commented Mar 6, 2023

@ejdre-vestas, thanks for pointing that out. It's a miss that needs fixing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants