diff --git a/docs/input/docs/learn/who.md b/docs/input/docs/learn/who.md index ace607d739..f71da3d125 100644 --- a/docs/input/docs/learn/who.md +++ b/docs/input/docs/learn/who.md @@ -12,7 +12,6 @@ that we know about today. * [ChocolateyGUI](https://github.com/chocolatey/ChocolateyGUI) * [GitLink](https://github.com/GitTools/GitLink) * [OctopusDeploy](https://github.com/OctopusDeploy) -* [NUKE](https://nuke.build) * [Orc.\* packages](https://github.com/wildgums?query=orc) * [Orchestra](https://github.com/wildgums/orchestra) * [Shouldly](https://github.com/shouldly/shouldly) diff --git a/docs/input/docs/reference/mdsource/configuration.source.md b/docs/input/docs/reference/mdsource/configuration.source.md index 5c2b43db5a..4d3b387b73 100644 --- a/docs/input/docs/reference/mdsource/configuration.source.md +++ b/docs/input/docs/reference/mdsource/configuration.source.md @@ -504,6 +504,8 @@ of `alpha.foo` with `label: 'alpha.{BranchName}'` and `regex: '^features?[\/-](? Another example: branch `features/sc-12345/some-description` would become a pre-release label of `sc-12345` with `label: '{StoryNo}'` and `regex: '^features?[\/-](?sc-\d+)[-/].+'`. +You can also use environment variable placeholders with the `{env:VARIABLE_NAME}` syntax. Environment variable placeholders can also be combined with regex placeholders, for example `{BranchName}-{env:VARIABLE_NAME}`, and support fallback values using the `{env:VARIABLE_NAME ?? "fallback"}` syntax. + **Note:** To clear a default use an empty string: `label: ''` ### increment diff --git a/src/GitVersion.Configuration.Tests/Configuration/ConfigurationExtensionsTests.cs b/src/GitVersion.Configuration.Tests/Configuration/ConfigurationExtensionsTests.cs index b1f4bc6be1..057e72762f 100644 --- a/src/GitVersion.Configuration.Tests/Configuration/ConfigurationExtensionsTests.cs +++ b/src/GitVersion.Configuration.Tests/Configuration/ConfigurationExtensionsTests.cs @@ -6,6 +6,8 @@ namespace GitVersion.Configuration.Tests; [TestFixture] public class ConfigurationExtensionsTests : TestBase { + private const string BranchName = "pull-request"; + [TestCase("release/2.0.0", "refs/heads/release/2.0.0", "release/2.0.0", "release/2.0.0", true, false, false, false, true)] @@ -51,7 +53,94 @@ public void EnsureGetBranchSpecificLabelWorksAsExpected(string branchName, strin .Build(); var effectiveConfiguration = configuration.GetEffectiveConfiguration(ReferenceName.FromBranchName(branchName)); - var actual = effectiveConfiguration.GetBranchSpecificLabel(ReferenceName.FromBranchName(branchName), null); + var actual = effectiveConfiguration.GetBranchSpecificLabel(ReferenceName.FromBranchName(branchName), null, new TestEnvironment()); actual.ShouldBe(expectedLabel); } + + [Test] + public void EnsureGetBranchSpecificLabelProcessesEnvironmentVariables() + { + var environment = new TestEnvironment(); + environment.SetEnvironmentVariable("GITHUB_HEAD_REF", "feature-branch"); + + var configuration = GitFlowConfigurationBuilder.New + .WithoutBranches() + .WithBranch(BranchName, builder => builder + .WithLabel("pr-{env:GITHUB_HEAD_REF}") + .WithRegularExpression(@"^pull[/-]")) + .Build(); + + var effectiveConfiguration = configuration.GetEffectiveConfiguration(ReferenceName.FromBranchName(BranchName)); + var actual = effectiveConfiguration.GetBranchSpecificLabel(ReferenceName.FromBranchName(BranchName), null, environment); + actual.ShouldBe("pr-feature-branch"); + } + + [Test] + public void EnsureGetBranchSpecificLabelProcessesEnvironmentVariablesWithFallback() + { + var environment = new TestEnvironment(); + // Don't set GITHUB_HEAD_REF to test fallback + + var configuration = GitFlowConfigurationBuilder.New + .WithoutBranches() + .WithBranch(BranchName, builder => builder + .WithLabel("pr-{env:GITHUB_HEAD_REF ?? \"unknown\"}") + .WithRegularExpression(@"^pull[/-]")) + .Build(); + + var effectiveConfiguration = configuration.GetEffectiveConfiguration(ReferenceName.FromBranchName(BranchName)); + var actual = effectiveConfiguration.GetBranchSpecificLabel(ReferenceName.FromBranchName(BranchName), null, environment); + actual.ShouldBe("pr-unknown"); + } + + [Test] + public void EnsureGetBranchSpecificLabelProcessesEnvironmentVariablesAndRegexPlaceholders() + { + var environment = new TestEnvironment(); + environment.SetEnvironmentVariable("GITHUB_HEAD_REF", "feature-branch"); + + var configuration = GitFlowConfigurationBuilder.New + .WithoutBranches() + .WithBranch("feature/test-branch", builder => builder + .WithLabel("{BranchName}-{env:GITHUB_HEAD_REF}") + .WithRegularExpression(@"^features?[\/-](?.+)")) + .Build(); + + var effectiveConfiguration = configuration.GetEffectiveConfiguration(ReferenceName.FromBranchName("feature/test-branch")); + var actual = effectiveConfiguration.GetBranchSpecificLabel(ReferenceName.FromBranchName("feature/test-branch"), null, environment); + actual.ShouldBe("test-branch-feature-branch"); + } + + [Test] + public void EnsureGetBranchSpecificLabelWorksWithoutEnvironmentWhenNoEnvPlaceholders() + { + var configuration = GitFlowConfigurationBuilder.New + .WithoutBranches() + .WithBranch("feature/test", builder => builder + .WithLabel("{BranchName}") + .WithRegularExpression(@"^features?[\/-](?.+)")) + .Build(); + + var effectiveConfiguration = configuration.GetEffectiveConfiguration(ReferenceName.FromBranchName("feature/test")); + var actual = effectiveConfiguration.GetBranchSpecificLabel(ReferenceName.FromBranchName("feature/test"), null, new TestEnvironment()); + actual.ShouldBe("test"); + } + + [Test] + public void EnsureGetBranchSpecificLabelThrowsWhenThrowIfNotFoundAndEnvVarMissing() + { + var environment = new TestEnvironment(); + // Do not set MISSING_VAR + + var configuration = GitFlowConfigurationBuilder.New + .WithoutBranches() + .WithBranch(BranchName, builder => builder + .WithLabel("pr-{env:MISSING_VAR}") + .WithRegularExpression(@"^pull[/-]")) + .Build(); + + var effectiveConfiguration = configuration.GetEffectiveConfiguration(ReferenceName.FromBranchName(BranchName)); + Should.Throw(() => + effectiveConfiguration.GetBranchSpecificLabel(ReferenceName.FromBranchName(BranchName), null, environment)); + } } diff --git a/src/GitVersion.Core/Extensions/ConfigurationExtensions.cs b/src/GitVersion.Core/Extensions/ConfigurationExtensions.cs index 68e77ee4fd..e79fcca522 100644 --- a/src/GitVersion.Core/Extensions/ConfigurationExtensions.cs +++ b/src/GitVersion.Core/Extensions/ConfigurationExtensions.cs @@ -1,5 +1,6 @@ using GitVersion.Core; using GitVersion.Extensions; +using GitVersion.Formatting; using GitVersion.Git; using GitVersion.VersionCalculation; @@ -97,38 +98,25 @@ private static bool ShouldBeIgnored(ICommit commit, IIgnoreConfiguration ignore) extension(EffectiveConfiguration configuration) { - public string? GetBranchSpecificLabel(ReferenceName branchName, string? branchNameOverride) - => GetBranchSpecificLabel(configuration, branchName.WithoutOrigin, branchNameOverride); + public string? GetBranchSpecificLabel(ReferenceName branchName, string? branchNameOverride, IEnvironment environment) + => GetBranchSpecificLabel(configuration, branchName.WithoutOrigin, branchNameOverride, environment); - public string? GetBranchSpecificLabel(string? branchName, string? branchNameOverride) + public string? GetBranchSpecificLabel(string? branchName, string? branchNameOverride, IEnvironment environment) { configuration.NotNull(); + environment.NotNull(); var label = configuration.Label; + if (label is null) { return label; } var effectiveBranchName = branchNameOverride ?? branchName; - if (configuration.RegularExpression.IsNullOrWhiteSpace() || effectiveBranchName.IsNullOrEmpty()) return label; - var regex = RegexPatterns.Cache.GetOrAdd(configuration.RegularExpression); - var match = regex.Match(effectiveBranchName); - if (!match.Success) return label; - foreach (var groupName in regex.GetGroupNames()) - { - var groupValue = match.Groups[groupName].Value; - Lazy escapedGroupValueLazy = new(() => groupValue.RegexReplace(RegexPatterns.SanitizeNameRegexPattern, "-")); - var placeholder = $"{{{groupName}}}"; - int index, startIndex = 0; - while ((index = label.IndexOf(placeholder, startIndex, StringComparison.InvariantCulture)) >= 0) - { - var escapedGroupValue = escapedGroupValueLazy.Value; - label = label.Remove(index, placeholder.Length).Insert(index, escapedGroupValue); - startIndex = index + escapedGroupValue.Length; - } - } - return label; + var labelPlaceholders = BuildLabelPlaceholders(configuration.RegularExpression, effectiveBranchName); + + return label.FormatWith(labelPlaceholders, environment); } public TaggedSemanticVersions GetTaggedSemanticVersion() @@ -153,5 +141,27 @@ public TaggedSemanticVersions GetTaggedSemanticVersion() } return taggedSemanticVersion; } + + private static Dictionary BuildLabelPlaceholders(string? regularExpression, string? effectiveBranchName) + { + var placeholders = new Dictionary(); + + if (regularExpression.IsNullOrWhiteSpace() || effectiveBranchName.IsNullOrEmpty()) + return placeholders; + + var regex = RegexPatterns.Cache.GetOrAdd(regularExpression); + var match = regex.Match(effectiveBranchName); + + if (!match.Success) + return placeholders; + + foreach (var groupName in regex.GetGroupNames()) + { + var groupValue = match.Groups[groupName].Value; + placeholders[groupName] = groupValue.RegexReplace(RegexPatterns.SanitizeNameRegexPattern, "-"); + } + + return placeholders; + } } } diff --git a/src/GitVersion.Core/Formatting/StringFormatWithExtension.cs b/src/GitVersion.Core/Formatting/StringFormatWithExtension.cs index 06154aefe5..341c9096f0 100644 --- a/src/GitVersion.Core/Formatting/StringFormatWithExtension.cs +++ b/src/GitVersion.Core/Formatting/StringFormatWithExtension.cs @@ -37,17 +37,51 @@ internal static class StringFormatWithExtension /// "{env:BUILD_NUMBER}".FormatWith(new { }, env); /// "{env:BUILD_NUMBER ?? \"0\"}".FormatWith(new { }, env); /// - public string FormatWith(T? source, IEnvironment environment) + public string FormatWith(object source, IEnvironment environment) + { + ArgumentNullException.ThrowIfNull(source); + + return template.FormatWith((member, format, fallback) => EvaluateMemberFromObject(source, member, format, fallback), environment); + } + + /// + /// Formats the , replacing each expression wrapped in curly braces + /// with the corresponding property from the or . + /// + /// The source object to apply to the + /// + /// The is null. + /// An environment variable was null and no fallback was provided. + /// + /// An expression containing "." is treated as a property or field access on the . + /// An expression starting with "env:" is replaced with the value of the corresponding variable from the . + /// Each expression may specify a single hardcoded fallback value using the {Prop ?? "fallback"} syntax, which applies if the expression evaluates to null. + /// + /// + /// // replace an expression with a property value + /// "Hello {Name}".FormatWith(new { Name = "Fred" }, env); + /// "Hello {Name ?? \"Fred\"}".FormatWith(new { Name = GetNameOrNull() }, env); + /// // replace an expression with an environment variable + /// "{env:BUILD_NUMBER}".FormatWith(new { }, env); + /// "{env:BUILD_NUMBER ?? \"0\"}".FormatWith(new { }, env); + /// + public string FormatWith(IDictionary source, IEnvironment environment) { - ArgumentNullException.ThrowIfNull(template); ArgumentNullException.ThrowIfNull(source); + return template.FormatWith((member, format, fallback) => EvaluateMemberFromDictionary(source, member, format, fallback), environment); + } + + private string FormatWith(EvaluateMemberDelegate memberEvaluator, IEnvironment environment) + { + ArgumentNullException.ThrowIfNull(template); + var result = new StringBuilder(); var lastIndex = 0; foreach (var match in RegexPatterns.ExpandTokensRegex.Matches(template).Cast()) { - var replacement = EvaluateMatch(match, source, environment); + var replacement = EvaluateMatch(match, memberEvaluator, environment); result.Append(template, lastIndex, match.Index - lastIndex); result.Append(replacement); lastIndex = match.Index + match.Length; @@ -58,7 +92,7 @@ public string FormatWith(T? source, IEnvironment environment) } } - private static string EvaluateMatch(Match match, T source, IEnvironment environment) + private static string EvaluateMatch(Match match, EvaluateMemberDelegate memberEvaluator, IEnvironment environment) { var fallback = match.Groups["fallback"].Success ? match.Groups["fallback"].Value : null; @@ -68,7 +102,7 @@ private static string EvaluateMatch(Match match, T source, IEnvironment envir if (match.Groups["member"].Success) { var format = match.Groups["format"].Success ? match.Groups["format"].Value : null; - return EvaluateMember(source, match.Groups["member"].Value, format, fallback); + return memberEvaluator(match.Groups["member"].Value, format, fallback); } throw new ArgumentException($"Invalid token format: '{match.Value}'"); @@ -82,7 +116,7 @@ private static string EvaluateEnvVar(string name, string? fallback, IEnvironment ?? throw new ArgumentException($"Environment variable {safeName} not found and no fallback provided"); } - private static string EvaluateMember(T source, string member, string? format, string? fallback) + private static string EvaluateMemberFromObject(object source, string member, string? format, string? fallback) { var safeMember = InputSanitizer.SanitizeMemberName(member); var memberPath = MemberResolver.ResolveMemberPath(source!.GetType(), safeMember); @@ -93,13 +127,31 @@ private static string EvaluateMember(T source, string member, string? format, return fallback ?? string.Empty; if (format is not null && ValueFormatter.Default.TryFormat( - value, - InputSanitizer.SanitizeFormat(format), - out var formatted)) + value, + InputSanitizer.SanitizeFormat(format), + out var formatted)) { return formatted; } return value.ToString() ?? fallback ?? string.Empty; } + + private static string EvaluateMemberFromDictionary(IDictionary source, string member, string? format, string? fallback) + { + var safeMember = InputSanitizer.SanitizeMemberName(member); + + if (!source.TryGetValue(safeMember, out var value)) + return fallback ?? string.Empty; + + if (value is null) + return fallback ?? string.Empty; + + if (format is not null && ValueFormatter.Default.TryFormat(value, InputSanitizer.SanitizeFormat(format), out var formatted)) + return formatted; + + return value.ToString() ?? fallback ?? string.Empty; + } + + private delegate string EvaluateMemberDelegate(string member, string? format, string? fallback); } diff --git a/src/GitVersion.Core/VersionCalculation/Mainline/EnrichIncrement.cs b/src/GitVersion.Core/VersionCalculation/Mainline/EnrichIncrement.cs index 22d09d92ee..eff180d3b8 100644 --- a/src/GitVersion.Core/VersionCalculation/Mainline/EnrichIncrement.cs +++ b/src/GitVersion.Core/VersionCalculation/Mainline/EnrichIncrement.cs @@ -19,7 +19,7 @@ public void Enrich(MainlineIteration iteration, MainlineCommit commit, MainlineC if (commit.Predecessor is not null && commit.Predecessor.BranchName != commit.BranchName) context.Label = null; - context.Label ??= effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); + context.Label ??= effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null, context.Environment); if (effectiveConfiguration.IsMainBranch) context.BaseVersionSource = commit.Predecessor?.Value; diff --git a/src/GitVersion.Core/VersionCalculation/Mainline/EnrichSemanticVersion.cs b/src/GitVersion.Core/VersionCalculation/Mainline/EnrichSemanticVersion.cs index ec0efc946b..094fead4da 100644 --- a/src/GitVersion.Core/VersionCalculation/Mainline/EnrichSemanticVersion.cs +++ b/src/GitVersion.Core/VersionCalculation/Mainline/EnrichSemanticVersion.cs @@ -9,9 +9,9 @@ public void Enrich(MainlineIteration iteration, MainlineCommit commit, MainlineC { var branchSpecificLabel = context.TargetLabel; branchSpecificLabel ??= iteration.GetEffectiveConfiguration(context.Configuration) - .GetBranchSpecificLabel(commit.BranchName, null); + .GetBranchSpecificLabel(commit.BranchName, null, context.Environemnt); branchSpecificLabel ??= commit.GetEffectiveConfiguration(context.Configuration) - .GetBranchSpecificLabel(commit.BranchName, null); + .GetBranchSpecificLabel(commit.BranchName, null, context.Environment); var semanticVersions = commit.SemanticVersions.Where( element => element.IsMatchForBranchSpecificLabel(branchSpecificLabel) diff --git a/src/GitVersion.Core/VersionCalculation/Mainline/MainlineContext.cs b/src/GitVersion.Core/VersionCalculation/Mainline/MainlineContext.cs index 3657484b37..b7e39dc562 100644 --- a/src/GitVersion.Core/VersionCalculation/Mainline/MainlineContext.cs +++ b/src/GitVersion.Core/VersionCalculation/Mainline/MainlineContext.cs @@ -4,12 +4,14 @@ namespace GitVersion.VersionCalculation.Mainline; -internal record MainlineContext(IIncrementStrategyFinder IncrementStrategyFinder, IGitVersionConfiguration Configuration) +internal record MainlineContext(IIncrementStrategyFinder IncrementStrategyFinder, IGitVersionConfiguration Configuration, IEnvironment Environment) { public IIncrementStrategyFinder IncrementStrategyFinder { get; } = IncrementStrategyFinder.NotNull(); public IGitVersionConfiguration Configuration { get; } = Configuration.NotNull(); + public IEnvironment Environemnt { get; } = Environment.NotNull(); + public string? TargetLabel { get; init; } public SemanticVersion? SemanticVersion { get; set; } diff --git a/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunk.cs b/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunk.cs index d50f955a35..e1a8d9020e 100644 --- a/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunk.cs +++ b/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunk.cs @@ -22,7 +22,7 @@ public IEnumerable GetIncrements( context.Label = null; var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); - context.Label ??= effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); + context.Label ??= effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null, context.Environment); if (commit.Successor is not null) yield break; yield return new BaseVersionOperator diff --git a/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunkBranchedBase.cs b/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunkBranchedBase.cs index 371cf513d6..5d7b5aa97a 100644 --- a/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunkBranchedBase.cs +++ b/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunkBranchedBase.cs @@ -21,7 +21,7 @@ public virtual IEnumerable GetIncrements( context.Increment = context.Increment.Consolidate(incrementForcedByBranch); var iterationEffectiveConfiguration = iteration.GetEffectiveConfiguration(context.Configuration); - context.Label = iterationEffectiveConfiguration.GetBranchSpecificLabel(iteration.BranchName, null) ?? context.Label; + context.Label = iterationEffectiveConfiguration.GetBranchSpecificLabel(iteration.BranchName, null, context.Environment) ?? context.Label; context.ForceIncrement = true; yield return new BaseVersionOperator diff --git a/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunkWithPreReleaseTagBase.cs b/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunkWithPreReleaseTagBase.cs index 7c1c5c841a..94f6f5a860 100644 --- a/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunkWithPreReleaseTagBase.cs +++ b/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunkWithPreReleaseTagBase.cs @@ -24,7 +24,7 @@ public virtual IEnumerable GetIncrements( context.Increment = commit.GetIncrementForcedByBranch(context.Configuration); var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); - context.Label = effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); + context.Label = effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null, context.Environment); context.ForceIncrement = false; } } diff --git a/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunkWithStableTagBase.cs b/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunkWithStableTagBase.cs index 37e3b68a49..8065034493 100644 --- a/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunkWithStableTagBase.cs +++ b/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/CommitOnNonTrunkWithStableTagBase.cs @@ -24,6 +24,6 @@ public virtual IEnumerable GetIncrements( context.Increment = commit.GetIncrementForcedByBranch(context.Configuration); var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); - context.Label = effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); + context.Label = effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null, context.Environment); } } diff --git a/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/MergeCommitOnNonTrunkBase.cs b/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/MergeCommitOnNonTrunkBase.cs index ce2c089aae..94ca86304e 100644 --- a/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/MergeCommitOnNonTrunkBase.cs +++ b/src/GitVersion.Core/VersionCalculation/Mainline/NonTrunk/MergeCommitOnNonTrunkBase.cs @@ -22,7 +22,8 @@ IEnumerable GetIncrementsInternal() iteration: commit.ChildIteration, targetLabel: context.TargetLabel, incrementStrategyFinder: context.IncrementStrategyFinder, - configuration: context.Configuration + configuration: context.Configuration, + environment: context.Environment ); context.Label ??= baseVersion.Operator?.Label; diff --git a/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/CommitOnTrunk.cs b/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/CommitOnTrunk.cs index 152b81577e..7e5f85d1c2 100644 --- a/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/CommitOnTrunk.cs +++ b/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/CommitOnTrunk.cs @@ -21,7 +21,7 @@ public IEnumerable GetIncrements( context.Label = null; var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); - context.Label ??= effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); + context.Label ??= effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null, context.Environment); context.ForceIncrement = true; yield return new BaseVersionOperator diff --git a/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/CommitOnTrunkBranchedBase.cs b/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/CommitOnTrunkBranchedBase.cs index 2e64ac60bf..887a03d48c 100644 --- a/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/CommitOnTrunkBranchedBase.cs +++ b/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/CommitOnTrunkBranchedBase.cs @@ -28,7 +28,7 @@ public virtual IEnumerable GetIncrements( context.Increment = incrementForcedByBranch; var iterationEffectiveConfiguration = iteration.GetEffectiveConfiguration(context.Configuration); - context.Label = iterationEffectiveConfiguration.GetBranchSpecificLabel(iteration.BranchName, null) ?? context.Label; + context.Label = iterationEffectiveConfiguration.GetBranchSpecificLabel(iteration.BranchName, null, context.Environment) ?? context.Label; context.ForceIncrement = true; yield return new BaseVersionOperator diff --git a/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/CommitOnTrunkWithStableTagBase.cs b/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/CommitOnTrunkWithStableTagBase.cs index f9ca1a445b..f590cb3a3e 100644 --- a/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/CommitOnTrunkWithStableTagBase.cs +++ b/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/CommitOnTrunkWithStableTagBase.cs @@ -22,6 +22,6 @@ public virtual IEnumerable GetIncrements( }; var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); - context.Label = effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); + context.Label = effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null, context.Environment); } } diff --git a/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/LastCommitOnTrunkWithPreReleaseTag.cs b/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/LastCommitOnTrunkWithPreReleaseTag.cs index 97316952f6..fc7c263749 100644 --- a/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/LastCommitOnTrunkWithPreReleaseTag.cs +++ b/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/LastCommitOnTrunkWithPreReleaseTag.cs @@ -22,7 +22,7 @@ public override IEnumerable GetIncrements( context.Increment = commit.GetIncrementForcedByBranch(context.Configuration); var effectiveConfiguration = commit.GetEffectiveConfiguration(context.Configuration); - context.Label = effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null); + context.Label = effectiveConfiguration.GetBranchSpecificLabel(commit.BranchName, null, context.Environment); context.ForceIncrement = false; yield return new BaseVersionOperator diff --git a/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/MergeCommitOnTrunkBase.cs b/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/MergeCommitOnTrunkBase.cs index 26170a710c..84c7119052 100644 --- a/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/MergeCommitOnTrunkBase.cs +++ b/src/GitVersion.Core/VersionCalculation/Mainline/Trunk/MergeCommitOnTrunkBase.cs @@ -20,7 +20,8 @@ IEnumerable GetIncrementsInternal() iteration: commit.ChildIteration!, targetLabel: context.TargetLabel, incrementStrategyFinder: context.IncrementStrategyFinder, - configuration: context.Configuration + configuration: context.Configuration, + environment: context.Environment ); context.Label ??= baseVersion.Operator?.Label; diff --git a/src/GitVersion.Core/VersionCalculation/VersionCalculators/NextVersionCalculator.cs b/src/GitVersion.Core/VersionCalculation/VersionCalculators/NextVersionCalculator.cs index d43017eda1..67d34935cb 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionCalculators/NextVersionCalculator.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionCalculators/NextVersionCalculator.cs @@ -14,13 +14,15 @@ internal class NextVersionCalculator( IEnumerable deploymentModeCalculators, IEnumerable versionStrategies, IEffectiveBranchConfigurationFinder effectiveBranchConfigurationFinder, - ITaggedSemanticVersionService taggedSemanticVersionService) + ITaggedSemanticVersionService taggedSemanticVersionService, + IEnvironment environment) : INextVersionCalculator { private readonly ILog log = log.NotNull(); private readonly Lazy versionContext = versionContext.NotNull(); private readonly IVersionStrategy[] versionStrategies = [.. versionStrategies.NotNull()]; private readonly IEffectiveBranchConfigurationFinder effectiveBranchConfigurationFinder = effectiveBranchConfigurationFinder.NotNull(); + private readonly IEnvironment environment = environment.NotNull(); private GitVersionContext Context => this.versionContext.Value; @@ -108,7 +110,7 @@ private bool TryGetSemanticVersion( { result = null; - var label = effectiveConfiguration.GetBranchSpecificLabel(Context.CurrentBranch.Name, null); + var label = effectiveConfiguration.GetBranchSpecificLabel(Context.CurrentBranch.Name, null, this.environment); var currentCommitTaggedVersion = taggedSemanticVersionsOfCurrentCommit .Where(element => element.Value.IsMatchForBranchSpecificLabel(label)).Max(); diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/ConfiguredNextVersionVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/ConfiguredNextVersionVersionStrategy.cs index 275aee185a..eee9b78d8f 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/ConfiguredNextVersionVersionStrategy.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/ConfiguredNextVersionVersionStrategy.cs @@ -8,9 +8,10 @@ namespace GitVersion.VersionCalculation; /// BaseVersionSource is null. /// Does not increment. /// -internal sealed class ConfiguredNextVersionVersionStrategy(Lazy contextLazy) : IVersionStrategy +internal sealed class ConfiguredNextVersionVersionStrategy(Lazy contextLazy, IEnvironment environment) : IVersionStrategy { private readonly Lazy contextLazy = contextLazy.NotNull(); + private readonly IEnvironment environment = environment.NotNull(); private GitVersionContext Context => contextLazy.Value; @@ -26,7 +27,7 @@ public IEnumerable GetBaseVersions(EffectiveBranchConfiguration con var semanticVersion = SemanticVersion.Parse( nextVersion, Context.Configuration.TagPrefixPattern, Context.Configuration.SemanticVersionFormat ); - var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null); + var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null, environment); if (!semanticVersion.IsMatchForBranchSpecificLabel(label)) yield break; BaseVersionOperator? operation = null; diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/FallbacktVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/FallbacktVersionStrategy.cs index 31858d5a4d..019852e035 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/FallbacktVersionStrategy.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/FallbacktVersionStrategy.cs @@ -12,12 +12,14 @@ namespace GitVersion.VersionCalculation; internal sealed class FallbackVersionStrategy( Lazy contextLazy, IIncrementStrategyFinder incrementStrategyFinder, - ITaggedSemanticVersionService taggedSemanticVersionService) + ITaggedSemanticVersionService taggedSemanticVersionService, + IEnvironment environment) : IVersionStrategy { private readonly Lazy contextLazy = contextLazy.NotNull(); private readonly IIncrementStrategyFinder incrementStrategyFinder = incrementStrategyFinder.NotNull(); private readonly ITaggedSemanticVersionService taggedSemanticVersionService = taggedSemanticVersionService.NotNull(); + private readonly IEnvironment environment = environment.NotNull(); private GitVersionContext Context => contextLazy.Value; @@ -31,7 +33,7 @@ private IEnumerable GetBaseVersionsInternal(EffectiveBranchConfigur if (!Context.Configuration.VersionStrategy.HasFlag(VersionStrategies.Fallback)) yield break; - var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null); + var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null, this.environment); var baseVersionSource = taggedSemanticVersionService.GetTaggedSemanticVersions( branch: Context.CurrentBranch, diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MainlineVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MainlineVersionStrategy.cs index 805dfae9f8..0bcf15667e 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MainlineVersionStrategy.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MainlineVersionStrategy.cs @@ -13,7 +13,8 @@ internal sealed class MainlineVersionStrategy( Lazy contextLazy, IRepositoryStore repositoryStore, ITaggedSemanticVersionService taggedSemanticVersionService, - IIncrementStrategyFinder incrementStrategyFinder) + IIncrementStrategyFinder incrementStrategyFinder, + IEnvironment environment) : IVersionStrategy { private volatile int iterationCounter; @@ -21,6 +22,7 @@ internal sealed class MainlineVersionStrategy( private readonly ITaggedSemanticVersionService taggedSemanticVersionService = taggedSemanticVersionService.NotNull(); private readonly IRepositoryStore repositoryStore = repositoryStore.NotNull(); private readonly IIncrementStrategyFinder incrementStrategyFinder = incrementStrategyFinder.NotNull(); + private readonly IEnvironment environment = environment.NotNull(); private readonly Dictionary>> commitsWasBranchedFromCache = new(); private GitVersionContext Context => contextLazy.Value; @@ -102,7 +104,7 @@ public IEnumerable GetBaseVersions(EffectiveBranchConfiguration con notOlderThan: Context.CurrentCommit.When, taggedSemanticVersion: taggedSemanticVersion ); - var targetLabel = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null); + var targetLabel = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null, this.environment); IterateOverCommitsRecursive( commitsInReverseOrder: commitsInReverseOrder, iteration: iteration, @@ -111,7 +113,7 @@ public IEnumerable GetBaseVersions(EffectiveBranchConfiguration con taggedSemanticVersions: taggedSemanticVersions ); - yield return DetermineBaseVersion(iteration, targetLabel, incrementStrategyFinder, Context.Configuration); + yield return DetermineBaseVersion(iteration, targetLabel, incrementStrategyFinder, Context.Configuration, this.environment); } private MainlineIteration CreateIteration( @@ -204,7 +206,7 @@ private bool IterateOverCommitsRecursive( var label = targetLabel ?? new EffectiveConfiguration( configuration: Context.Configuration, branchConfiguration: configuration - ).GetBranchSpecificLabel(branchName, null); + ).GetBranchSpecificLabel(branchName, null, this.environment); foreach (var semanticVersion in semanticVersions) { @@ -334,15 +336,15 @@ private bool IterateOverCommitsRecursive( } private static BaseVersion DetermineBaseVersion(MainlineIteration iteration, string? targetLabel, - IIncrementStrategyFinder incrementStrategyFinder, IGitVersionConfiguration configuration) - => DetermineBaseVersionRecursive(iteration, targetLabel, incrementStrategyFinder, configuration); + IIncrementStrategyFinder incrementStrategyFinder, IGitVersionConfiguration configuration, IEnvironment environment) + => DetermineBaseVersionRecursive(iteration, targetLabel, incrementStrategyFinder, configuration, environment); internal static BaseVersion DetermineBaseVersionRecursive(MainlineIteration iteration, string? targetLabel, - IIncrementStrategyFinder incrementStrategyFinder, IGitVersionConfiguration configuration) + IIncrementStrategyFinder incrementStrategyFinder, IGitVersionConfiguration configuration, IEnvironment environment) { iteration.NotNull(); - var incrementSteps = GetIncrements(iteration, targetLabel, incrementStrategyFinder, configuration).ToArray(); + var incrementSteps = GetIncrements(iteration, targetLabel, incrementStrategyFinder, configuration, environment).ToArray(); BaseVersion? result = null; foreach (var baseVersionIncrement in incrementSteps) @@ -365,9 +367,9 @@ internal static BaseVersion DetermineBaseVersionRecursive(MainlineIteration iter } private static IEnumerable GetIncrements(MainlineIteration iteration, string? targetLabel, - IIncrementStrategyFinder incrementStrategyFinder, IGitVersionConfiguration configuration) + IIncrementStrategyFinder incrementStrategyFinder, IGitVersionConfiguration configuration, IEnvironment environment) { - MainlineContext context = new(incrementStrategyFinder, configuration) + MainlineContext context = new(incrementStrategyFinder, configuration, environment) { TargetLabel = targetLabel }; diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MergeMessageVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MergeMessageVersionStrategy.cs index d8490a734b..ae39de3386 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MergeMessageVersionStrategy.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/MergeMessageVersionStrategy.cs @@ -11,13 +11,14 @@ namespace GitVersion.VersionCalculation; /// Increments if PreventIncrementOfMergedBranchVersion (from the branch configuration) is false. /// internal sealed class MergeMessageVersionStrategy(ILog log, Lazy contextLazy, - IRepositoryStore repositoryStore, IIncrementStrategyFinder incrementStrategyFinder) + IRepositoryStore repositoryStore, IIncrementStrategyFinder incrementStrategyFinder, IEnvironment environment) : IVersionStrategy { private readonly ILog log = log.NotNull(); private readonly Lazy contextLazy = contextLazy.NotNull(); private readonly IRepositoryStore repositoryStore = repositoryStore.NotNull(); private readonly IIncrementStrategyFinder incrementStrategyFinder = incrementStrategyFinder.NotNull(); + private readonly IEnvironment environment = environment.NotNull(); private GitVersionContext Context => contextLazy.Value; @@ -51,7 +52,7 @@ private IEnumerable GetBaseVersionsInternal(EffectiveBranchConfigur baseVersionSource = this.repositoryStore.FindMergeBase(commit.Parents[0], commit.Parents[1]); } - var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null); + var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null, this.environment); var increment = configuration.Value.PreventIncrementOfMergedBranch ? VersionField.None : this.incrementStrategyFinder.DetermineIncrementedField( currentCommit: Context.CurrentCommit, diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TaggedCommitVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TaggedCommitVersionStrategy.cs index 4e08eef9c8..1b3445e9d9 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TaggedCommitVersionStrategy.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TaggedCommitVersionStrategy.cs @@ -14,13 +14,15 @@ internal sealed class TaggedCommitVersionStrategy( ILog log, Lazy contextLazy, ITaggedSemanticVersionService taggedSemanticVersionService, - IIncrementStrategyFinder incrementStrategyFinder) + IIncrementStrategyFinder incrementStrategyFinder, + IEnvironment environment) : IVersionStrategy { private readonly ILog log = log.NotNull(); private readonly ITaggedSemanticVersionService taggedSemanticVersionService = taggedSemanticVersionService.NotNull(); private readonly Lazy contextLazy = contextLazy.NotNull(); private readonly IIncrementStrategyFinder incrementStrategyFinder = incrementStrategyFinder.NotNull(); + private readonly IEnvironment environment = environment.NotNull(); private GitVersionContext Context => contextLazy.Value; @@ -42,7 +44,7 @@ private IEnumerable GetBaseVersionsInternal(EffectiveBranchConfigur taggedSemanticVersion: configuration.Value.GetTaggedSemanticVersion() ).SelectMany(elements => elements).Distinct().ToArray(); - var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null); + var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null, this.environment); var semanticVersionTreshold = SemanticVersion.Empty; List alternativeSemanticVersionsWithTag = []; diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TrackReleaseBranchesVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TrackReleaseBranchesVersionStrategy.cs index 75dc51146e..4250ef2ad2 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TrackReleaseBranchesVersionStrategy.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/TrackReleaseBranchesVersionStrategy.cs @@ -11,14 +11,16 @@ internal sealed class TrackReleaseBranchesVersionStrategy( Lazy contextLazy, IRepositoryStore repositoryStore, IBranchRepository branchRepository, - IIncrementStrategyFinder incrementStrategyFinder) + IIncrementStrategyFinder incrementStrategyFinder, + IEnvironment environment) : IVersionStrategy { private readonly Lazy contextLazy = contextLazy.NotNull(); private readonly IRepositoryStore repositoryStore = repositoryStore.NotNull(); private readonly IBranchRepository branchRepository = branchRepository.NotNull(); private readonly IIncrementStrategyFinder incrementStrategyFinder = incrementStrategyFinder.NotNull(); - private readonly VersionInBranchNameVersionStrategy releaseVersionStrategy = new(contextLazy); + private readonly IEnvironment environment = environment.NotNull(); + private readonly VersionInBranchNameVersionStrategy releaseVersionStrategy = new(contextLazy, environment); private GitVersionContext Context => contextLazy.Value; @@ -48,7 +50,7 @@ private bool TryGetBaseVersion( if (!this.releaseVersionStrategy.TryGetBaseVersion(releaseBranchConfiguration, out var baseVersion)) return result is not null; // Find the commit where the child branch was created. var baseVersionSource = this.repositoryStore.FindMergeBase(releaseBranch, Context.CurrentBranch); - var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null); + var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, null, this.environment); var increment = this.incrementStrategyFinder.DetermineIncrementedField( currentCommit: Context.CurrentCommit, baseVersionSource: baseVersionSource, diff --git a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/VersionInBranchNameVersionStrategy.cs b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/VersionInBranchNameVersionStrategy.cs index 6565f560b3..08886ecb59 100644 --- a/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/VersionInBranchNameVersionStrategy.cs +++ b/src/GitVersion.Core/VersionCalculation/VersionSearchStrategies/VersionInBranchNameVersionStrategy.cs @@ -9,9 +9,10 @@ namespace GitVersion.VersionCalculation; /// BaseVersionSource is the commit where the branch was branched from its parent. /// Does not increment. /// -internal sealed class VersionInBranchNameVersionStrategy(Lazy contextLazy) : IVersionStrategy +internal sealed class VersionInBranchNameVersionStrategy(Lazy contextLazy, IEnvironment environment) : IVersionStrategy { private readonly Lazy contextLazy = contextLazy.NotNull(); + private readonly IEnvironment environment = environment.NotNull(); private GitVersionContext Context => contextLazy.Value; @@ -43,7 +44,7 @@ public bool TryGetBaseVersion(EffectiveBranchConfiguration configuration, [NotNu branchNameOverride = result.Name; } - var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, branchNameOverride); + var label = configuration.Value.GetBranchSpecificLabel(Context.CurrentBranch.Name, branchNameOverride, this.environment); baseVersion = new BaseVersion("Version in branch name", result.Value) {