diff --git a/docs/configuration.md b/docs/configuration.md index bea563f6e1..26f9cf2eec 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,4 +1,4 @@ -# Configuration +# Configuration GitVersion 3.0 is mainly powered by configuration and no longer has branching strategies hard coded. ## Configuration tool @@ -79,8 +79,20 @@ The options in here are: - **`prevent-increment-of-merged-branch-version:`** When `release-2.0.0` is merged into master, we want master to build `2.0.0`. If `release-2.0.0` is merged into develop we want it to build `2.1.0`, this option prevents incrementing after a versioned branch is merged - - **`tag-number-pattern:`** Pull requests require us to pull the pre-release number out of the branch name so `refs/pulls/534/merge` builds as `PullRequest.534`. - This is a regex with a named capture group called `number` + - **`tag-number-pattern:`** Pull requests require us to extract the pre-release number out of the branch name so `refs/pulls/534/merge` builds as `PullRequest.534`. + This is a regex with a named capture group called `number` + If the branch mode is set to ContinuousDeployment, then the extracted `number` is appended to the name of the pre-release tag and the number portion is the number of commits since the last tag. + This enables consecutive commits to the pull request branch to generate unique full semantic version numbers when the branch is configured to use ContinuousDeployment mode. + Example usage: +```yaml +branches: + (pull|pull\-requests|pr)[/-]: + mode: ContinuousDeployment + tag: PullRequest + increment: Inherit + track-merge-target: true + tag-name-pattern: '[/-](?\d+)[-/]' +``` - **`track-merge-target:`** Strategy which will look for tagged merge commits directly off the current branch. For example `develop` → `release/1.0.0` → merge into `master` and tag `1.0.0`. The tag is *not* on develop, but develop should be version `1.0.0` now. diff --git a/src/GitVersionCore.Tests/VariableProviderTests.cs b/src/GitVersionCore.Tests/VariableProviderTests.cs index 285ab46692..7ae6e64eb3 100644 --- a/src/GitVersionCore.Tests/VariableProviderTests.cs +++ b/src/GitVersionCore.Tests/VariableProviderTests.cs @@ -152,4 +152,47 @@ public void ProvidesVariablesInContinuousDeploymentModeForStableWhenCurrentCommi JsonOutputFormatter.ToJson(vars).ShouldMatchApproved(c => c.SubFolder("Approved")); } + + [Test] + public void ProvidesVariablesInContinuousDeploymentModeWithTagNamePattern() + { + var semVer = new SemanticVersion + { + Major = 1, + Minor = 2, + Patch = 3, + PreReleaseTag = "PullRequest", + BuildMetaData = "5.Branch.develop" + }; + + semVer.BuildMetaData.Branch = "pull/2/merge"; + semVer.BuildMetaData.Sha = "commitSha"; + semVer.BuildMetaData.CommitDate = DateTimeOffset.Parse("2014-03-06 23:59:59Z"); + + var config = new TestEffectiveConfiguration(versioningMode: VersioningMode.ContinuousDeployment, tagNumberPattern: @"[/-](?\d+)[-/]"); + var vars = VariableProvider.GetVariablesFor(semVer, config, false); + + vars.FullSemVer.ShouldBe("1.2.3-PullRequest0002.5"); + } + + [Test] + public void ProvidesVariablesInContinuousDeploymentModeWithTagSetToUseBranchName() + { + var semVer = new SemanticVersion + { + Major = 1, + Minor = 2, + Patch = 3, + BuildMetaData = "5.Branch.develop" + }; + + semVer.BuildMetaData.Branch = "feature"; + semVer.BuildMetaData.Sha = "commitSha"; + semVer.BuildMetaData.CommitDate = DateTimeOffset.Parse("2014-03-06 23:59:59Z"); + + var config = new TestEffectiveConfiguration(versioningMode: VersioningMode.ContinuousDeployment, tag: "useBranchName"); + var vars = VariableProvider.GetVariablesFor(semVer, config, false); + + vars.FullSemVer.ShouldBe("1.2.3-feature.5"); + } } \ No newline at end of file diff --git a/src/GitVersionCore/OutputVariables/VariableProvider.cs b/src/GitVersionCore/OutputVariables/VariableProvider.cs index 7aaf205c13..6e0eb13a18 100644 --- a/src/GitVersionCore/OutputVariables/VariableProvider.cs +++ b/src/GitVersionCore/OutputVariables/VariableProvider.cs @@ -2,6 +2,8 @@ { using System; using System.ComponentModel; + using System.Text.RegularExpressions; + using GitVersion.VersionCalculation; public static class VariableProvider { @@ -13,7 +15,22 @@ public static VersionVariables GetVariablesFor(SemanticVersion semanticVersion, // Continuous Deployment always requires a pre-release tag unless the commit is tagged if (!semanticVersion.PreReleaseTag.HasTag()) { - semanticVersion.PreReleaseTag.Name = config.ContinuousDeploymentFallbackTag; + semanticVersion.PreReleaseTag.Name = NextVersionCalculator.GetBranchSpecificTag(config, semanticVersion.BuildMetaData.Branch, null); + if (string.IsNullOrEmpty(semanticVersion.PreReleaseTag.Name)) + { + semanticVersion.PreReleaseTag.Name = config.ContinuousDeploymentFallbackTag; + } + } + + // Evaluate tag number pattern and append to prerelease tag, preserving build metadata + if (!string.IsNullOrEmpty(config.TagNumberPattern)) + { + var match = Regex.Match(semanticVersion.BuildMetaData.Branch, config.TagNumberPattern); + var numberGroup = match.Groups["number"]; + if (numberGroup.Success) + { + semanticVersion.PreReleaseTag.Name += numberGroup.Value.PadLeft(config.BuildMetaDataPadding, '0'); + } } // For continuous deployment the commits since tag gets promoted to the pre-release number diff --git a/src/GitVersionCore/VersionCalculation/NextVersionCalculator.cs b/src/GitVersionCore/VersionCalculation/NextVersionCalculator.cs index eebc26527a..2b4bf6183c 100644 --- a/src/GitVersionCore/VersionCalculation/NextVersionCalculator.cs +++ b/src/GitVersionCore/VersionCalculation/NextVersionCalculator.cs @@ -69,24 +69,7 @@ public SemanticVersion FindVersion(GitVersionContext context) void UpdatePreReleaseTag(GitVersionContext context, SemanticVersion semanticVersion, string branchNameOverride) { - var tagToUse = context.Configuration.Tag; - if (tagToUse == "useBranchName") - { - tagToUse = "{BranchName}"; - } - if (tagToUse.Contains("{BranchName}")) - { - Logger.WriteInfo("Using branch name to calculate version tag"); - - var branchName = branchNameOverride ?? context.CurrentBranch.FriendlyName; - if (!string.IsNullOrWhiteSpace(context.Configuration.BranchPrefixToTrim)) - { - branchName = branchName.RegexReplace(context.Configuration.BranchPrefixToTrim, string.Empty, RegexOptions.IgnoreCase); - } - branchName = branchName.RegexReplace("[^a-zA-Z0-9-]", "-"); - - tagToUse = tagToUse.Replace("{BranchName}", branchName); - } + var tagToUse = GetBranchSpecificTag(context.Configuration, context.CurrentBranch.FriendlyName, branchNameOverride); int? number = null; if (!string.IsNullOrEmpty(context.Configuration.TagNumberPattern)) @@ -119,6 +102,29 @@ void UpdatePreReleaseTag(GitVersionContext context, SemanticVersion semanticVers semanticVersion.PreReleaseTag = new SemanticVersionPreReleaseTag(tagToUse, number); } + public static string GetBranchSpecificTag(EffectiveConfiguration configuration, string branchFriendlyName, string branchNameOverride) + { + var tagToUse = configuration.Tag; + if (tagToUse == "useBranchName") + { + tagToUse = "{BranchName}"; + } + if (tagToUse.Contains("{BranchName}")) + { + Logger.WriteInfo("Using branch name to calculate version tag"); + + var branchName = branchNameOverride ?? branchFriendlyName; + if (!string.IsNullOrWhiteSpace(configuration.BranchPrefixToTrim)) + { + branchName = branchName.RegexReplace(configuration.BranchPrefixToTrim, string.Empty, RegexOptions.IgnoreCase); + } + branchName = branchName.RegexReplace("[^a-zA-Z0-9-]", "-"); + + tagToUse = tagToUse.Replace("{BranchName}", branchName); + } + return tagToUse; + } + static bool MajorMinorPatchEqual(SemanticVersion lastTag, SemanticVersion baseVersion) { return lastTag.Major == baseVersion.Major &&