Skip to content

Commit 22e0342

Browse files
authored
Merge pull request #950 from JakeGinnivan/MainlineDevelopmentMode
Mainline development mode
2 parents 93f2646 + 03e5f91 commit 22e0342

16 files changed

+300
-19
lines changed

docs/configuration.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ The global configuration options are:
2424

2525
- **`assembly-informational-format:`** Set this to any of the available [variables](/more-info/variables) to change the value of the `AssemblyInformationalVersion` attribute. Default set to `{InformationalVersion}`. It also supports string interpolation (`{MajorMinorPatch}+{Branch}`)
2626

27-
- **`mode:`** Sets the mode of how GitVersion should create a new version. Can be set to either `ContinuousDelivery` or `ContinuousDeployment`. Read more about [ContinuousDelivery](/reference/continuous-delivery/) or [ContinuousDeployment](/reference/continuous-deployment/).
27+
- **`mode:`** Sets the mode of how GitVersion should create a new version. Read more at [versioning mode](./versioning-mode.md)
2828

2929
- **`continuous-delivery-fallback-tag:`** When using `mode: ContinuousDeployment`, the value specified will be used as the pre-release tag for branches which do not have one specified. Default set to `ci`.
3030

@@ -36,6 +36,8 @@ The global configuration options are:
3636

3737
- **`patch-version-bump-message:`** The regex to match commit messages with to perform a patch version increment. Default set to `'\+semver:\s?(fix|patch)'`, which will match occurrences of `+semver: fix` and `+semver: patch` in a commit message.
3838

39+
- **`no-bump-message:`** Used to tell GitVersion not to increment when in Mainline development mode. Default `\+semver:\s?(none|skip)`, which will match occurrences of `+semver: none` and `+semver: skip`
40+
3941
- **`legacy-semver-padding:`** The number of characters to pad `LegacySemVer` to in the `LegacySemVerPadded` [variable](/more-info/variables). Is default set to `4`, which will pad the `LegacySemVer` value of `3.0.0-beta1` to `3.0.0-beta0001`.
4042

4143
- **`build-metadata-padding:`** The number of characters to pad `BuildMetaData` to in the `BuildMetaDataPadded` [variable](/more-info/variables). Is default set to `4`, which will pad the `BuildMetaData` value of `1` to `0001`.
2.58 KB
Loading

docs/img/mainline-mode.png

69.5 KB
Loading

docs/versioning-mode.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Versioning modes
2+
GitVersion has multiple modes to fit different different ways of working.
3+
4+
5+
## Continuous Delivery
6+
This is the default mode, GitVersion calculates the next version and will use that until that is released. For instance:
7+
8+
- 1.1.0+5
9+
- 1.1.0+6
10+
- 1.1.0+7 <-- This is the artifact we release, tag the commit which created this version
11+
- 1.1.1+0
12+
13+
Tags are required in this mode to communicate when the release is done as it's an external manual process.
14+
15+
## Continuous deployment
16+
Sometimes you just want the version to keep changing and continuously deploy. A good case for this is when using Octopus deploy, as you cannot publish the same version of a package into the same feed.
17+
18+
For this mode we followed the logic in this blog post by Xavier Decoster on the issues of incrementing automatically - http://www.xavierdecoster.com/semantic-versioning-auto-incremented-nuget-package-versions
19+
20+
As such we force a pre-release tag on all branches, this is fine for applications but can cause problems for libraries. As such this mode may or may not work for you, which leads us into a new mode in v4. Mainline development.
21+
22+
## Mainline development
23+
Mainline development works more like the Continuous Delivery mode, except that it tells GitVersion to *infer* releases from merges and commits to `master`.
24+
25+
This mode is great if you do not want to tag each release because you simply deploy every commit to master. The behaviour of this mode is as follows:
26+
27+
1. Calclate a base version (likely a tag in this mode)
28+
1. Walk all commits from the base version commit
29+
1. When a merge commit is found:
30+
- Calculate increments for each direct commit on master
31+
- Calculate the increment for the branch
32+
1. Calculate increments for each remaining direct commit
33+
1. For feature branches then calculate increment for the commits so far on your feature branch.
34+
35+
If you *do not want* GitVersion to treat a commit or a pull request as a release and increment the version you can use `+semver: none` or `+semver: skip` in a commit message to skip incrementing for that commit.
36+
37+
Here is an example of what mainline development looks like:
38+
39+
![Mainline mode](./img/mainline-mode.png)
40+
41+
42+
**WARNING:** This approach can slow down over time, we recommend to tag intermitently (maybe for minor or major releases) because then GitVersion will start the version calculation from that point. Much like a snapshot in an event sourced system. We will probably add in warnings to tag when things are slowing down.

src/GitVersionCore.Tests/ConfigProviderTests.CanWriteOutEffectiveConfiguration.approved.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ continuous-delivery-fallback-tag: ci
55
major-version-bump-message: '\+semver:\s?(breaking|major)'
66
minor-version-bump-message: '\+semver:\s?(feature|minor)'
77
patch-version-bump-message: '\+semver:\s?(fix|patch)'
8+
no-bump-message: '\+semver:\s?(none|skip)'
89
legacy-semver-padding: 4
910
build-metadata-padding: 4
1011
commits-since-version-source-padding: 4

src/GitVersionCore.Tests/GitVersionCore.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
<Compile Include="ConfigProviderTests.cs" />
114114
<Compile Include="GitVersionContextTests.cs" />
115115
<Compile Include="Helpers\DirectoryHelper.cs" />
116+
<Compile Include="IntegrationTests\MainlineDevelopmentMode.cs" />
116117
<Compile Include="Mocks\MockThreadSleep.cs" />
117118
<Compile Include="OperationWithExponentialBackoffTests.cs" />
118119
<Compile Include="Init\InitScenarios.cs" />
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
using System;
2+
using System.Reflection;
3+
using System.Text;
4+
using GitTools.Testing;
5+
using GitVersion;
6+
using GitVersionCore.Tests;
7+
using LibGit2Sharp;
8+
using NUnit.Framework;
9+
10+
public class MainlineDevelopmentMode
11+
{
12+
private Config config = new Config
13+
{
14+
VersioningMode = VersioningMode.Mainline
15+
};
16+
17+
[Test]
18+
public void MergedFeatureBranchesToMasterImpliesRelease()
19+
{
20+
using (var fixture = new EmptyRepositoryFixture())
21+
{
22+
fixture.Repository.MakeACommit("1");
23+
fixture.MakeATaggedCommit("1.0.0");
24+
25+
fixture.BranchTo("feature/foo", "foo");
26+
fixture.MakeACommit("2");
27+
fixture.AssertFullSemver(config, "1.0.1-foo.1+1");
28+
fixture.Checkout("master");
29+
fixture.MergeNoFF("feature/foo");
30+
31+
fixture.AssertFullSemver(config, "1.0.1+2");
32+
33+
fixture.BranchTo("feature/foo2", "foo2");
34+
fixture.MakeACommit("3 +semver: minor");
35+
fixture.AssertFullSemver(config, "1.1.0-foo2.1+3");
36+
fixture.Checkout("master");
37+
fixture.MergeNoFF("feature/foo2");
38+
fixture.AssertFullSemver(config, "1.1.0+4");
39+
40+
fixture.BranchTo("feature/foo3", "foo3");
41+
fixture.MakeACommit("4");
42+
fixture.Checkout("master");
43+
fixture.MergeNoFF("feature/foo3");
44+
fixture.SequenceDiagram.NoteOver("Merge message contains '+semver: minor'", "master");
45+
var commit = fixture.Repository.Head.Tip;
46+
// Put semver increment in merge message
47+
fixture.Repository.Commit(commit.Message + " +semver: minor", commit.Author, commit.Committer, new CommitOptions
48+
{
49+
AmendPreviousCommit = true
50+
});
51+
fixture.AssertFullSemver(config, "1.2.0+6");
52+
53+
fixture.BranchTo("feature/foo4", "foo4");
54+
fixture.MakeACommit("5 +semver: major");
55+
fixture.AssertFullSemver(config, "2.0.0-foo4.1+7");
56+
fixture.Checkout("master");
57+
fixture.MergeNoFF("feature/foo4");
58+
fixture.AssertFullSemver(config, "2.0.0+8");
59+
60+
// We should evaluate any commits not included in merge commit calculations for direct commit/push or squash to merge commits
61+
fixture.MakeACommit("6 +semver: major");
62+
fixture.AssertFullSemver(config, "3.0.0+9");
63+
fixture.MakeACommit("7 +semver: minor");
64+
fixture.AssertFullSemver(config, "3.1.0+10");
65+
fixture.MakeACommit("8");
66+
fixture.AssertFullSemver(config, "3.1.1+11");
67+
68+
// Finally verify that the merge commits still function properly
69+
fixture.BranchTo("feature/foo5", "foo5");
70+
fixture.MakeACommit("9 +semver: minor");
71+
fixture.AssertFullSemver(config, "3.2.0-foo5.1+12");
72+
fixture.Checkout("master");
73+
fixture.MergeNoFF("feature/foo5");
74+
fixture.AssertFullSemver(config, "3.2.0+13");
75+
76+
// One more direct commit for good measure
77+
fixture.MakeACommit("10 +semver: minor");
78+
fixture.AssertFullSemver(config, "3.3.0+14");
79+
// And we can commit without bumping semver
80+
fixture.MakeACommit("11 +semver: none");
81+
fixture.AssertFullSemver(config, "3.3.0+15");
82+
Console.WriteLine(fixture.SequenceDiagram.GetDiagram());
83+
}
84+
}
85+
// Write test which has a forward merge into a feature branch
86+
}
87+
88+
static class CommitExtensions
89+
{
90+
public static void MakeACommit(this RepositoryFixtureBase fixture, string commitMsg)
91+
{
92+
fixture.Repository.MakeACommit(commitMsg);
93+
var diagramBuilder = (StringBuilder)typeof(SequenceDiagram)
94+
.GetField("_diagramBuilder", BindingFlags.Instance | BindingFlags.NonPublic)
95+
.GetValue(fixture.SequenceDiagram);
96+
Func<string, string> getParticipant = participant => (string)typeof(SequenceDiagram)
97+
.GetMethod("GetParticipant", BindingFlags.Instance | BindingFlags.NonPublic)
98+
.Invoke(fixture.SequenceDiagram, new object[]
99+
{
100+
participant
101+
});
102+
diagramBuilder.AppendLineFormat("{0} -> {0}: Commit '{1}'", getParticipant(fixture.Repository.Head.FriendlyName),
103+
commitMsg);
104+
}
105+
}

src/GitVersionCore.Tests/TestEffectiveConfiguration.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public TestEffectiveConfiguration(
2222
string majorMessage = null,
2323
string minorMessage = null,
2424
string patchMessage = null,
25+
string noBumpMessage = null,
2526
CommitMessageIncrementMode commitMessageMode = CommitMessageIncrementMode.Enabled,
2627
int legacySemVerPadding = 4,
2728
int buildMetaDataPadding = 4,
@@ -32,7 +33,7 @@ public TestEffectiveConfiguration(
3233
base(assemblyVersioningScheme, assemblyInformationalFormat, versioningMode, gitTagPrefix, tag, nextVersion, IncrementStrategy.Patch,
3334
branchPrefixToTrim, preventIncrementForMergedBranchVersion, tagNumberPattern, continuousDeploymentFallbackTag,
3435
trackMergeTarget,
35-
majorMessage, minorMessage, patchMessage,
36+
majorMessage, minorMessage, patchMessage, noBumpMessage,
3637
commitMessageMode, legacySemVerPadding, buildMetaDataPadding, commitsSinceVersionSourcePadding,
3738
versionFilters ?? Enumerable.Empty<IVersionFilter>(),
3839
isDevelop, isRelease)

src/GitVersionCore/Configuration/Config.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ public string NextVersion
5252
[YamlMember(Alias = "patch-version-bump-message")]
5353
public string PatchVersionBumpMessage { get; set; }
5454

55+
[YamlMember(Alias = "no-bump-message")]
56+
public string NoBumpMessage { get; set; }
57+
5558
[YamlMember(Alias = "legacy-semver-padding")]
5659
public int? LegacySemVerPadding { get; set; }
5760

src/GitVersionCore/Configuration/ConfigurationProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public static void ApplyDefaultsTo(Config config)
6262
config.MajorVersionBumpMessage = config.MajorVersionBumpMessage ?? IncrementStrategyFinder.DefaultMajorPattern;
6363
config.MinorVersionBumpMessage = config.MinorVersionBumpMessage ?? IncrementStrategyFinder.DefaultMinorPattern;
6464
config.PatchVersionBumpMessage = config.PatchVersionBumpMessage ?? IncrementStrategyFinder.DefaultPatchPattern;
65+
config.NoBumpMessage = config.NoBumpMessage ?? IncrementStrategyFinder.DefaultNoBumpPattern;
6566
config.CommitMessageIncrementing = config.CommitMessageIncrementing ?? CommitMessageIncrementMode.Enabled;
6667
config.LegacySemVerPadding = config.LegacySemVerPadding ?? 4;
6768
config.BuildMetaDataPadding = config.BuildMetaDataPadding ?? 4;

0 commit comments

Comments
 (0)