diff --git a/src/GitVersionCore.Tests/IntegrationTests/DevelopScenarios.cs b/src/GitVersionCore.Tests/IntegrationTests/DevelopScenarios.cs index 3c5f675697..ef3384c9ac 100644 --- a/src/GitVersionCore.Tests/IntegrationTests/DevelopScenarios.cs +++ b/src/GitVersionCore.Tests/IntegrationTests/DevelopScenarios.cs @@ -222,4 +222,81 @@ public void TagOnHotfixShouldNotAffectDevelop() fixture.AssertFullSemver("1.3.0-alpha.2"); } } + + [Test] + public void CommitsSinceVersionSourceShouldNotGoDownUponGitFlowReleaseFinish() + { + var config = new Config + { + VersioningMode = VersioningMode.ContinuousDeployment + }; + + using (var fixture = new EmptyRepositoryFixture()) + { + fixture.MakeACommit(); + fixture.ApplyTag("1.1.0"); + fixture.BranchTo("develop"); + fixture.MakeACommit("commit in develop - 1"); + fixture.AssertFullSemver("1.2.0-alpha.1"); + fixture.BranchTo("release/1.2.0"); + fixture.AssertFullSemver("1.2.0-beta.1+0"); + fixture.Checkout("develop"); + fixture.MakeACommit("commit in develop - 2"); + fixture.MakeACommit("commit in develop - 3"); + fixture.MakeACommit("commit in develop - 4"); + fixture.MakeACommit("commit in develop - 5"); + fixture.AssertFullSemver("1.3.0-alpha.4"); + fixture.Checkout("release/1.2.0"); + fixture.MakeACommit("commit in release/1.2.0 - 1"); + fixture.MakeACommit("commit in release/1.2.0 - 2"); + fixture.MakeACommit("commit in release/1.2.0 - 3"); + fixture.AssertFullSemver("1.2.0-beta.1+3"); + fixture.Checkout("master"); + fixture.MergeNoFF("release/1.2.0"); + fixture.ApplyTag("1.2.0"); + fixture.Checkout("develop"); + fixture.MergeNoFF("release/1.2.0"); + fixture.MakeACommit("commit in develop - 6"); + fixture.AssertFullSemver("1.3.0-alpha.9"); + fixture.SequenceDiagram.Destroy("release/1.2.0"); + fixture.Repository.Branches.Remove("release/1.2.0"); + + var expectedFullSemVer = "1.3.0-alpha.9"; + fixture.AssertFullSemver(config, expectedFullSemVer); + } + } + + [Test] + public void CommitsSinceVersionSourceShouldNotGoDownUponMergingFeatureOnlyToDevelop() + { + var config = new Config + { + VersioningMode = VersioningMode.ContinuousDeployment + }; + + using (var fixture = new EmptyRepositoryFixture()) + { + fixture.MakeACommit("commit in master - 1"); + fixture.ApplyTag("1.1.0"); + fixture.BranchTo("develop"); + fixture.MakeACommit("commit in develop - 1"); + fixture.AssertFullSemver("1.2.0-alpha.1"); + fixture.BranchTo("release/1.2.0"); + fixture.MakeACommit("commit in release - 1"); + fixture.MakeACommit("commit in release - 2"); + fixture.MakeACommit("commit in release - 3"); + fixture.AssertFullSemver("1.2.0-beta.1+3"); + fixture.ApplyTag("1.2.0"); + fixture.Checkout("develop"); + fixture.MakeACommit("commit in develop - 2"); + fixture.AssertFullSemver("1.3.0-alpha.1"); + fixture.MergeNoFF("release/1.2.0"); + fixture.AssertFullSemver("1.3.0-alpha.5"); + fixture.SequenceDiagram.Destroy("release/1.2.0"); + fixture.Repository.Branches.Remove("release/1.2.0"); + + var expectedFullSemVer = "1.3.0-alpha.5"; + fixture.AssertFullSemver(config, expectedFullSemVer); + } + } } diff --git a/src/GitVersionCore.Tests/IntegrationTests/ReleaseBranchScenarios.cs b/src/GitVersionCore.Tests/IntegrationTests/ReleaseBranchScenarios.cs index a5927d7603..f91938e670 100644 --- a/src/GitVersionCore.Tests/IntegrationTests/ReleaseBranchScenarios.cs +++ b/src/GitVersionCore.Tests/IntegrationTests/ReleaseBranchScenarios.cs @@ -51,7 +51,7 @@ public void NoMergeBacksToDevelopInCaseThereAreChangesInReleaseBranch() fixture.Repository.MakeACommit(); fixture.Repository.Branches.Remove("release/1.0.0"); - fixture.AssertFullSemver("1.1.0-alpha.2"); + fixture.AssertFullSemver("1.1.0-alpha.3"); } } diff --git a/src/GitVersionCore/VersionCalculation/BaseVersionCalculator.cs b/src/GitVersionCore/VersionCalculation/BaseVersionCalculator.cs index 66d312dfa8..105218dc88 100644 --- a/src/GitVersionCore/VersionCalculation/BaseVersionCalculator.cs +++ b/src/GitVersionCore/VersionCalculation/BaseVersionCalculator.cs @@ -1,7 +1,9 @@ -namespace GitVersion.VersionCalculation +namespace GitVersion.VersionCalculation { using System; + using System.Collections.Generic; using System.Linq; + using System.Text.RegularExpressions; using GitVersion.VersionCalculation.BaseVersionCalculators; public class BaseVersionCalculator : IBaseVersionCalculator @@ -37,13 +39,15 @@ public BaseVersion GetBaseVersion(GitVersionContext context) return true; }) - .Select(v => new + .Select(v => new Versions { IncrementedVersion = MaybeIncrement(context, v), Version = v }) .ToList(); + FixTheBaseVersionSourceOfMergeMessageStrategyIfReleaseBranchWasMergedAndDeleted + (context, baseVersions); var maxVersion = baseVersions.Aggregate((v1, v2) => v1.IncrementedVersion > v2.IncrementedVersion ? v1 : v2); var matchingVersionsOnceIncremented = baseVersions .Where(b => b.Version.BaseVersionSource != null && b.IncrementedVersion == maxVersion.IncrementedVersion) @@ -92,5 +96,46 @@ public static SemanticVersion MaybeIncrement(GitVersionContext context, BaseVers return version.SemanticVersion; } + + private void FixTheBaseVersionSourceOfMergeMessageStrategyIfReleaseBranchWasMergedAndDeleted( + GitVersionContext context, List baseVersions) + { + if (!ReleaseBranchExistsInRepo(context)) + { + foreach (var baseVersion in baseVersions) + { + if (baseVersion.Version.Source.Contains( + MergeMessageBaseVersionStrategy.MergeMessageStrategyPrefix) + && baseVersion.Version.Source.Contains("Merge branch") + && baseVersion.Version.Source.Contains("release")) + { + var parents = baseVersion.Version.BaseVersionSource.Parents.ToList(); + baseVersion.Version = new BaseVersion( + context, + baseVersion.Version.Source, + baseVersion.Version.ShouldIncrement, + baseVersion.Version.SemanticVersion, + context.Repository.ObjectDatabase.FindMergeBase(parents[0], parents[1]), + baseVersion.Version.BranchNameOverride); + } + } + } + } + + private bool ReleaseBranchExistsInRepo(GitVersionContext context) + { + var releaseBranchConfig = context.FullConfiguration.Branches + .Where(b => b.Value.IsReleaseBranch == true) + .ToList(); + var releaseBranches = context.Repository.Branches + .Where(b => releaseBranchConfig.Any(c => Regex.IsMatch(b.FriendlyName, c.Value.Regex))); + return releaseBranches.Any(); + } + + private class Versions + { + public SemanticVersion IncrementedVersion { get; set; } + public BaseVersion Version { get; set; } + } } -} \ No newline at end of file +} diff --git a/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/MergeMessageBaseVersionStrategy.cs b/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/MergeMessageBaseVersionStrategy.cs index dae854251b..3b2d4f228f 100644 --- a/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/MergeMessageBaseVersionStrategy.cs +++ b/src/GitVersionCore/VersionCalculation/BaseVersionCalculators/MergeMessageBaseVersionStrategy.cs @@ -26,7 +26,7 @@ public override IEnumerable GetVersions(GitVersionContext context) var shouldIncrement = !context.Configuration.PreventIncrementForMergedBranchVersion; return new[] { - new BaseVersion(context, $"Merge message '{c.Message.Trim()}'", shouldIncrement, mergeMessage.Version, c, null) + new BaseVersion(context, $"{MergeMessageStrategyPrefix} '{c.Message.Trim()}'", shouldIncrement, mergeMessage.Version, c, null) }; } return Enumerable.Empty(); @@ -34,6 +34,8 @@ public override IEnumerable GetVersions(GitVersionContext context) return baseVersions; } + public static readonly string MergeMessageStrategyPrefix = "Merge message"; + static bool TryParse(Commit mergeCommit, GitVersionContext context, out MergeMessage mergeMessage) { mergeMessage = Inner(mergeCommit, context);