I'm trying to use gitversion for internal nuget packages that are just utility classes. Essentially if a PR gets merged then the package should be released and I don't want to deal with tagging. I'd like the build server to just iterate the patch number automatically without a pre-release tag otherwise nuget will act weird with update in visual studio. I've try the following settings expecting it to work and it removed the last number as that is the pre-release but I'm not sure how I can get it to auto increment the patch as a result.
assembly-versioning-scheme: MajorMinorPatch
mode: ContinuousDeployment
tag-prefix: '[vV]'
continuous-delivery-fallback-tag: ''
major-version-bump-message: '\+semver:\s?(breaking|major)'
minor-version-bump-message: '\+semver:\s?(feature|minor)'
patch-version-bump-message: '\+semver:\s?(fix|patch)'
legacy-semver-padding: 4
build-metadata-padding: 4
commits-since-version-source-padding: 4
commit-message-incrementing: Enabled
branches:
master:
mode: ContinuousDeployment
tag: ''
increment: Patch
prevent-increment-of-merged-branch-version: true
track-merge-target: false
breaking changes don't happen that often and would be manually tagging with a major version increment.
I also have this requirement - are there any settings that would make this work?
Unfortunately not. GitVersion has been built to enable Semantic Versioning, I was talking to @gep13 about this at NDC. A semver: false setting needs to be introduced which turns off the semantic versioning logic.
No idea how much work this would be but happy for someone to give it a try and submit a PR.
The other thing is why not just use the build server auto increment and just version via the build server?
Actually, you can use GitVersion /output json then manually construct the version number from the variables returned.
Hi, @JakeGinnivan Thanks for the response. I am slightly confused as to why my requirements are considered not SemVer:
My setup is as follows, we are creating nuget packages:
Which part of the above is not semver?
@JakeGinnivan RE using the build server to do versioning - the issue with this is that we like to have everything in source control, and to have repeatable builds. So that it is possible for a developer to checkout a specific version of the source code and run the build and produce identical artifacts.
Hrrm interesting. Maybe a preconception that you would not automatically deploy master when you merge to master. Do pull requests also update the readme or something with the breaking changes? If you are deploying every merge commit to master then yep, that would be SemVer.
The problem with this is it will get slower and slower over time because GitVersion will have to scan the entire repo for every merge commit to the current branch, make sure it only includes merge commits to that actual branch (ie merged pull/1 into 'master'), and calc the version.
Currently GitVersion can use tags and the merge base of those tags to limit the amount of history it has to scan. Any thoughts on a nice way to do this at a conceptual level?
@JakeGinnivan said...
I was talking to @gep13 about this at NDC. A semver: false setting needs to be introduced which turns off the semantic versioning logic.
Part of me still thinks this a good idea, but I also flip flop on it.
This would essentially be a commit counter, since the last release, and it would append to a pre-defined portion of the build number, similar to what you would do in say TeamCity.
This would essentially be a commit counter, since the last release
Thats the problem. Without tags there is no previous release. It needs to calculate since the beginning of time? Maybe im missing something
Could it not cache the calculated version for each commit and then use that? Then you would only need to calculate from the beginning on a clean checkout.
@JakeGinnivan said... I was talking to @gep13 about this at NDC. A semver: false setting needs to be introduced which turns off the semantic versioning logic.Part of me still thinks this a good idea, but I also flip flop on it.
I agree with @stocksr: a "semver: false" setting is not the appropriate solution to his scenario, because his scenario IS semver; and in fact I would argue that it is closer to Continuous Delivery than what GitVersion currently defines as CD.
I was planning on following a similar approach when I first picked up GitVersion. For now I am working around the problem by tagging, but I would prefer a fix inside GitVersion.
That said, getting a commit counter from git is easy and fast, even for very large repos: git rev-list master --count (or for all commits on a particular branch: git rev-list branch ^master --count).
We are doing the same thing - PR's merged to master are officially "released". Breaking changes would be a major version change and would just be a new tag.
While I've thought about doing this manually with a composition of variables - it gets complicated when you want to do the pull-request versioning as well and if for whatever reason we have a separate branch running. I can't and don't have a business case for the other branches but its kind of a fail safe IMO. But if I have to write a set of scripts to do it - it'd be virtually a replacement for GitVersion.
The desire is something like master automatically producing this from master merges:
- Commit 1 = 1.0.0 (tagged 1.0.0)
- Commit 2 = 1.0.1
- Commit 3 = 1.0.2
- Commit 4 = 1.0.3
While GitVersion can also handle pre-release the PR and other branches - something like:
- Commit 1 = 1.0.0 (tagged 1.0.0)
- Pull Request 1 = 1.0.0.PR-1
If our source was on github it'd be very easy to use a commit hook to automatically tag merges to master based on the last merge - but it'd be a relatively blunt tool solution and a bit hacky.
and in fact I would argue that it is closer to Continuous Delivery than what GitVersion currently defines as CD
The way GitVersion modelled Continuous delivery is that any number of commits can build up, then the product owner or someone from the business decides that there is enough functionality to deploy and hits the button. Because there is no way for gitversion to know this has happened other than tags it is modelled that way.
because his scenario IS semver
Yep I see that, as I said before it is much closer to continuous deployment because each release will only ever contain either a bug fix, breaking change or feature.
That said, getting a commit counter from git is easy and fast
GitVersion doesn't just do commit counting unfortunately, it tracks quite a few sources to infer semantic versions flowing through git workflows.
Maybe another solution is that only major and minor releases are tagged because they are relevant to SemVer. Then we can just do commit counting since the last significant change. I am not sure what would trigger this, maybe a new command line argument could be introduced into GitVersion which will tag a branch if it's SemVer has changed? That would then involve GitVersion needing write permission to push the tag.
I am not trying to block a solution here, I am happy to receive a PR for this.
@Ashtonian in that example, GitVersion couldn't use other strategies like +semver: minor in commit messages, right?
The reason this is hard is because GitVersion is predictive about it's version number, i.e it calculates what the _next_ release number will be. Because it is being predictive GitVersion needs to understand _when_ that release has actually happened, hence tagging. Merging is not a release, something picks up that merged commit and makes a decision that that commit should be released because it is on master. This is why GitVersion requires tags, it is a communication mechanism from from release process back to source control that the build artifacts have actually been deployed somewhere.
I would _love_ to see this solved because I have seen this issue many times before. Thoughts on implementation strategies are welcome, and pull requests even more so.
@JakeGinnivan I'm not familiar with the idea of that strategy would you be able to give me an example?
Are you talking about incrementing the version from a commit message? Tags would still be used for major versions as gitversion cannot be aware of a "breaking" change.
@JakeGinnivan said Merging is not a release, something picks up that merged commit and makes a decision that that commit should be released because it is on master. This is why GitVersion requires tags, it is a communication mechanism from from release process back to source control that the build artifacts have actually been deployed somewhere.
What is the version number embedded in those artifacts? the pre-release version number that GitVersion predicts or the actual release version number? do you suggest that we re-run the build process after tagging the commit?
@JakeGinnivan said "This is why GitVersion requires tags"
I can kind of see your point here - however due to "some external reason that is unchangeable" I am not able to use tags for this. Are there any other ways that I could provide GitVersion this information. e.g. Text in the commit message +Version: 2.1.0 ?
@stocksr Yes, although it's a bit hard to find (I had difficulties finding this now that I wanted to reference it), this is explained in the documentation (see "Commit messages"). As explained there:
Adding
+semver: breakingor+semver: majorwill cause the major version to be increased,+semver: featureor+semver:minorwill bump minor and+semver:patchor+semver:fixwill bump the patch.
@asbjornu Thanks I was aware of those options, but my understanding of how they work is that all the commits since last tag are reviewed and the most significant commit message increment is applied.
Giving these versions:
What I am looking for is something like:
I think what we need to start thinking about is a new mode for GitVersion.
My initial thoughts is to call it mainline. The description of mainline development would be:
Mainline development considers a merge to 'master' a release, unlike the continuous delivery and deployment modes which get notified of a release via a tag. This allows you to use many of the GitVersion conveniences without having to tag your releases.
Initial thoughts about how this would work:
Thoughts?
@stocksr I might be misreading things, but isn't this test doing exactly what you want? If not, it would be great if you could write a similar test with the behavior you'd expect either as a comment here or submitted as a pull request, so we have something concrete to work on.
@asbjornu if I have 2x +semver:breaking and 1x +semver:minor between the last tag and HEAD then GitVersion will only do +major (it takes the highest only). The change is that when tags are not used we need to evaluate the commit messages as if each merge to master was a tag.
@JakeGinnivan Ah. I see! Then I agree that adding a new mainline mode would be good. This is something that then needs to invoked by adding mode: mainline to the configuration, right?
@asbjornu yeah exactly, it would change the behaviour and it's a completely different run mode and all branches would need to run in that mode so we would need to enforce that
@JakeGinnivan at first glance this seems like it would be perfect for our internal applications.
@JakeGinnivan I agree as well - this would fit our model perfectly, as it is exactly what we are doing. We even call our remote mainline (probably just like everyone else) but still this makes me excited!
I am not going to get to this for at least a week, I have Shouldly and DbUp coreclr releases to get out first. If anyone wants to have a stab then cool. Otherwise I hope to take a decent run at GitVersion in about a week or so.
This new mainline mode sounds like the solution to what I'm trying to accomplish in #877 as well. Currently we're dealing with this by disabling the git trigger in our CI builds for the master branch, manually adding the intended version as a label on the master branch, and then manually triggering each of the CI builds for the master branch. We want to keep the automatic prerelease tagging of builds on the development branch just the way it is in ContinuousDeployment mode, but creating release branches seems like an unnecessary increase in effort just to get our master builds properly versioned.
This is exactly what i need to :+1:
Have promoted this issue to a new dedicated issue: #932
Most helpful comment
I think what we need to start thinking about is a new mode for GitVersion.
My initial thoughts is to call it
mainline. The description of mainline development would be:Initial thoughts about how this would work:
Thoughts?