Skip to content

Commit

Permalink
Merge pull request #159 from heaths/issue130
Browse files Browse the repository at this point in the history
Add option to set all cloud variables
  • Loading branch information
AArnott authored Jan 28, 2018
2 parents 146671c + 37d476d commit 6c88c60
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 7 deletions.
24 changes: 21 additions & 3 deletions src/NerdBank.GitVersioning.Tests/BuildIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -484,14 +484,15 @@ public static object[][] CloudBuildVariablesData
{
return new object[][]
{
new object[] { CloudBuild.VSTS, "##vso[task.setvariable variable={NAME};]{VALUE}" },
new object[] { CloudBuild.VSTS, "##vso[task.setvariable variable={NAME};]{VALUE}", false },
new object[] { CloudBuild.VSTS, "##vso[task.setvariable variable={NAME};]{VALUE}", true },
};
}
}

[Theory]
[MemberData(nameof(CloudBuildVariablesData))]
public async Task CloudBuildVariables_SetInCI(IReadOnlyDictionary<string, string> properties, string expectedMessage)
public async Task CloudBuildVariables_SetInCI(IReadOnlyDictionary<string, string> properties, string expectedMessage, bool setAllVariables)
{
using (ApplyEnvironmentVariables(properties))
{
Expand All @@ -506,7 +507,7 @@ public async Task CloudBuildVariables_SetInCI(IReadOnlyDictionary<string, string
var versionOptions = new VersionOptions
{
Version = SemanticVersion.Parse("1.0"),
CloudBuild = new VersionOptions.CloudBuildOptions { SetVersionVariables = true },
CloudBuild = new VersionOptions.CloudBuildOptions { SetAllVariables = setAllVariables, SetVersionVariables = true },
};
this.WriteVersionFile(versionOptions);
this.InitializeSourceControl();
Expand All @@ -533,6 +534,19 @@ public async Task CloudBuildVariables_SetInCI(IReadOnlyDictionary<string, string
Assert.Equal(buildResult.BuildVersionSimple, buildResult.GitBuildVersionSimple);
Assert.Equal(buildResult.AssemblyInformationalVersion, buildResult.GitAssemblyInformationalVersion);

if (setAllVariables)
{
// Assert that some project properties were set as build properties prefaced with "NBGV_".
Assert.Equal(buildResult.GitCommitIdShort, buildResult.NBGV_GitCommitIdShort);
Assert.Equal(buildResult.NuGetPackageVersion, buildResult.NBGV_NuGetPackageVersion);
}
else
{
// Assert that the NBGV_ prefixed properties are *not* set.
Assert.Equal(string.Empty, buildResult.NBGV_GitCommitIdShort);
Assert.Equal(string.Empty, buildResult.NBGV_NuGetPackageVersion);
}

// Assert that env variables were also set in context of the build.
Assert.True(buildResult.LoggedEvents.Any(e => string.Equals(e.Message, $"n1=v1", StringComparison.OrdinalIgnoreCase)));

Expand Down Expand Up @@ -1127,6 +1141,10 @@ internal BuildResults(BuildResult buildResult, IReadOnlyList<BuildEventArgs> log
public string GitBuildVersionSimple => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("GitBuildVersionSimple");
public string GitAssemblyInformationalVersion => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("GitAssemblyInformationalVersion");

// Just a sampling of other properties optionally set in cloud build.
public string NBGV_GitCommitIdShort => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("NBGV_GitCommitIdShort");
public string NBGV_NuGetPackageVersion => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("NBGV_NuGetPackageVersion");

public override string ToString()
{
var sb = new StringBuilder();
Expand Down
1 change: 1 addition & 0 deletions src/NerdBank.GitVersioning.Tests/VersionFileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ public void SetVersion_WritesSimplestFile(string version, string assemblyVersion
[InlineData(@"{""cloudBuild"":{""buildNumber"":{""enabled"":true,""includeCommitId"":{""when"":""always"",""where"":""buildMetadata""}}}}", @"{""cloudBuild"":{""buildNumber"":{""enabled"":true,""includeCommitId"":{""when"":""always""}}}}")]
[InlineData(@"{""cloudBuild"":{""buildNumber"":{""enabled"":true,""includeCommitId"":{""when"":""nonPublicReleaseOnly"",""where"":""fourthVersionComponent""}}}}", @"{""cloudBuild"":{""buildNumber"":{""enabled"":true,""includeCommitId"":{""where"":""fourthVersionComponent""}}}}")]
[InlineData(@"{""cloudBuild"":{""setVersionVariables"":true}}", @"{}")]
[InlineData(@"{""cloudBuild"":{""setAllVariables"":false}}", @"{}")]
public void JsonMinification(string full, string minimal)
{
var settings = VersionOptions.GetJsonSettings();
Expand Down
23 changes: 22 additions & 1 deletion src/NerdBank.GitVersioning/VersionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -458,12 +458,16 @@ public class CloudBuildOptions : IEquatable<CloudBuildOptions>
/// </summary>
internal static readonly CloudBuildOptions DefaultInstance = new CloudBuildOptions(isReadOnly: true)
{
setAllVariables = false,
setVersionVariables = true,
};

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly bool isReadOnly;

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private bool? setAllVariables;

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private bool? setVersionVariables;

Expand All @@ -486,6 +490,15 @@ protected CloudBuildOptions(bool isReadOnly)
this.isReadOnly = isReadOnly;
}

/// <summary>
/// Gets or sets a value indicating whether to elevate all build properties to cloud build variables prefaced with "NBGV_".
/// </summary>
public bool? SetAllVariables
{
get => this.setAllVariables;
set => this.SetIfNotReadOnly(ref this.setAllVariables, value);
}

/// <summary>
/// Gets or sets a value indicating whether to elevate certain calculated version build properties to cloud build variables.
/// </summary>
Expand All @@ -495,6 +508,12 @@ public bool? SetVersionVariables
set => this.SetIfNotReadOnly(ref this.setVersionVariables, value);
}

/// <summary>
/// Gets a value indicating whether to elevate all build properties to cloud build variables prefaced with "NBGV_".
/// </summary>
[JsonIgnore]
public bool SetAllVariablesOrDefault => this.SetAllVariables ?? DefaultInstance.SetAllVariables.Value;

/// <summary>
/// Gets a value indicating whether to elevate certain calculated version build properties to cloud build variables.
/// </summary>
Expand Down Expand Up @@ -562,13 +581,15 @@ public bool Equals(CloudBuildOptions x, CloudBuildOptions y)
}

return x.SetVersionVariablesOrDefault == y.SetVersionVariablesOrDefault
&& x.SetAllVariablesOrDefault == y.SetAllVariablesOrDefault
&& CloudBuildNumberOptions.EqualWithDefaultsComparer.Singleton.Equals(x.BuildNumberOrDefault, y.BuildNumberOrDefault);
}

/// <inheritdoc />
public int GetHashCode(CloudBuildOptions obj)
{
return obj.SetVersionVariablesOrDefault ? 1 : 0
return (obj.SetVersionVariablesOrDefault ? 1 : 0)
+ (obj.SetAllVariablesOrDefault ? 1 : 0)
+ obj.BuildNumberOrDefault.GetHashCode();
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/NerdBank.GitVersioning/VersionOptionsContractResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerializ
property.ShouldSerialize = instance => !((VersionOptions)instance).CloudBuildOrDefault.IsDefault;
}

if (property.DeclaringType == typeof(VersionOptions.CloudBuildOptions) && member.Name == nameof(VersionOptions.CloudBuildOptions.SetAllVariables))
{
property.ShouldSerialize = instance => ((VersionOptions.CloudBuildOptions)instance).SetAllVariablesOrDefault != VersionOptions.CloudBuildOptions.DefaultInstance.SetAllVariables.Value;
}

if (property.DeclaringType == typeof(VersionOptions.CloudBuildOptions) && member.Name == nameof(VersionOptions.CloudBuildOptions.SetVersionVariables))
{
property.ShouldSerialize = instance => ((VersionOptions.CloudBuildOptions)instance).SetVersionVariablesOrDefault != VersionOptions.CloudBuildOptions.DefaultInstance.SetVersionVariables.Value;
Expand Down
46 changes: 46 additions & 0 deletions src/NerdBank.GitVersioning/VersionOracle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using Validation;

Expand Down Expand Up @@ -124,11 +125,13 @@ public string CloudBuildNumber
/// <summary>
/// Gets a value indicating whether the cloud build number should be set.
/// </summary>
[Ignore]
public bool CloudBuildNumberEnabled => this.CloudBuildNumberOptions.EnabledOrDefault;

/// <summary>
/// Gets the build metadata identifiers, including the git commit ID as the first identifier if appropriate.
/// </summary>
[Ignore]
public IEnumerable<string> BuildMetadataWithCommitId
{
get
Expand Down Expand Up @@ -228,16 +231,53 @@ public IEnumerable<string> BuildMetadataWithCommitId
/// </summary>
public Version Version { get; }

/// <summary>
/// Gets a value indicating whether to set all cloud build variables prefaced with "NBGV_".
/// </summary>
[Ignore]
public bool CloudBuildAllVarsEnabled => this.VersionOptions?.CloudBuildOrDefault.SetAllVariablesOrDefault
?? VersionOptions.CloudBuildOptions.DefaultInstance.SetAllVariablesOrDefault;

/// <summary>
/// Gets a dictionary of all cloud build variables that applies to this project,
/// regardless of the current setting of <see cref="CloudBuildAllVarsEnabled"/>.
/// </summary>
[Ignore]
public IDictionary<string, string> CloudBuildAllVars
{
get
{
var variables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

var properties = this.GetType().GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance);
foreach (var property in properties)
{
if (property.GetCustomAttribute<IgnoreAttribute>() == null)
{
var value = property.GetValue(this);
if (value != null)
{
variables.Add($"NBGV_{property.Name}", value.ToString());
}
}
}

return variables;
}
}

/// <summary>
/// Gets a value indicating whether to set cloud build version variables.
/// </summary>
[Ignore]
public bool CloudBuildVersionVarsEnabled => this.VersionOptions?.CloudBuildOrDefault.SetVersionVariablesOrDefault
?? VersionOptions.CloudBuildOptions.DefaultInstance.SetVersionVariablesOrDefault;

/// <summary>
/// Gets a dictionary of cloud build variables that applies to this project,
/// regardless of the current setting of <see cref="CloudBuildVersionVarsEnabled"/>.
/// </summary>
[Ignore]
public IDictionary<string, string> CloudBuildVersionVars
{
get
Expand All @@ -254,6 +294,7 @@ public IDictionary<string, string> CloudBuildVersionVars
/// <summary>
/// Gets the list of build metadata identifiers to include in semver version strings.
/// </summary>
[Ignore]
public List<string> BuildMetadata { get; } = new List<string>();

/// <summary>
Expand Down Expand Up @@ -450,5 +491,10 @@ private static bool IsVersionFileChangedInWorkingTree(VersionOptions committedVe
// A missing working version is a change only if it was previously commited.
return committedVersion != null;
}

[AttributeUsage(AttributeTargets.Property)]
private class IgnoreAttribute : Attribute
{
}
}
}
5 changes: 5 additions & 0 deletions src/NerdBank.GitVersioning/version.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@
"type": "object",
"description": "Options that are applicable specifically to cloud builds (e.g. VSTS, AppVeyor, TeamCity)",
"properties": {
"setAllVariables": {
"type": "boolean",
"default": false,
"description": "Elevates all build properties to cloud build variables prefaced with \"NBGV_\""
},
"setVersionVariables": {
"type": "boolean",
"default": true,
Expand Down
27 changes: 24 additions & 3 deletions src/Nerdbank.GitVersioning.Tasks/GetBuildVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,32 @@ protected override bool ExecuteInner()
this.NuGetPackageVersion = oracle.NuGetPackageVersion;
this.NpmPackageVersion = oracle.NpmPackageVersion;

IEnumerable<ITaskItem> cloudBuildVersionVars = null;
if (oracle.CloudBuildVersionVarsEnabled)
{
this.CloudBuildVersionVars = oracle.CloudBuildVersionVars
.Select(item => new TaskItem(item.Key, new Dictionary<string, string> { { "Value", item.Value } }))
.ToArray();
cloudBuildVersionVars = oracle.CloudBuildVersionVars
.Select(item => new TaskItem(item.Key, new Dictionary<string, string> { { "Value", item.Value } }));
}

if (oracle.CloudBuildAllVarsEnabled)
{
var allVariables = oracle.CloudBuildAllVars
.Select(item => new TaskItem(item.Key, new Dictionary<string, string> { { "Value", item.Value } }));

if (cloudBuildVersionVars != null)
{
cloudBuildVersionVars = cloudBuildVersionVars
.Union(allVariables);
}
else
{
cloudBuildVersionVars = allVariables;
}
}

if (cloudBuildVersionVars != null)
{
this.CloudBuildVersionVars = cloudBuildVersionVars.ToArray();
}

return !this.Log.HasLoggedErrors;
Expand Down

0 comments on commit 6c88c60

Please sign in to comment.