Gitversion: New mode: mainline

Created on 10 Jul 2016  Â·  12Comments  Â·  Source: GitTools/GitVersion

I think what we need to start thinking about is a new mode for GitVersion (in addition to ContinuousDelivery and ContinuousDeployment).

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:

  1. Find initial base version

    • If version is specified in GitVersion.yml, find the commit it was updated in, this commit and version can be a base version

    • Other base version sources would be the same, can use tags (as a snapshot, similar to event sourced systems)

  2. Calculate the current version

    • Find all merge commits to master

    • Merged commits under their merge commits

    • Go through each merge commit, run the increment strategies on the merged commits

    • Aggregate the increments to get to the current version

See #889 for the discussion which lead to this new mode and also covers the naming of each of the modes.

Most helpful comment

@JakeGinnivan Do you have any dates on milestone:4.0.0 release? As we want to use mainline mode but there are concerns of using beta version.

All 12 comments

Nice - great idea!

On 10 Jul 2016, at 3:00 PM, Jake Ginnivan [email protected] wrote:

I think what we need to start thinking about is a new mode for GitVersion (in addition to ContinuousDelivery and ContinuousDeployment).

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:

Find initial base version
If version is specified in GitVersion.yml, find the commit it was updated in, this commit and version can be a base version
Other base version sources would be the same, can use tags (as a snapshot, similar to event sourced systems)
Calculate the current version
Find all merge commits to master
Merged commits under their merge commits
Go through each merge commit, run the increment strategies on the merged commits
Aggregate the increments to get to the current version
See #889 for the discussion which lead to this new mode and also covers the naming of each of the modes.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.

PR open - #950

Going to leave it up for a day or so to try and get some feedback if it's enough for the initial v4 beta release. Have put some basic docs in there too. If I don't hear anything I will go ahead and release.

// @stocksr @ashtonian @labmonkey42 @taborda @v-karbovnichiy-parc @eatdrinksleepcode @aarondandy @robgha01 (you all have commented or :+1: the feature)

This looks ace!

https://github.com/GitTools/GitVersion/pull/950/commits/defc31b1fedc562cd2e553895467515053eaac8b -> this is the commit with a brief documentation update, including a graphic, detailing the new mode.

Looks awesome! I did a local build and ran some quick tests against my repo - seems like it will do what I need.

@JakeGinnivan my apologies for the really delayed response. I updated my TeamCity metarunner for GitVersion to use the 4.0 beta build, set mode: ContinuousDelivery at the top level in GitVersion.yml, and mode: Mainline under the master branch spec and unless I've overlooked something the automatic release versioning is working as anticipated. Thanks very much for your work on this!

So I've been using Mainline mode a bit more in my TeamCity builds and here are my observations.

The behavior I'm trying to achieve is:

  • "devel" is our unstable development branch off of master.
  • GitVersion.yml has ContinuousDeployment as the global mode
  • GitVersion.yml branch specification for master overrides mode as Mainline
  • commits/merges from devel to master should be versioned by the most recent version from "devel", dropping the prerelease tag (e.g. 1.2.3-unstable.123 in devel should be 1.2.3 in master)
  • my TeamCity builds are configured to tag the built commit with the project name and version (e.g. Foo.Bar.Web-1.2.3-unstable.123 in devel and Foo.Bar.Web-1.2.3 in master)
  • the GitVersion step in my TeamCity builds also specifies "/nofetch /overrideConfig:tag-prefix=%system.teamcity.buildConfName%-" which should have GitVersion look for version tags that were created by previous successful builds

The observed behavior, however, is:

  • even with /overrideConfig, version tags are ignored and GitVersion seems to want to start versioning from 0.1.0, even though I have tags in the 1.1.x series in some repos. I'm not sure if Mainline mode is ignoring tag history, the /nofetch option is interfering, or I'm doing something else wrong here.
  • builds in devel are getting versioned as 1.2.3-unstable.123, but builds of merges to master are getting 1.2.456+123, apparently indicating that Mainline mode doesn't seem to care about versions in the source branch

So I'm back to the situation of being unsure whether I'm doing something wrong in my config, completely misunderstanding how these modes are supposed to work, or trying to create a configuration that currently isn't possible.

Mainline mode and GitFlow are not really compatible. The idea with mainline is that you work directly against master and as soon as you merge to master you will release that merged commit.

We probably need to throw if you use mainline for a single branch, it has to be a global setting (i.e the entire repo is in mainline mode). I will make this change in my latest round of fixes.

Do you have multiple projects building from a single repo with different versions and deployments? If so, that scenario isn't really supported by GitVersion, it adds way too much complexity. We have the assumption that each repository has a single version moving forward and each repo is a deployment unit.

tl;dr: Honestly maybe my whole issue here should apply to reopening #877 because as far as I can tell Mainline mode appears to do what it is intended to do. It just isn't intended to do what my team needs.

So the conclusion then is that what my team needs is almost supported by GitVersion, but Mainline mode does not provide the remaining support as I had hoped.

At this point I fear that GitVersion simply cannot fill our need because a merge to master will only get a release version if someone explicitly (manually) tags the merge with the intended version when it is pushed, and our need is for that release version to be calculated from the most recent matching tag on the source branch during build automation and tags on master are created upon successful build by the build server. I'm really pushing for GitHubFlow on our team, but neither that nor release branching are going to happen for us soon enough. Politics aside, what we want doesn't seem that difficult.

Consider the following pseudo-graph. (The metadata here could be completely wrong considering the multiple-projects-per-repo situation, but I'll address that below. At this point I don't really care whether the metadata is correct, but that I can automate release versioning and tagging of master based on devel.)

* asdfasd 1 day ago (origin/master, master)
|\
| * fasdfda 1 day ago (tag: ProjectA-0.5.20-unstable.2+3, origin/devel, devel)
| * fdasfds 2 days ago (tag: ProjectB-0.5.20-unstable.1+2)
| * fadsfad 3 days ago (tag: ProjectA-0.5.20-unstable.1+1)
* | dasdfas 10 days ago (tag: ProjectA-0.5.19+5, tag: ProjectB-0.5.19+5)
...

What we're looking for is that the CI builds for both ProjectA and ProjectB are triggered by that last commit on master, the GitVersion step in the CI build determines both of their versions to be 0.5.20+x, and if both builds succeeded (meaning that TeamCity tagged the repo for each build) we would get something like this.

* asdfasd 1 day ago (tag: ProjectA-0.5.20+3, tag: ProjectB-0.5.20+3, origin/master, master)
|\
| * fasdfda 1 day ago (tag: ProjectA-0.5.20-unstable.2+3, origin/devel, devel)
| * fdasfds 2 days ago (tag: ProjectB-0.5.20-unstable.1+2)
| * fadsfad 3 days ago (tag: ProjectA-0.5.20-unstable.1+1)
* | dasdfas 10 days ago (tag: ProjectA-0.5.19+5, tag: ProjectB-0.5.19+5)
...

The person merging devel into master shouldn't have to look at TeamCity to figure out what tags he has to apply to it before committing and pushing the merge. If we have reason to bump major or minor, we can do that with "semver: breaking" or such in a commit message.

The issue with multiple projects being built from the same repository is that if I trigger a build based on a filter such as +:Foo.Bar/** for builds of the Foo.Bar project and that successful build tags the commit as Foo.Bar-1.2.3-whatever.321, though the gitversion commandline has /overrideConfig:tag-prefix=Foo.Bar- every commit since the last Foo.Bar-x.y.z-blah tag will count toward the calculated version, regardless of whether that commit contained any changes matching the trigger filter. At the moment this is far less of a concern for us, and I can live with this behavior as it stands for the time being. I agree that ultimately the best solution is to split projects into separate repositories. Making that conversion, however, is currently mired in more internal politics.

@JakeGinnivan Do you have any dates on milestone:4.0.0 release? As we want to use mainline mode but there are concerns of using beta version.

Any update on this? We release several times a day and we are currently having to manage every merge from develop into master with tagging so we get a clean SemVer version (without the -ci). It would be nice if the merge to master automatically created a Major.Minor.Patch version.

We don't want to waste time creating a release branch for every small change and there generally is no need to check a change into the release branch anyway (which also causes issues if the RB doesn't have a change committed against it).

Mainline mode was implemented in #950 and has been improved since then in the v4 beta releases. Please upgrade to that and submit any issues you have with mode: Mainline as new issues. Closing this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pcoombe picture pcoombe  Â·  5Comments

Scharpp picture Scharpp  Â·  3Comments

aronsky picture aronsky  Â·  4Comments

cryptomatt picture cryptomatt  Â·  4Comments

mikeblakeuk picture mikeblakeuk  Â·  3Comments