Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC regarding the calculation of Base Versions #2799

Closed
wants to merge 8 commits into from
24 changes: 12 additions & 12 deletions src/GitVersion.Core.Tests/IntegrationTests/DevelopScenarios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,11 @@ public void CommitsSinceVersionSourceShouldNotGoDownUponGitFlowReleaseFinish()
fixture.Checkout("develop");
fixture.MergeNoFF("release/1.2.0");
fixture.MakeACommit("commit in develop - 6");
fixture.AssertFullSemver("1.3.0-alpha.9");
fixture.AssertFullSemver("1.3.0-alpha.6");
fixture.SequenceDiagram.Destroy("release/1.2.0");
fixture.Repository.Branches.Remove("release/1.2.0");

const string expectedFullSemVer = "1.3.0-alpha.9";
const string expectedFullSemVer = "1.3.0-alpha.6";
fixture.AssertFullSemver(expectedFullSemVer, config);
}

Expand Down Expand Up @@ -260,11 +260,11 @@ public void CommitsSinceVersionSourceShouldNotGoDownUponMergingFeatureOnlyToDeve
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.AssertFullSemver("1.3.0-alpha.2");
fixture.SequenceDiagram.Destroy("release/1.2.0");
fixture.Repository.Branches.Remove("release/1.2.0");

const string expectedFullSemVer = "1.3.0-alpha.5";
const string expectedFullSemVer = "1.3.0-alpha.2";
fixture.AssertFullSemver(expectedFullSemVer, config);
}

Expand Down Expand Up @@ -317,16 +317,16 @@ public void WhenPreventIncrementOfMergedBranchVersionIsSetToFalseForDevelopCommi
fixture.MergeNoFF(ReleaseBranch);

// Version numbers will still be correct when the release branch is around.
fixture.AssertFullSemver("1.2.0-alpha.6");
fixture.AssertFullSemver("1.2.0-alpha.6", config);
fixture.AssertFullSemver("1.2.0-alpha.3");
fixture.AssertFullSemver("1.2.0-alpha.3", config);

var versionSourceBeforeReleaseBranchIsRemoved = fixture.GetVersion(config).Sha;

fixture.Repository.Branches.Remove(ReleaseBranch);
var versionSourceAfterReleaseBranchIsRemoved = fixture.GetVersion(config).Sha;
Assert.AreEqual(versionSourceBeforeReleaseBranchIsRemoved, versionSourceAfterReleaseBranchIsRemoved);
fixture.AssertFullSemver("1.2.0-alpha.6");
fixture.AssertFullSemver("1.2.0-alpha.6", config);
fixture.AssertFullSemver("1.2.0-alpha.3");
fixture.AssertFullSemver("1.2.0-alpha.3", config);

config.Branches = new Dictionary<string, BranchConfig>
{
Expand Down Expand Up @@ -374,7 +374,7 @@ public void WhenPreventIncrementOfMergedBranchVersionIsSetToFalseForDevelopCommi
fixture.Repository.MakeCommits(2);
fixture.MergeNoFF(ReleaseBranch);
fixture.Repository.Branches.Remove(ReleaseBranch);
fixture.AssertFullSemver("1.2.0-alpha.6", config);
fixture.AssertFullSemver("1.2.0-alpha.3", config);

// Create hotfix for defects found in release/1.1.0
const string HotfixBranch = "hotfix/1.1.1";
Expand All @@ -391,11 +391,11 @@ public void WhenPreventIncrementOfMergedBranchVersionIsSetToFalseForDevelopCommi
fixture.Checkout("develop");
// Simulate some work done on develop while the hotfix branch was open.
fixture.Repository.MakeCommits(3);
fixture.AssertFullSemver("1.2.0-alpha.9", config);
fixture.AssertFullSemver("1.2.0-alpha.6", config);
fixture.Repository.MergeNoFF(HotfixBranch);
fixture.AssertFullSemver("1.2.0-alpha.19", config);
fixture.AssertFullSemver("1.2.0-alpha.10", config);

fixture.Repository.Branches.Remove(HotfixBranch);
fixture.AssertFullSemver("1.2.0-alpha.19", config);
fixture.AssertFullSemver("1.2.0-alpha.10", config);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public void GitFlowMinorRelease()

// Not 0 for commit count as we can't know the increment rules of the merged branch
fixture.Checkout("develop");
fixture.AssertFullSemver("1.4.0-alpha.4");
fixture.AssertFullSemver("1.4.0-alpha.2");
Console.WriteLine(fixture.SequenceDiagram.GetDiagram());
}

Expand Down Expand Up @@ -211,7 +211,7 @@ public void GitFlowMajorRelease()

// Not 0 for commit count as we can't know the increment rules of the merged branch
fixture.Checkout("develop");
fixture.AssertFullSemver("2.1.0-alpha.4");
fixture.AssertFullSemver("2.1.0-alpha.2");
Console.WriteLine(fixture.SequenceDiagram.GetDiagram());
}

Expand Down
12 changes: 6 additions & 6 deletions src/GitVersion.Core.Tests/IntegrationTests/GitflowScenarios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,16 @@ public void GitflowComplexExample()
fixture.Checkout(developBranch);
fixture.MergeNoFF(release1Branch);
fixture.Repository.Branches.Remove(fixture.Repository.Branches[release1Branch]);
fixture.AssertFullSemver("1.2.0-alpha.2");
fixture.AssertFullSemver("1.2.0-alpha.1");

// Feature 2
fixture.BranchTo(feature2Branch);
fixture.MakeACommit("added feature 2");
fixture.AssertFullSemver("1.2.0-f2.1+3");
fixture.AssertFullSemver("1.2.0-f2.1+2");
fixture.Checkout(developBranch);
fixture.MergeNoFF(feature2Branch);
fixture.Repository.Branches.Remove(fixture.Repository.Branches[feature2Branch]);
fixture.AssertFullSemver("1.2.0-alpha.4");
fixture.AssertFullSemver("1.2.0-alpha.3");

// Release 1.2.0
fixture.BranchTo(release2Branch);
Expand All @@ -64,13 +64,13 @@ public void GitflowComplexExample()
fixture.Checkout(developBranch);
fixture.MergeNoFF(release2Branch);
fixture.Repository.Branches.Remove(fixture.Repository.Branches[release2Branch]);
fixture.AssertFullSemver("1.3.0-alpha.2");
fixture.AssertFullSemver("1.3.0-alpha.1");

// Hotfix
fixture.Checkout(MainBranch);
fixture.BranchTo(hotfixBranch);
fixture.MakeACommit("added hotfix");
fixture.AssertFullSemver("1.2.1-beta.1+7");
fixture.AssertFullSemver("1.2.1-beta.1+1");
fixture.Checkout(MainBranch);
fixture.MergeNoFF(hotfixBranch);
fixture.AssertFullSemver("1.2.1+2");
Expand All @@ -79,7 +79,7 @@ public void GitflowComplexExample()
fixture.Checkout(developBranch);
fixture.MergeNoFF(hotfixBranch);
fixture.Repository.Branches.Remove(fixture.Repository.Branches[hotfixBranch]);
fixture.AssertFullSemver("1.3.0-alpha.9");
fixture.AssertFullSemver("1.3.0-alpha.3");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using GitVersion.VersionCalculation;
using LibGit2Sharp;
using NUnit.Framework;
using Shouldly;

namespace GitVersion.Core.Tests.IntegrationTests;

Expand Down Expand Up @@ -48,12 +49,12 @@ public void NoMergeBacksToDevelopInCaseThereAreChangesInReleaseBranch()
// Merge to develop
fixture.Checkout("develop");
fixture.Repository.MergeNoFF("release/1.0.0");
fixture.AssertFullSemver("1.1.0-alpha.2");
fixture.AssertFullSemver("1.1.0-alpha.1");

fixture.Repository.MakeACommit();
fixture.Repository.Branches.Remove("release/1.0.0");

fixture.AssertFullSemver("1.1.0-alpha.3");
fixture.AssertFullSemver("1.1.0-alpha.2");
}

[Test]
Expand Down Expand Up @@ -184,7 +185,7 @@ public void WhenReleaseBranchOffMainIsMergedIntoMainVersionIsTakenWithIt()
}

[Test]
public void MainVersioningContinuousCorrectlyAfterMergingReleaseBranch()
public void MainVersioningContinuesCorrectlyAfterMergingReleaseBranch()
{
using var fixture = new EmptyRepositoryFixture();
fixture.Repository.MakeATaggedCommit("1.0.3");
Expand All @@ -201,6 +202,56 @@ public void MainVersioningContinuousCorrectlyAfterMergingReleaseBranch()
fixture.AssertFullSemver("2.0.1+1");
}

[Test]
public void MainVersioningContinuesCountingAfterMergingTheSameReleaseBranchMultipleTimes()
{
using var fixture = new EmptyRepositoryFixture();
fixture.Repository.MakeATaggedCommit("1.0.3");
fixture.Repository.MakeCommits(1);
fixture.Repository.CreateBranch("release/2.0.0");
fixture.Checkout("release/2.0.0");
fixture.Repository.MakeCommits(4);
fixture.Checkout(MainBranch);
fixture.Repository.MergeNoFF("release/2.0.0", Generate.SignatureNow());

fixture.AssertFullSemver("2.0.0+0");

fixture.Checkout("release/2.0.0");
fixture.Repository.MakeCommits(3);
fixture.Checkout(MainBranch);
fixture.Repository.MergeNoFF("release/2.0.0", Generate.SignatureNow());

fixture.AssertFullSemver("2.0.0+4");
fixture.Repository.MakeCommits(1);
fixture.AssertFullSemver("2.0.0+5");
}

[Test]
public void ShouldUseTagsAsVersionSourceWhenPossible()
{
using var fixture = new EmptyRepositoryFixture();
fixture.Repository.MakeATaggedCommit("0.1.0");
fixture.Checkout(MainBranch);
fixture.Repository.CreateBranch("develop");
fixture.Checkout("develop");
fixture.MakeACommit("Feature commit 1");
fixture.BranchTo("release/0.2.0");
fixture.MakeACommit("Release commit 1");
fixture.Checkout(MainBranch);
fixture.MergeNoFF("release/0.2.0");
fixture.ApplyTag("0.2.0");

var tag = fixture.Repository.Head.Tip;

fixture.Checkout("develop");
fixture.MergeNoFF(MainBranch);

fixture.AssertFullSemver("0.3.0-alpha.1");

var version = fixture.GetVersion();
version.VersionSourceSha.ShouldBeEquivalentTo(tag.Sha);
}

[Test]
public void WhenReleaseBranchIsMergedIntoDevelopHighestVersionIsTakenWithIt()
{
Expand Down Expand Up @@ -434,7 +485,7 @@ public void CommitOnDevelopAfterReleaseBranchMergeToDevelopShouldNotResetCount()
}

[Test]
public void CommitBeetweenMergeReleaseToDevelopShouldNotResetCount()
public void CommitBetweenMergeReleaseToDevelopShouldNotResetCount()
{
var config = new Config
{
Expand Down
55 changes: 44 additions & 11 deletions src/GitVersion.Core/VersionCalculation/BaseVersionCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,24 +53,53 @@ public BaseVersion GetBaseVersion()

if (matchingVersionsOnceIncremented.Any())
{
static Versions CompareVersions(Versions versions1, Versions version2)
if (matchingVersionsOnceIncremented.Count > 1)
{
if (versions1.Version.BaseVersionSource == null)
static Versions CompareVersions(Versions versions1, Versions version2)
{
return version2;
if (versions1.Version.BaseVersionSource == null)
{
return version2;
}
if (version2.Version.BaseVersionSource == null)
{
return versions1;
}

return versions1.Version.BaseVersionSource.When < version2.Version.BaseVersionSource.When ? versions1 : version2;
}
if (version2.Version.BaseVersionSource == null)

this.log.Info($"Found multiple base versions which will produce the same SemVer ({maxVersion.IncrementedVersion})");
this.log.Info($"Here are the different source candidate for commit counting : ");
foreach (var baseVersion in matchingVersionsOnceIncremented.Select(b => b.Version))
{
return versions1;
if (baseVersion != null)
{
this.log.Info($" - {BaseVersionToString(baseVersion)}");
}
}

return versions1.Version.BaseVersionSource.When < version2.Version.BaseVersionSource.When ? versions1 : version2;
}
var tagVersions = matchingVersionsOnceIncremented.FindAll(b => b.Version.Source.Contains("Git tag"));

if (tagVersions.Count > 0)
{
this.log.Info("As there are Git tags, the other sources will be discarded");
matchingVersionsOnceIncremented = tagVersions;
}

var oldest = matchingVersionsOnceIncremented.Aggregate(CompareVersions);
baseVersionWithOldestSource = oldest.Version;
maxVersion = oldest;
this.log.Info($"Found multiple base versions which will produce the same SemVer ({maxVersion.IncrementedVersion}), taking oldest source for commit counting ({baseVersionWithOldestSource.Source})");
maxVersion = matchingVersionsOnceIncremented.Aggregate(CompareVersions);
baseVersionWithOldestSource = maxVersion.Version;
this.log.Info($"Taking oldest source for commit counting : {BaseVersionToString(baseVersionWithOldestSource)}");
}
else
{
maxVersion = matchingVersionsOnceIncremented.First();
baseVersionWithOldestSource = maxVersion.Version;
this.log.Info(
$"Found a base versions which will produce the following SemVer ({maxVersion.IncrementedVersion}), " +
$"with the following source for commit counting : {BaseVersionToString(baseVersionWithOldestSource)}"
);
}
}
else
{
Expand All @@ -97,6 +126,10 @@ static Versions CompareVersions(Versions versions1, Versions version2)
return calculatedBase;
}
}

private static string BaseVersionToString(BaseVersion baseVersion) =>
$"{baseVersion!.Source} ({baseVersion!.BaseVersionSource!.Sha})";

private IEnumerable<BaseVersion> GetBaseVersions(IVersionStrategy strategy)
{
foreach (var version in strategy.GetVersions())
Expand Down