Skip to content

Commit cb46ec6

Browse files
authored
Merge pull request #81 from AArnott/fix80
Set MSBuild properties and env vars with cloud build variables
2 parents eadcc5f + 83b723d commit cb46ec6

File tree

9 files changed

+109
-32
lines changed

9 files changed

+109
-32
lines changed

src/NerdBank.GitVersioning.Tests/BuildIntegrationTests.cs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,13 @@ public async Task CloudBuildVariables_SetInCI(IReadOnlyDictionary<string, string
438438
Assert.Contains(alwaysExpectedMessage, buildResult.LoggedEvents.Select(e => e.Message.TrimEnd()));
439439
Assert.Contains(conditionallyExpectedMessage, buildResult.LoggedEvents.Select(e => e.Message.TrimEnd()));
440440

441+
// Assert that project properties are also set.
442+
Assert.Equal(buildResult.BuildVersion, buildResult.GitBuildVersion);
443+
Assert.Equal(buildResult.AssemblyInformationalVersion, buildResult.GitAssemblyInformationalVersion);
444+
445+
// Assert that env variables were also set in context of the build.
446+
Assert.True(buildResult.LoggedEvents.Any(e => string.Equals(e.Message, $"n1=v1", StringComparison.OrdinalIgnoreCase)));
447+
441448
versionOptions.CloudBuild.SetVersionVariables = false;
442449
this.WriteVersionFile(versionOptions);
443450
buildResult = await this.BuildAsync();
@@ -447,6 +454,7 @@ public async Task CloudBuildVariables_SetInCI(IReadOnlyDictionary<string, string
447454
.Replace("{VALUE}", buildResult.BuildVersion);
448455
Assert.Contains(alwaysExpectedMessage, buildResult.LoggedEvents.Select(e => e.Message.TrimEnd()));
449456
Assert.DoesNotContain(conditionallyExpectedMessage, buildResult.LoggedEvents.Select(e => e.Message.TrimEnd()));
457+
Assert.NotEqual(buildResult.BuildVersion, buildResult.BuildResult.ProjectStateAfterBuild.GetPropertyValue("GitBuildVersion"));
450458
}
451459
}
452460

@@ -842,26 +850,13 @@ where name.StartsWith(prefix, StringComparison.Ordinal)
842850

843851
private ProjectRootElement CreateProjectRootElement(string projectDirectory, string projectName)
844852
{
845-
var pre = ProjectRootElement.Create(this.projectCollection);
846-
pre.FullPath = Path.Combine(projectDirectory, projectName);
847-
848-
pre.AddProperty("RootNamespace", "TestNamespace");
849-
pre.AddProperty("AssemblyName", "TestAssembly");
850-
pre.AddProperty("AssemblyTitle", "TestAssembly");
851-
pre.AddProperty("AssemblyProduct", "TestProduct");
852-
pre.AddProperty("AssemblyCompany", "TestCompany");
853-
pre.AddProperty("AssemblyCopyright", "TestCopyright");
854-
pre.AddProperty("AssemblyConfiguration", "TestConfiguration");
855-
pre.AddProperty("TargetFrameworkVersion", "v4.5");
856-
pre.AddProperty("OutputType", "Library");
857-
pre.AddProperty("OutputPath", @"bin\");
858-
859-
pre.AddItem("Reference", "System");
860-
861-
pre.AddImport(@"$(MSBuildToolsPath)\Microsoft.CSharp.targets");
862-
pre.AddImport(Path.Combine(this.RepoPath, GitVersioningTargetsFileName));
863-
864-
return pre;
853+
using (var reader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream($"{ThisAssembly.RootNamespace}.test.proj")))
854+
{
855+
var pre = ProjectRootElement.Create(reader, this.projectCollection);
856+
pre.FullPath = Path.Combine(projectDirectory, projectName);
857+
pre.AddImport(Path.Combine(this.RepoPath, GitVersioningTargetsFileName));
858+
return pre;
859+
}
865860
}
866861

867862
private void MakeItAVBProject()
@@ -947,6 +942,9 @@ internal BuildResults(BuildResult buildResult, IReadOnlyList<BuildEventArgs> log
947942
public string AssemblyConfiguration => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("Configuration");
948943
public string RootNamespace => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("RootNamespace");
949944

945+
public string GitBuildVersion => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("GitBuildVersion");
946+
public string GitAssemblyInformationalVersion => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("GitAssemblyInformationalVersion");
947+
950948
public override string ToString()
951949
{
952950
var sb = new StringBuilder();

src/NerdBank.GitVersioning.Tests/NerdBank.GitVersioning.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
<ItemGroup>
8282
<EmbeddedResource Include="Keys\protectedPair.pfx" />
8383
<None Include="project.json" />
84+
<EmbeddedResource Include="test.proj" />
8485
</ItemGroup>
8586
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
8687
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<RootNamespace>TestNamespace</RootNamespace>
5+
<AssemblyName>TestAssembly</AssemblyName>
6+
<AssemblyTitle>TestAssembly</AssemblyTitle>
7+
<AssemblyProduct>TestProduct</AssemblyProduct>
8+
<AssemblyCompany>TestCompany</AssemblyCompany>
9+
<AssemblyCopyright>TestCopyright</AssemblyCopyright>
10+
<AssemblyConfiguration>TestConfiguration</AssemblyConfiguration>
11+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
12+
<OutputType>Library</OutputType>
13+
<OutputPath>bin\</OutputPath>
14+
</PropertyGroup>
15+
<ItemGroup>
16+
<Reference Include="System" />
17+
</ItemGroup>
18+
<Target Name="PrintEnvironmentVariables"
19+
DependsOnTargets="SetCloudBuildNumberWithVersion;SetCloudBuildVersionVars"
20+
AfterTargets="GetBuildVersion">
21+
<Exec Command="set" />
22+
</Target>
23+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
24+
</Project>

src/NerdBank.GitVersioning/CloudBuildServices/AppVeyor.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace Nerdbank.GitVersioning.CloudBuildServices
22
{
33
using System;
4+
using System.Collections.Generic;
45
using System.ComponentModel;
56
using System.Diagnostics;
67
using System.IO;
@@ -37,15 +38,17 @@ internal class AppVeyor : ICloudBuild
3738

3839
public bool IsPullRequest => !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("APPVEYOR_PULL_REQUEST_NUMBER"));
3940

40-
public void SetCloudBuildNumber(string buildNumber, TextWriter stdout, TextWriter stderr)
41+
public IReadOnlyDictionary<string, string> SetCloudBuildNumber(string buildNumber, TextWriter stdout, TextWriter stderr)
4142
{
4243
// We ignore exit code so as to not fail the build when the cloud build number is not unique.
4344
RunAppveyor($"UpdateBuild -Version \"{buildNumber}\"", stdout, stderr);
45+
return new Dictionary<string, string>();
4446
}
4547

46-
public void SetCloudBuildVariable(string name, string value, TextWriter stdout, TextWriter stderr)
48+
public IReadOnlyDictionary<string, string> SetCloudBuildVariable(string name, string value, TextWriter stdout, TextWriter stderr)
4749
{
4850
RunAppveyor($"SetVariable -Name {name} -Value \"{value}\"", stdout, stderr);
51+
return new Dictionary<string, string>();
4952
}
5053

5154
private static void RunAppveyor(string args, TextWriter stdout, TextWriter stderr)

src/NerdBank.GitVersioning/CloudBuildServices/TeamCity.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace Nerdbank.GitVersioning.CloudBuildServices
22
{
33
using System;
4+
using System.Collections.Generic;
45
using System.IO;
56

67
internal class TeamCity : ICloudBuild
@@ -15,12 +16,14 @@ internal class TeamCity : ICloudBuild
1516

1617
public bool IsPullRequest => false;
1718

18-
public void SetCloudBuildNumber(string buildNumber, TextWriter stdout, TextWriter stderr)
19+
public IReadOnlyDictionary<string, string> SetCloudBuildNumber(string buildNumber, TextWriter stdout, TextWriter stderr)
1920
{
21+
return new Dictionary<string, string>();
2022
}
2123

22-
public void SetCloudBuildVariable(string name, string value, TextWriter stdout, TextWriter stderr)
24+
public IReadOnlyDictionary<string, string> SetCloudBuildVariable(string name, string value, TextWriter stdout, TextWriter stderr)
2325
{
26+
return new Dictionary<string, string>();
2427
}
2528
}
2629
}

src/NerdBank.GitVersioning/CloudBuildServices/VisualStudioTeamServices.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace Nerdbank.GitVersioning.CloudBuildServices
22
{
33
using System;
4+
using System.Collections.Generic;
45
using System.IO;
56

67
/// <summary>
@@ -24,14 +25,26 @@ internal class VisualStudioTeamServices : ICloudBuild
2425

2526
public bool IsApplicable => !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("SYSTEM_TEAMPROJECTID"));
2627

27-
public void SetCloudBuildNumber(string buildNumber, TextWriter stdout, TextWriter stderr)
28+
public IReadOnlyDictionary<string, string> SetCloudBuildNumber(string buildNumber, TextWriter stdout, TextWriter stderr)
2829
{
2930
(stdout ?? Console.Out).WriteLine($"##vso[build.updatebuildnumber]{buildNumber}");
31+
return GetDictionaryFor("Build.BuildNumber", buildNumber);
3032
}
3133

32-
public void SetCloudBuildVariable(string name, string value, TextWriter stdout, TextWriter stderr)
34+
public IReadOnlyDictionary<string, string> SetCloudBuildVariable(string name, string value, TextWriter stdout, TextWriter stderr)
3335
{
3436
(stdout ?? Console.Out).WriteLine($"##vso[task.setvariable variable={name};]{value}");
37+
return GetDictionaryFor(name, value);
3538
}
39+
40+
private static IReadOnlyDictionary<string, string> GetDictionaryFor(string variableName, string value)
41+
{
42+
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
43+
{
44+
{ GetEnvironmentVariableNameForVariable(variableName), value },
45+
};
46+
}
47+
48+
private static string GetEnvironmentVariableNameForVariable(string name) => name.ToUpperInvariant().Replace('.', '_');
3649
}
3750
}

src/NerdBank.GitVersioning/ICloudBuild.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
namespace Nerdbank.GitVersioning
22
{
3+
using System.Collections.Generic;
34
using System.IO;
45

56
/// <summary>
@@ -38,7 +39,8 @@ public interface ICloudBuild
3839
/// <param name="buildNumber">The build number to set.</param>
3940
/// <param name="stdout">An optional redirection for what should be written to the standard out stream.</param>
4041
/// <param name="stderr">An optional redirection for what should be written to the standard error stream.</param>
41-
void SetCloudBuildNumber(string buildNumber, TextWriter stdout, TextWriter stderr);
42+
/// <returns>A dictionary of environment/build variables that the caller should set to update the environment to match the new settings.</returns>
43+
IReadOnlyDictionary<string, string> SetCloudBuildNumber(string buildNumber, TextWriter stdout, TextWriter stderr);
4244

4345
/// <summary>
4446
/// Sets a cloud build variable, if supported.
@@ -47,6 +49,7 @@ public interface ICloudBuild
4749
/// <param name="value">The value for the variable.</param>
4850
/// <param name="stdout">An optional redirection for what should be written to the standard out stream.</param>
4951
/// <param name="stderr">An optional redirection for what should be written to the standard error stream.</param>
50-
void SetCloudBuildVariable(string name, string value, TextWriter stdout, TextWriter stderr);
52+
/// <returns>A dictionary of environment/build variables that the caller should set to update the environment to match the new settings.</returns>
53+
IReadOnlyDictionary<string, string> SetCloudBuildVariable(string name, string value, TextWriter stdout, TextWriter stderr);
5154
}
5255
}

src/Nerdbank.GitVersioning.NuGet/build/NerdBank.GitVersioning.targets

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,25 @@
8282
AfterTargets="GetBuildVersion"
8383
Condition=" '@(CloudBuildVersionVars)' != '' ">
8484
<Nerdbank.GitVersioning.Tasks.SetCloudBuildVariables
85-
CloudBuildVersionVars="@(CloudBuildVersionVars)" />
85+
CloudBuildVersionVars="@(CloudBuildVersionVars)">
86+
<Output TaskParameter="MSBuildPropertyUpdates" ItemName="_MSBuildPropertyUpdates_Vars" />
87+
</Nerdbank.GitVersioning.Tasks.SetCloudBuildVariables>
88+
<CreateProperty Value="%(_MSBuildPropertyUpdates_Vars.Value)" Condition=" '@(_MSBuildPropertyUpdates_Vars)' != '' ">
89+
<Output TaskParameter="Value" PropertyName="%(_MSBuildPropertyUpdates_Vars.Identity)" />
90+
</CreateProperty>
8691
</Target>
8792

8893
<Target Name="SetCloudBuildNumberWithVersion"
8994
DependsOnTargets="GetBuildVersion"
9095
AfterTargets="GetBuildVersion"
9196
Condition=" '$(CloudBuildNumber)' != '' ">
9297
<Nerdbank.GitVersioning.Tasks.SetCloudBuildVariables
93-
CloudBuildNumber="$(CloudBuildNumber)" />
98+
CloudBuildNumber="$(CloudBuildNumber)">
99+
<Output TaskParameter="MSBuildPropertyUpdates" ItemName="_MSBuildPropertyUpdates_BuildNumber" />
100+
</Nerdbank.GitVersioning.Tasks.SetCloudBuildVariables>
101+
<CreateProperty Value="%(_MSBuildPropertyUpdates_BuildNumber.Value)" Condition=" '@(_MSBuildPropertyUpdates_BuildNumber)' != '' ">
102+
<Output TaskParameter="Value" PropertyName="%(_MSBuildPropertyUpdates_BuildNumber.Identity)" />
103+
</CreateProperty>
94104
</Target>
95105

96106
<Target Name="GetNuGetPackageVersion" DependsOnTargets="GetBuildVersion" Returns="$(NuGetPackageVersion)" />

src/Nerdbank.GitVersioning.Tasks/SetCloudBuildVariables.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,18 @@ public class SetCloudBuildVariables : Task
1212
{
1313
public ITaskItem[] CloudBuildVersionVars { get; set; }
1414

15+
[Output]
16+
public ITaskItem[] MSBuildPropertyUpdates { get; set; }
17+
1518
public string CloudBuildNumber { get; set; }
1619

1720
public override bool Execute()
1821
{
1922
var cloudBuild = CloudBuild.Active;
2023
if (cloudBuild != null)
2124
{
25+
var envVars = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
26+
2227
// Take care in a unit test environment because it would actually
2328
// adversely impact the build variables of the cloud build underway that
2429
// is running the tests.
@@ -30,17 +35,34 @@ public override bool Execute()
3035

3136
if (!string.IsNullOrWhiteSpace(this.CloudBuildNumber))
3237
{
33-
cloudBuild.SetCloudBuildNumber(this.CloudBuildNumber, stdout, stderr);
38+
var newVars = cloudBuild.SetCloudBuildNumber(this.CloudBuildNumber, stdout, stderr);
39+
foreach (var item in newVars)
40+
{
41+
envVars[item.Key] = item.Value;
42+
}
3443
}
3544

3645
if (this.CloudBuildVersionVars != null)
3746
{
3847
foreach (var variable in this.CloudBuildVersionVars)
3948
{
40-
cloudBuild.SetCloudBuildVariable(variable.ItemSpec, variable.GetMetadata("Value"), stdout, stderr);
49+
var newVars = cloudBuild.SetCloudBuildVariable(variable.ItemSpec, variable.GetMetadata("Value"), stdout, stderr);
50+
foreach (var item in newVars)
51+
{
52+
envVars[item.Key] = item.Value;
53+
}
4154
}
4255
}
4356

57+
this.MSBuildPropertyUpdates = (from envVar in envVars
58+
let metadata = new Dictionary<string, string> { { "Value", envVar.Value } }
59+
select new TaskItem(envVar.Key, metadata)).ToArray();
60+
61+
foreach (var item in envVars)
62+
{
63+
Environment.SetEnvironmentVariable(item.Key, item.Value, EnvironmentVariableTarget.Process);
64+
}
65+
4466
if (isUnitTest)
4567
{
4668
PipeOutputToMSBuildLog(testStdOut.ToString(), warning: false);

0 commit comments

Comments
 (0)