Skip to content

Adding Merge Commit Version Strategy #4630

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/GitVersion.Core/Configuration/ConfigurationConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ internal static class ConfigurationConstants
VersionStrategies.MergeMessage,
VersionStrategies.TaggedCommit,
VersionStrategies.TrackReleaseBranches,
VersionStrategies.VersionInBranchName
VersionStrategies.VersionInBranchName,
VersionStrategies.MergeCommit
];
public const string DefaultAssemblyInformationalFormat = "{InformationalVersion}";
public const string DefaultCommitDateFormat = "yyyy-MM-dd";
Expand Down
1 change: 1 addition & 0 deletions src/GitVersion.Core/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@ GitVersion.VersionCalculation.VersionStrategies
GitVersion.VersionCalculation.VersionStrategies.ConfiguredNextVersion = 2 -> GitVersion.VersionCalculation.VersionStrategies
GitVersion.VersionCalculation.VersionStrategies.Fallback = 1 -> GitVersion.VersionCalculation.VersionStrategies
GitVersion.VersionCalculation.VersionStrategies.Mainline = 64 -> GitVersion.VersionCalculation.VersionStrategies
GitVersion.VersionCalculation.VersionStrategies.MergeCommit = 128 -> GitVersion.VersionCalculation.VersionStrategies
GitVersion.VersionCalculation.VersionStrategies.MergeMessage = 4 -> GitVersion.VersionCalculation.VersionStrategies
GitVersion.VersionCalculation.VersionStrategies.None = 0 -> GitVersion.VersionCalculation.VersionStrategies
GitVersion.VersionCalculation.VersionStrategies.TaggedCommit = 8 -> GitVersion.VersionCalculation.VersionStrategies
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using GitVersion.Common;
using GitVersion.Configuration;
using GitVersion.Core;
using GitVersion.Extensions;
using GitVersion.Git;
using GitVersion.Logging;

namespace GitVersion.VersionCalculation;

/// <summary>
/// Version is extracted from older merge commits.
/// BaseVersionSource is the commit where the message was found.
/// </summary>
internal sealed class MergeCommitVersionStrategy(ILog log, Lazy<GitVersionContext> contextLazy,
IRepositoryStore repositoryStore, IIncrementStrategyFinder incrementStrategyFinder, IEffectiveBranchConfigurationFinder effectiveBranchConfigurationFinder,
ITaggedSemanticVersionRepository taggedSemanticVersionRepository
)
: IVersionStrategy
{
private readonly ILog log = log.NotNull();
private readonly Lazy<GitVersionContext> contextLazy = contextLazy.NotNull();
private readonly IRepositoryStore repositoryStore = repositoryStore.NotNull();
private readonly IIncrementStrategyFinder incrementStrategyFinder = incrementStrategyFinder.NotNull();
private readonly IEffectiveBranchConfigurationFinder effectiveBranchConfigurationFinder = effectiveBranchConfigurationFinder.NotNull();
private readonly ITaggedSemanticVersionRepository taggedSemanticVersionRepository = taggedSemanticVersionRepository.NotNull();

private GitVersionContext Context => contextLazy.Value;

public IEnumerable<BaseVersion> GetBaseVersions(EffectiveBranchConfiguration configuration)
{
configuration.NotNull();

if (!Context.Configuration.VersionStrategy.HasFlag(VersionStrategies.MergeCommit))
{
yield break;
}

var taggedCommits = this.taggedSemanticVersionRepository.GetTaggedSemanticVersions(
tagPrefix: Context.Configuration.TagPrefixPattern,
format: Context.Configuration.SemanticVersionFormat,
ignore: Context.Configuration.Ignore
);
var previousVersion = new SemanticVersion(0, 0, 0);

// Must Loop In Reverse To Ensure Correct Version Calculation
foreach (var commit in configuration.Value.Ignore.Filter(Context.CurrentBranchCommits.ToArray()).Reverse())
{
if (taggedCommits.Contains(commit))
{
this.log.Debug($"Found tagged commit {commit}, adjusting previous version.");
previousVersion = taggedCommits[commit].First().Value;
}
if (!commit.IsMergeCommit())
{
continue;
}

// Using Merge Message Since The Formats Are Identical
if (!MergeMessage.TryParse(commit, Context.Configuration, out var mergeMessage))
{
continue;
}

this.log.Info($"Found commit [{commit}] matching merge message format: {mergeMessage.FormatName}");

var currentBranch = this.repositoryStore.GetTargetBranch(mergeMessage.MergedBranch!.Friendly);
var branchConfiguration = this.effectiveBranchConfigurationFinder.GetConfigurations(currentBranch, Context.Configuration).First();
var baseVersionSource = this.repositoryStore.FindMergeBase(commit.Parents[0], commit.Parents[1]);

var label = branchConfiguration.Value.GetBranchSpecificLabel(mergeMessage.MergedBranch!.Friendly, "");
var increment = this.incrementStrategyFinder.DetermineIncrementedField(
currentCommit: commit,
baseVersionSource: baseVersionSource,
shouldIncrement: true,
configuration: branchConfiguration.Value,
label: label
);

yield return new BaseVersion($"Merge Commit From '{mergeMessage.MergedBranch?.Friendly}'", previousVersion
)
{
Operator = new()
{
Increment = increment,
ForceIncrement = false,
Label = label
}
};

previousVersion = previousVersion.Increment(
increment,
label,
true
);
}
}
}
3 changes: 2 additions & 1 deletion src/GitVersion.Core/VersionCalculation/VersionStrategies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ public enum VersionStrategies
TaggedCommit = 8,
TrackReleaseBranches = 16,
VersionInBranchName = 32,
Mainline = 64
Mainline = 64,
MergeCommit = 128
}
Loading