Skip to content
Merged
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
18 changes: 15 additions & 3 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Configuration
# Configuration
GitVersion 3.0 is mainly powered by configuration and no longer has branching strategies hard coded.

## Configuration tool
Expand Down Expand Up @@ -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: '[/-](?<number>\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.

Expand Down
43 changes: 43 additions & 0 deletions src/GitVersionCore.Tests/VariableProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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: @"[/-](?<number>\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");
}
}
19 changes: 18 additions & 1 deletion src/GitVersionCore/OutputVariables/VariableProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
{
using System;
using System.ComponentModel;
using System.Text.RegularExpressions;
using GitVersion.VersionCalculation;

public static class VariableProvider
{
Expand All @@ -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
Expand Down
42 changes: 24 additions & 18 deletions src/GitVersionCore/VersionCalculation/NextVersionCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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 &&
Expand Down