Skip to content

Commit

Permalink
feat: Support fallback environment source branch (#146)
Browse files Browse the repository at this point in the history
* feat: Add TeamCity Environment

Introduces TeamCity Environment detection based on
TEAMCITY_VERSION variable.

Implements #141

* chore: Remove Teamcity specific implementation

* chore: Ignore Resharper assets

* feature: Enable BaseVersionEnvironment to resolve branch environment variable

Exposes `simpleversion.sourcebranch` to environments by default

* feature: Expose default environment branhc to all

* docs: Environments section added

* fix: Correct broken tests

Co-authored-by: Anna Moser <[email protected]>
  • Loading branch information
Kieranties and Anna Moser authored May 15, 2022
1 parent 49e1600 commit 4fc670e
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 25 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ testResults.xml
coverage.xml
coverage.cobertura.xml
*.trx
*.DotSettings.user
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Licensed under the MIT license. See https://kieranties.mit-license.org/ for full license information.

using System;
using SimpleVersion.Pipeline;
using System.Text.RegularExpressions;

namespace SimpleVersion.Environment
{
Expand All @@ -10,20 +10,30 @@ namespace SimpleVersion.Environment
/// </summary>
public abstract class BaseVersionEnvironment : IVersionEnvironment
{
/// <summary>
/// Use to normalize branch names from a canonical name.
/// </summary>
protected static readonly Regex CanonicalBranchTrimmer = new Regex(@"^refs\/(heads\/)?", RegexOptions.IgnoreCase);

/// <summary>
/// Initializes a new instance of the <see cref="BaseVersionEnvironment"/> class.
/// </summary>
/// <param name="accessor">The accessor for environment variables.</param>
public BaseVersionEnvironment(IEnvironmentVariableAccessor accessor)
protected BaseVersionEnvironment(IEnvironmentVariableAccessor accessor)
{
Variables = accessor ?? throw new ArgumentNullException(nameof(accessor));
CanonicalBranchName = Variables.GetVariable("simpleversion.sourcebranch");
if (CanonicalBranchName != null)
{
BranchName = CanonicalBranchTrimmer.Replace(CanonicalBranchName, string.Empty);
}
}

/// <inheritdoc/>
public abstract string? CanonicalBranchName { get; }
public string? CanonicalBranchName { get; protected set; }

/// <inheritdoc/>
public abstract string? BranchName { get; }
public string? BranchName { get; protected set; }

/// <inheritdoc/>
public abstract bool IsValid { get; }
Expand Down
17 changes: 6 additions & 11 deletions src/SimpleVersion.Core/Environment/AzureDevopsEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,23 @@ namespace SimpleVersion.Environment
/// </summary>
public class AzureDevopsEnvironment : BaseVersionEnvironment
{
private static readonly Regex _trim = new Regex(@"^refs\/(heads\/)?", RegexOptions.IgnoreCase);

/// <summary>
/// Initializes a new instance of the <see cref="AzureDevopsEnvironment"/> class.
/// </summary>
/// <param name="accessor">The accessor for environment variables.</param>
public AzureDevopsEnvironment(IEnvironmentVariableAccessor accessor)
: base(accessor)
{
CanonicalBranchName = Variables.GetVariable("BUILD_SOURCEBRANCH");
if (CanonicalBranchName != null)
if (string.IsNullOrWhiteSpace(CanonicalBranchName))
{
BranchName = _trim.Replace(CanonicalBranchName, string.Empty);
CanonicalBranchName = Variables.GetVariable("BUILD_SOURCEBRANCH");
if (CanonicalBranchName != null)
{
BranchName = CanonicalBranchTrimmer.Replace(CanonicalBranchName, string.Empty);
}
}
}

/// <inheritdoc/>
public override string? CanonicalBranchName { get; }

/// <inheritdoc/>
public override string? BranchName { get; }

/// <inheritdoc/>
public override bool IsValid => Variables.GetVariable("TF_BUILD").ToBool();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ public DefaultVersionEnvironment(IEnvironmentVariableAccessor accessor) : base(a
{
}

/// <inheritdoc/>
public override string? CanonicalBranchName => null;

/// <inheritdoc/>
public override string? BranchName => null;

/// <inheritdoc/>
public override bool IsValid => true;
}
Expand Down
26 changes: 26 additions & 0 deletions src/SimpleVersion.Docs/site/articles/environments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Environments
============

SimpleVersion attempts to identify git information from the local environment.
When running on Continuous Integration (CI) systems you may need to prepare the
environment to cater for the CI systems specific approach to builds.

Azure Devops
------------

Azure Devops is identified as the build environment when the environment variable `TF_BUILD` is set.

When identified, the canonical and friendly branch names are derived from the `BUILD_SOURCEBRANCH` environment variable.

Fallback Environment
--------------------

For all environments, the build branch can be overridden by setting `simpleversion.sourcebranch` to the _full canonical branch name_. When this variable is set it will override the resolution from any CI system as well as the local repository branch name.

### TeamCity

When building with TeamCity you can lift the branch name of the build to an environment variable by doing the following:

1. Open your build configuration, and select Parameters
1. Add a new paramter called `env.simpleversion.sourcebranch`
1. Set the value to `%teamcity.build.vcs.branch.{vcsid}%` where `{vcsid}` is the VCS Root of your repo
2 changes: 2 additions & 0 deletions src/SimpleVersion.Docs/site/articles/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
href: intro.md
- name: Configuration
href: configuration.md
- name: Environments
href: environments.md
- name: Results
href: results.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,28 @@ public void Ctor_WithAccessor_SetsProperty()
instance.VariablesWrapper.Should().BeSameAs(accessor);
}

[Fact]
public void BranchName_OverrideSet_ReturnsOverride()
{
// Arrange
var expectedName = "OVERRIDE";
var accessor = Substitute.For<IEnvironmentVariableAccessor>();
accessor.GetVariable("simpleversion.sourcebranch").Returns(expectedName);
var sut = new StubVersionEnvironment(accessor);

// Act
var result = sut.BranchName;

// Assert
result.Should().Be(expectedName);
}

private class StubVersionEnvironment : BaseVersionEnvironment
{
public StubVersionEnvironment(IEnvironmentVariableAccessor accessor) : base(accessor)
{
}

public override string CanonicalBranchName => throw new NotImplementedException("Should not be tested");

public override string BranchName => throw new NotImplementedException("Should not be tested");

public override bool IsValid => throw new NotImplementedException("Should not be tested");

public IEnvironmentVariableAccessor VariablesWrapper => Variables;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,25 @@ public void BranchName_ReadsCorrectVariable(string canonical, string branch)
// Assert
result.Should().Be(branch);
}

[Theory]
[InlineData("refs/heads/master")]
[InlineData("refs/heads/release/1.0/master")]
[InlineData("refs/pull/10/merge")]
public void BranchName_OverrideSet_ReturnsOverride(string canonical)
{
// Arrange
var expectedName = "override";
_env.GetVariable("simpleversion.sourcebranch").Returns(expectedName);
_env.GetVariable("BUILD_SOURCEBRANCH").Returns(canonical);

var sut = new AzureDevopsEnvironment(_env);

// Act
var result = sut.BranchName;

// Assert
result.Should().Be(expectedName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class DefaultVersionEnvironmentFixture
public DefaultVersionEnvironmentFixture()
{
_env = Substitute.For<IEnvironmentVariableAccessor>();
_env.GetVariable("simpleversion.sourcebranch").Returns((string)null);
}

[Fact]
Expand Down Expand Up @@ -66,5 +67,20 @@ public void BranchName_ReturnsNull()
// Assert
result.Should().BeNull();
}

[Fact]
public void BranchName_OverrideSet_ReturnsOverride()
{
// Arrange
var expectedName = "OVERRIDE";
_env.GetVariable("simpleversion.sourcebranch").Returns(expectedName);
var sut = new DefaultVersionEnvironment(_env);

// Act
var result = sut.BranchName;

// Assert
result.Should().Be(expectedName);
}
}
}

0 comments on commit 4fc670e

Please sign in to comment.