Skip to content

Commit f84321e

Browse files
authored
Merge pull request #997 from JakeGinnivan/MainlineAndPrImprovements
Mainline PR improvements
2 parents 51b0543 + 12771e4 commit f84321e

File tree

7 files changed

+120
-62
lines changed

7 files changed

+120
-62
lines changed

src/GitVersionCore.Tests/IntegrationTests/DocumentationSamples.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ public void GitFlowPullRequestBranch()
6363
// Open Pull Request
6464
fixture.BranchTo("pull/2/merge", "pr");
6565
fixture.SequenceDiagram.Activate("pull/2/merge");
66-
fixture.AssertFullSemver("1.3.0-PullRequest.2+1");
66+
fixture.AssertFullSemver("1.3.0-PullRequest0002.1");
6767
fixture.MakeACommit();
68-
fixture.AssertFullSemver("1.3.0-PullRequest.2+2");
68+
fixture.AssertFullSemver("1.3.0-PullRequest0002.2");
6969

7070
// Merge into develop
7171
fixture.Checkout("develop");
@@ -365,9 +365,9 @@ public void GitHubFlowPullRequestBranch()
365365
// Open Pull Request
366366
fixture.BranchTo("pull/2/merge", "pr");
367367
fixture.SequenceDiagram.Activate("pull/2/merge");
368-
fixture.AssertFullSemver("1.2.1-PullRequest.2+1");
368+
fixture.AssertFullSemver("1.2.1-PullRequest0002.1");
369369
fixture.MakeACommit();
370-
fixture.AssertFullSemver("1.2.1-PullRequest.2+2");
370+
fixture.AssertFullSemver("1.2.1-PullRequest0002.2");
371371

372372
// Merge into master
373373
fixture.Checkout("master");

src/GitVersionCore.Tests/IntegrationTests/HotfixBranchScenarios.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ public void PatchOlderReleaseExample()
103103
fixture.Repository.MakeACommit();
104104
fixture.AssertFullSemver("1.1.1-fix.1+3");
105105

106-
fixture.Repository.CreatePullRequestRef("feature/fix", "hotfix-1.1.1", normalise: true);
107-
fixture.AssertFullSemver("1.1.1-PullRequest.2+4");
106+
fixture.Repository.CreatePullRequestRef("feature/fix", "hotfix-1.1.1", normalise: true, prNumber: 8);
107+
fixture.AssertFullSemver("1.1.1-PullRequest0008.4");
108108
fixture.Repository.Checkout("hotfix-1.1.1");
109109
fixture.Repository.MergeNoFF("feature/fix", Generate.SignatureNow());
110110
fixture.AssertFullSemver("1.1.1-beta.1+4");

src/GitVersionCore.Tests/IntegrationTests/MainlineDevelopmentMode.cs

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using GitVersionCore.Tests;
77
using LibGit2Sharp;
88
using NUnit.Framework;
9+
using LibGitExtensions = GitTools.LibGitExtensions;
910

1011
public class MainlineDevelopmentMode
1112
{
@@ -24,18 +25,20 @@ public void MergedFeatureBranchesToMasterImpliesRelease()
2425

2526
fixture.BranchTo("feature/foo", "foo");
2627
fixture.MakeACommit("2");
27-
fixture.AssertFullSemver(config, "1.0.1-foo.1+1");
28+
fixture.AssertFullSemver(config, "1.0.1-foo.1");
29+
fixture.MakeACommit("2.1");
30+
fixture.AssertFullSemver(config, "1.0.1-foo.2");
2831
fixture.Checkout("master");
2932
fixture.MergeNoFF("feature/foo");
3033

31-
fixture.AssertFullSemver(config, "1.0.1+2");
34+
fixture.AssertFullSemver(config, "1.0.1");
3235

3336
fixture.BranchTo("feature/foo2", "foo2");
3437
fixture.MakeACommit("3 +semver: minor");
35-
fixture.AssertFullSemver(config, "1.1.0-foo2.1+3");
38+
fixture.AssertFullSemver(config, "1.1.0-foo2.1");
3639
fixture.Checkout("master");
3740
fixture.MergeNoFF("feature/foo2");
38-
fixture.AssertFullSemver(config, "1.1.0+4");
41+
fixture.AssertFullSemver(config, "1.1.0");
3942

4043
fixture.BranchTo("feature/foo3", "foo3");
4144
fixture.MakeACommit("4");
@@ -48,41 +51,82 @@ public void MergedFeatureBranchesToMasterImpliesRelease()
4851
{
4952
AmendPreviousCommit = true
5053
});
51-
fixture.AssertFullSemver(config, "1.2.0+6");
54+
fixture.AssertFullSemver(config, "1.2.0");
5255

5356
fixture.BranchTo("feature/foo4", "foo4");
5457
fixture.MakeACommit("5 +semver: major");
55-
fixture.AssertFullSemver(config, "2.0.0-foo4.1+7");
58+
fixture.AssertFullSemver(config, "2.0.0-foo4.1");
5659
fixture.Checkout("master");
5760
fixture.MergeNoFF("feature/foo4");
58-
fixture.AssertFullSemver(config, "2.0.0+8");
61+
fixture.AssertFullSemver(config, "2.0.0");
5962

6063
// We should evaluate any commits not included in merge commit calculations for direct commit/push or squash to merge commits
6164
fixture.MakeACommit("6 +semver: major");
62-
fixture.AssertFullSemver(config, "3.0.0+9");
65+
fixture.AssertFullSemver(config, "3.0.0");
6366
fixture.MakeACommit("7 +semver: minor");
64-
fixture.AssertFullSemver(config, "3.1.0+10");
67+
fixture.AssertFullSemver(config, "3.1.0");
6568
fixture.MakeACommit("8");
66-
fixture.AssertFullSemver(config, "3.1.1+11");
69+
fixture.AssertFullSemver(config, "3.1.1");
6770

6871
// Finally verify that the merge commits still function properly
6972
fixture.BranchTo("feature/foo5", "foo5");
7073
fixture.MakeACommit("9 +semver: minor");
71-
fixture.AssertFullSemver(config, "3.2.0-foo5.1+12");
74+
fixture.AssertFullSemver(config, "3.2.0-foo5.1");
7275
fixture.Checkout("master");
7376
fixture.MergeNoFF("feature/foo5");
74-
fixture.AssertFullSemver(config, "3.2.0+13");
77+
fixture.AssertFullSemver(config, "3.2.0");
7578

7679
// One more direct commit for good measure
7780
fixture.MakeACommit("10 +semver: minor");
78-
fixture.AssertFullSemver(config, "3.3.0+14");
81+
fixture.AssertFullSemver(config, "3.3.0");
7982
// And we can commit without bumping semver
8083
fixture.MakeACommit("11 +semver: none");
81-
fixture.AssertFullSemver(config, "3.3.0+15");
84+
fixture.AssertFullSemver(config, "3.3.0");
8285
Console.WriteLine(fixture.SequenceDiagram.GetDiagram());
8386
}
8487
}
85-
// Write test which has a forward merge into a feature branch
88+
89+
[Test]
90+
public void VerifyPullRequestsActLikeContinuousDelivery()
91+
{
92+
using (var fixture = new EmptyRepositoryFixture())
93+
{
94+
fixture.Repository.MakeACommit("1");
95+
fixture.MakeATaggedCommit("1.0.0");
96+
fixture.MakeACommit();
97+
fixture.AssertFullSemver(config, "1.0.1");
98+
99+
fixture.BranchTo("feature/foo", "foo");
100+
fixture.MakeACommit();
101+
fixture.MakeACommit();
102+
fixture.Repository.CreatePullRequestRef("feature/foo", "master", normalise: true, prNumber: 8);
103+
fixture.AssertFullSemver(config, "1.0.2-PullRequest0008.3");
104+
}
105+
}
106+
107+
[Test]
108+
[Ignore("Not passing yet")]
109+
public void VerifyForwardMerge()
110+
{
111+
using (var fixture = new EmptyRepositoryFixture())
112+
{
113+
fixture.Repository.MakeACommit("1");
114+
fixture.MakeATaggedCommit("1.0.0");
115+
fixture.MakeACommit(); // 1.0.1
116+
117+
fixture.BranchTo("feature/foo", "foo");
118+
fixture.MakeACommit();
119+
fixture.MakeACommit();
120+
fixture.AssertFullSemver(config, "1.0.2-foo.2");
121+
122+
fixture.Checkout("master");
123+
fixture.MakeACommit();
124+
fixture.AssertFullSemver(config, "1.0.2");
125+
fixture.Checkout("feature/foo");
126+
fixture.MergeNoFF("master");
127+
fixture.AssertFullSemver(config, "1.0.3-foo.3");
128+
}
129+
}
86130
}
87131

88132
static class CommitExtensions

src/GitVersionCore.Tests/IntegrationTests/PullRequestScenarios.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public void CanCalculatePullRequestChanges()
1919
fixture.Repository.CreatePullRequestRef("feature/Foo", "master", normalise: true);
2020

2121
fixture.Repository.DumpGraph();
22-
fixture.AssertFullSemver("0.1.1-PullRequest.2+2");
22+
fixture.AssertFullSemver("0.1.1-PullRequest0002.2");
2323
}
2424
}
2525

@@ -37,7 +37,7 @@ public void CanCalculatePullRequestChangesInheritingConfig()
3737
fixture.Repository.CreatePullRequestRef("feature/Foo", "develop", 44, normalise: true);
3838

3939
fixture.Repository.DumpGraph();
40-
fixture.AssertFullSemver("0.2.0-PullRequest.44+3");
40+
fixture.AssertFullSemver("0.2.0-PullRequest0044.3");
4141
}
4242
}
4343

@@ -54,7 +54,7 @@ public void CanCalculatePullRequestChangesFromRemoteRepo()
5454
fixture.Repository.CreatePullRequestRef("feature/Foo", "master", normalise: true);
5555

5656
fixture.Repository.DumpGraph();
57-
fixture.AssertFullSemver("0.1.1-PullRequest.2+2");
57+
fixture.AssertFullSemver("0.1.1-PullRequest0002.2");
5858
}
5959
}
6060

@@ -71,7 +71,7 @@ public void CanCalculatePullRequestChangesInheritingConfigFromRemoteRepo()
7171

7272
fixture.Repository.CreatePullRequestRef("feature/Foo", "develop", normalise: true);
7373

74-
fixture.AssertFullSemver("0.2.0-PullRequest.2+3");
74+
fixture.AssertFullSemver("0.2.0-PullRequest0002.3");
7575
}
7676
}
7777

@@ -89,7 +89,7 @@ public void CanCalculatePullRequestChangesWhenThereAreMultipleMergeCandidates()
8989

9090
fixture.Repository.CreatePullRequestRef("feature/Foo", "develop", normalise: true);
9191

92-
fixture.AssertFullSemver("0.2.0-PullRequest.2+3");
92+
fixture.AssertFullSemver("0.2.0-PullRequest0002.3");
9393
}
9494
}
9595

@@ -106,7 +106,7 @@ public void CalculatesCorrectVersionAfterReleaseBranchMergedToMaster()
106106

107107
fixture.Repository.CreatePullRequestRef("release/2.0.0", "master", normalise: true);
108108

109-
fixture.AssertFullSemver("2.0.0-PullRequest.2+0");
109+
fixture.AssertFullSemver("2.0.0-PullRequest0002.0");
110110
}
111111
}
112112
}

src/GitVersionCore/OutputVariables/VariableProvider.cs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ public static class VariableProvider
99
{
1010
public static VersionVariables GetVariablesFor(SemanticVersion semanticVersion, EffectiveConfiguration config, bool isCurrentCommitTagged)
1111
{
12-
if (config.VersioningMode == VersioningMode.ContinuousDeployment && !isCurrentCommitTagged)
12+
var isContinuousDeploymentMode = config.VersioningMode == VersioningMode.ContinuousDeployment && !isCurrentCommitTagged;
13+
if (isContinuousDeploymentMode)
1314
{
1415
semanticVersion = new SemanticVersion(semanticVersion);
1516
// Continuous Deployment always requires a pre-release tag unless the commit is tagged
@@ -21,22 +22,23 @@ public static VersionVariables GetVariablesFor(SemanticVersion semanticVersion,
2122
semanticVersion.PreReleaseTag.Name = config.ContinuousDeploymentFallbackTag;
2223
}
2324
}
25+
}
2426

25-
// Evaluate tag number pattern and append to prerelease tag, preserving build metadata
26-
if (!string.IsNullOrEmpty(config.TagNumberPattern))
27+
// Evaluate tag number pattern and append to prerelease tag, preserving build metadata
28+
var appendTagNumberPattern = !string.IsNullOrEmpty(config.TagNumberPattern) && semanticVersion.PreReleaseTag.HasTag();
29+
if (appendTagNumberPattern)
30+
{
31+
var match = Regex.Match(semanticVersion.BuildMetaData.Branch, config.TagNumberPattern);
32+
var numberGroup = match.Groups["number"];
33+
if (numberGroup.Success)
2734
{
28-
var match = Regex.Match(semanticVersion.BuildMetaData.Branch, config.TagNumberPattern);
29-
var numberGroup = match.Groups["number"];
30-
if (numberGroup.Success)
31-
{
32-
semanticVersion.PreReleaseTag.Name += numberGroup.Value.PadLeft(config.BuildMetaDataPadding, '0');
33-
}
35+
semanticVersion.PreReleaseTag.Name += numberGroup.Value.PadLeft(config.BuildMetaDataPadding, '0');
3436
}
37+
}
3538

36-
// For continuous deployment the commits since tag gets promoted to the pre-release number
37-
semanticVersion.PreReleaseTag.Number = semanticVersion.BuildMetaData.CommitsSinceTag;
38-
semanticVersion.BuildMetaData.CommitsSinceVersionSource = semanticVersion.BuildMetaData.CommitsSinceTag ?? 0;
39-
semanticVersion.BuildMetaData.CommitsSinceTag = null;
39+
if (isContinuousDeploymentMode || appendTagNumberPattern || config.VersioningMode == VersioningMode.Mainline)
40+
{
41+
PromoteNumberOfCommitsToTagNumber(semanticVersion);
4042
}
4143

4244
var semverFormatValues = new SemanticVersionFormatValues(semanticVersion, config);
@@ -87,5 +89,13 @@ public static VersionVariables GetVariablesFor(SemanticVersion semanticVersion,
8789

8890
return variables;
8991
}
92+
93+
static void PromoteNumberOfCommitsToTagNumber(SemanticVersion semanticVersion)
94+
{
95+
// For continuous deployment the commits since tag gets promoted to the pre-release number
96+
semanticVersion.PreReleaseTag.Number = semanticVersion.BuildMetaData.CommitsSinceTag;
97+
semanticVersion.BuildMetaData.CommitsSinceVersionSource = semanticVersion.BuildMetaData.CommitsSinceTag ?? 0;
98+
semanticVersion.BuildMetaData.CommitsSinceTag = null;
99+
}
90100
}
91101
}

src/GitVersionCore/VersionCalculation/NextVersionCalculator.cs

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,20 @@ public SemanticVersion FindVersion(GitVersionContext context)
4444
}
4545

4646
var baseVersion = baseVersionFinder.GetBaseVersion(context);
47-
var semver = context.Configuration.VersioningMode == VersioningMode.Mainline ?
48-
FindMainlineModeVersion(baseVersion, context) :
49-
PerformIncrement(context, baseVersion);
47+
SemanticVersion semver;
48+
if (context.Configuration.VersioningMode == VersioningMode.Mainline)
49+
semver = FindMainlineModeVersion(baseVersion, context);
50+
else
51+
{
52+
semver = PerformIncrement(context, baseVersion);
53+
semver.BuildMetaData = metaDataCalculator.Create(baseVersion.BaseVersionSource, context);
54+
}
5055

5156
if (!semver.PreReleaseTag.HasTag() && !string.IsNullOrEmpty(context.Configuration.Tag))
5257
{
5358
UpdatePreReleaseTag(context, semver, baseVersion.BranchNameOverride);
5459
}
5560

56-
semver.BuildMetaData = metaDataCalculator.Create(baseVersion.BaseVersionSource, context);
5761

5862
if (taggedSemanticVersion != null)
5963
{
@@ -76,7 +80,7 @@ private static SemanticVersion PerformIncrement(GitVersionContext context, BaseV
7680
return semver;
7781
}
7882

79-
private SemanticVersion FindMainlineModeVersion(BaseVersion baseVersion, GitVersionContext context)
83+
SemanticVersion FindMainlineModeVersion(BaseVersion baseVersion, GitVersionContext context)
8084
{
8185
if (baseVersion.SemanticVersion.PreReleaseTag.HasTag())
8286
{
@@ -121,18 +125,26 @@ private SemanticVersion FindMainlineModeVersion(BaseVersion baseVersion, GitVers
121125
if (context.CurrentBranch.FriendlyName != "master")
122126
{
123127
var mergedHead = context.CurrentCommit;
124-
var findMergeBase = context.Repository.ObjectDatabase.FindMergeBase(context.CurrentCommit, context.Repository.FindBranch("master").Tip);
128+
var second = context.Repository.FindBranch("master").Tip;
129+
var findMergeBase = context.Repository.ObjectDatabase.FindMergeBase(context.CurrentCommit, second);
125130
Logger.WriteInfo(string.Format("Current branch ({0}) was branch from {1}", context.CurrentBranch.FriendlyName, findMergeBase));
126131

127-
var branchIncrement = FindMessageIncrement(context, findMergeBase, mergedHead, findMergeBase, directCommits);
132+
var branchIncrement = FindMessageIncrement(context, null, mergedHead, findMergeBase, directCommits);
133+
// This will increment for any direct commits on master
128134
mainlineVersion = IncrementForEachCommit(context, directCommits, mainlineVersion);
129-
Logger.WriteInfo(string.Format("Performing {0} increment for current branch ", branchIncrement));
130-
mainlineVersion = mainlineVersion.IncrementVersion(branchIncrement);
135+
mainlineVersion.BuildMetaData = metaDataCalculator.Create(findMergeBase, context);
136+
// Only increment if head is not a merge commit, ensures PR's and forward merges end up correct.
137+
if (mergedHead.Parents.Count() == 1)
138+
{
139+
Logger.WriteInfo(string.Format("Performing {0} increment for current branch ", branchIncrement));
140+
mainlineVersion = mainlineVersion.IncrementVersion(branchIncrement);
141+
}
131142
}
132143
else
133144
{
134145
// If we are on master, make sure no commits get left behind
135146
mainlineVersion = IncrementForEachCommit(context, directCommits, mainlineVersion);
147+
mainlineVersion.BuildMetaData = metaDataCalculator.Create(baseVersion.BaseVersionSource, context);
136148
}
137149

138150
return mainlineVersion;
@@ -162,7 +174,9 @@ private static VersionField FindMessageIncrement(
162174
IncludeReachableFrom = mergedHead,
163175
ExcludeReachableFrom = findMergeBase
164176
};
165-
var commits = new[] { mergeCommit }.Union(context.Repository.Commits.QueryBy(filter)).ToList();
177+
var commits = mergeCommit == null ?
178+
context.Repository.Commits.QueryBy(filter).ToList() :
179+
new[] { mergeCommit }.Union(context.Repository.Commits.QueryBy(filter)).ToList();
166180
commitLog.RemoveAll(c => commits.Any(c1 => c1.Sha == c.Sha));
167181
return IncrementStrategyFinder.GetIncrementForCommits(context, commits) ?? VersionField.Patch;
168182
}
@@ -180,22 +194,12 @@ void UpdatePreReleaseTag(GitVersionContext context, SemanticVersion semanticVers
180194
var tagToUse = GetBranchSpecificTag(context.Configuration, context.CurrentBranch.FriendlyName, branchNameOverride);
181195

182196
int? number = null;
183-
if (!string.IsNullOrEmpty(context.Configuration.TagNumberPattern))
184-
{
185-
var match = Regex.Match(context.CurrentBranch.CanonicalName, context.Configuration.TagNumberPattern);
186-
var numberGroup = match.Groups["number"];
187-
if (numberGroup.Success)
188-
{
189-
number = int.Parse(numberGroup.Value);
190-
}
191-
}
192197

193198
var lastTag = context.CurrentBranch
194199
.GetVersionTagsOnBranch(context.Repository, context.Configuration.GitTagPrefix)
195200
.FirstOrDefault(v => v.PreReleaseTag.Name == tagToUse);
196201

197-
if (number == null &&
198-
lastTag != null &&
202+
if (lastTag != null &&
199203
MajorMinorPatchEqual(lastTag, semanticVersion) &&
200204
lastTag.PreReleaseTag.HasTag())
201205
{

src/GitVersionExe.Tests/PullRequestInTeamCityTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void GivenARemoteWithATagOnMaster_AndAPullRequestWithTwoCommits_AndBuildI
4242
var result = GitVersionHelper.ExecuteIn(fixture.RepositoryPath, isTeamCity: true);
4343

4444
result.ExitCode.ShouldBe(0);
45-
result.OutputVariables.FullSemVer.ShouldBe("1.0.4-PullRequest.5+3");
45+
result.OutputVariables.FullSemVer.ShouldBe("1.0.4-PullRequest0005.3");
4646

4747
// Cleanup repository files
4848
DirectoryHelper.DeleteDirectory(remoteRepositoryPath);

0 commit comments

Comments
 (0)