Skip to content

Commit 7a4397a

Browse files
committed
Merge remote-tracking branch 'refs/remotes/origin/master'
2 parents a155350 + 5bbc428 commit 7a4397a

File tree

12 files changed

+702
-37
lines changed

12 files changed

+702
-37
lines changed

doc/cloudbuild.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ you can activate features for some cloud build systems, as follows
2121
Cloud builds tend to associate some calendar date or monotonically increasing
2222
build number to each build. These build numbers are not very informative, if at all.
2323
Instead, Nerdbank.GitVersioning can automatically set your cloud build's
24-
build number to equal the semver version calculated during your build.
24+
build number to equal the semver version calculated during your build.
2525

2626
Enable this feature by setting the `cloudBuild.buildNumber.enabled` field
2727
in your `version.json` file to `true`, as shown below:
@@ -76,4 +76,12 @@ in your `version.json` file to `true`, as shown below:
7676
}
7777
```
7878

79+
## CI Server specific configurations
80+
81+
### TeamCity
82+
TeamCity does not expose the build branch by default as an environment variable. This can be exposed by
83+
adding an environment variable with the value of `%teamcity.build.vcs.branch.<vcsid>%` where `<vcsid>` is
84+
the root id described on the TeamCity VCS roots page. Details on this variable can be found on the
85+
[TeamCity docs](https://confluence.jetbrains.com/display/TCD8/Predefined+Build+Parameters).
86+
7987
[Issue37]: https://github.com/AArnott/Nerdbank.GitVersioning/issues/37

src/NerdBank.GitVersioning.Tests/BuildIntegrationTests.cs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ public static IEnumerable<object[]> CloudBuildOfBranch(string branchName)
436436
new object[] { CloudBuild.AppVeyor.SetItem("APPVEYOR_REPO_BRANCH", branchName) },
437437
new object[] { CloudBuild.VSTS.SetItem("BUILD_SOURCEBRANCH", $"refs/heads/{branchName}") },
438438
new object[] { CloudBuild.VSTS.SetItem("BUILD_SOURCEBRANCH", branchName) }, // VSTS building a github repo
439+
new object[] { CloudBuild.Teamcity.SetItem("BUILD_GIT_BRANCH", $"refs/heads/{branchName}") },
439440
};
440441
}
441442

@@ -802,6 +803,29 @@ public async Task AssemblyInfo_SuppressedImplicitlyByTargetExt()
802803
Assert.Empty(result.LoggedEvents.OfType<BuildWarningEventArgs>());
803804
}
804805

806+
/// <summary>
807+
/// Create a native resource .dll and verify that its version
808+
/// information is set correctly.
809+
/// </summary>
810+
[Fact]
811+
public async Task NativeVersionInfo_CreateNativeResourceDll()
812+
{
813+
this.testProject = this.CreateNativeProjectRootElement(this.projectDirectory, "test.vcxproj");
814+
this.WriteVersionFile();
815+
var result = await this.BuildAsync(Targets.Build, logVerbosity: LoggerVerbosity.Minimal);
816+
Assert.Empty(result.LoggedEvents.OfType<BuildErrorEventArgs>());
817+
818+
string targetFile = Path.Combine(this.projectDirectory, result.BuildResult.ProjectStateAfterBuild.GetPropertyValue("TargetPath"));
819+
Assert.True(File.Exists(targetFile));
820+
821+
var fileInfo = FileVersionInfo.GetVersionInfo(targetFile);
822+
Assert.Equal("1.2", fileInfo.FileVersion);
823+
Assert.Equal("1.2.0", fileInfo.ProductVersion);
824+
Assert.Equal("test", fileInfo.InternalName);
825+
Assert.Equal("NerdBank", fileInfo.CompanyName);
826+
Assert.Equal($"Copyright (c) {DateTime.Now.Year}. All rights reserved.", fileInfo.LegalCopyright);
827+
}
828+
805829
private static Version GetExpectedAssemblyVersion(VersionOptions versionOptions, Version version)
806830
{
807831
// Function should be very similar to VersionOracle.GetAssemblyVersion()
@@ -952,6 +976,17 @@ where name.StartsWith(prefix, StringComparison.Ordinal)
952976
}
953977
}
954978

979+
private ProjectRootElement CreateNativeProjectRootElement(string projectDirectory, string projectName)
980+
{
981+
using (var reader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream($"{ThisAssembly.RootNamespace}.test.vcprj")))
982+
{
983+
var pre = ProjectRootElement.Create(reader, this.projectCollection);
984+
pre.FullPath = Path.Combine(projectDirectory, projectName);
985+
pre.AddImport(Path.Combine(this.RepoPath, GitVersioningTargetsFileName));
986+
return pre;
987+
}
988+
}
989+
955990
private ProjectRootElement CreateProjectRootElement(string projectDirectory, string projectName)
956991
{
957992
using (var reader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream($"{ThisAssembly.RootNamespace}.test.prj")))
@@ -994,18 +1029,25 @@ private static class CloudBuild
9941029
.Add("APPVEYOR_PULL_REQUEST_NUMBER", string.Empty)
9951030
// VSTS
9961031
.Add("SYSTEM_TEAMPROJECTID", string.Empty)
997-
.Add("BUILD_SOURCEBRANCH", string.Empty);
1032+
.Add("BUILD_SOURCEBRANCH", string.Empty)
1033+
// Teamcity
1034+
.Add("BUILD_VCS_NUMBER", string.Empty)
1035+
.Add("BUILD_GIT_BRANCH", string.Empty);
9981036
public static readonly ImmutableDictionary<string, string> VSTS = SuppressEnvironment
9991037
.SetItem("SYSTEM_TEAMPROJECTID", "1");
10001038
public static readonly ImmutableDictionary<string, string> AppVeyor = SuppressEnvironment
10011039
.SetItem("APPVEYOR", "True");
1040+
public static readonly ImmutableDictionary<string, string> Teamcity = SuppressEnvironment
1041+
.SetItem("BUILD_VCS_NUMBER", "1");
10021042
}
10031043

10041044
private static class Targets
10051045
{
1046+
internal const string Build = "Build";
10061047
internal const string GetBuildVersion = "GetBuildVersion";
10071048
internal const string GetNuGetPackageVersion = "GetNuGetPackageVersion";
10081049
internal const string GenerateAssemblyVersionInfo = "GenerateAssemblyVersionInfo";
1050+
internal const string GenerateNativeVersionInfo = "GenerateNativeVersionInfo";
10091051
}
10101052

10111053
private class BuildResults

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<EmbeddedResource Include="Keys\*.snk" />
1414
<EmbeddedResource Include="Keys\*.pfx" />
1515
<EmbeddedResource Include="..\NerdBank.GitVersioning\version.schema.json" Link="version.schema.json" />
16+
<EmbeddedResource Include="test.vcprj" />
1617
<EmbeddedResource Include="test.prj" />
1718
<EmbeddedResource Include="repos\submodules.7z" />
1819
</ItemGroup>

src/NerdBank.GitVersioning.Tests/VersionOracleTests.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.IO;
1+
using System;
2+
using System.IO;
23
using System.Linq;
34
using LibGit2Sharp;
45
using Nerdbank.GitVersioning;
@@ -15,6 +16,14 @@ public VersionOracleTests(ITestOutputHelper logger)
1516

1617
private string CommitIdShort => this.Repo.Head.Commits.First().Id.Sha.Substring(0, 10);
1718

19+
[Fact]
20+
public void NotRepo()
21+
{
22+
// Seems safe to assume the system directory is not a repository.
23+
var oracle = VersionOracle.Create(Environment.SystemDirectory);
24+
Assert.Equal(0, oracle.VersionHeight);
25+
}
26+
1827
[Fact(Skip = "Unstable test. See issue #125")]
1928
public void Submodule_RecognizedWithCorrectVersion()
2029
{
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<ItemGroup Label="ProjectConfigurations">
4+
<ProjectConfiguration Include="Debug|Win32">
5+
<Configuration>Debug</Configuration>
6+
<Platform>Win32</Platform>
7+
</ProjectConfiguration>
8+
<ProjectConfiguration Include="Release|Win32">
9+
<Configuration>Release</Configuration>
10+
<Platform>Win32</Platform>
11+
</ProjectConfiguration>
12+
<ProjectConfiguration Include="Debug|x64">
13+
<Configuration>Debug</Configuration>
14+
<Platform>x64</Platform>
15+
</ProjectConfiguration>
16+
<ProjectConfiguration Include="Release|x64">
17+
<Configuration>Release</Configuration>
18+
<Platform>x64</Platform>
19+
</ProjectConfiguration>
20+
</ItemGroup>
21+
<PropertyGroup Label="Globals">
22+
<VCProjectVersion>15.0</VCProjectVersion>
23+
<ProjectGuid>{8FD9B6E8-A6E4-42A3-8B5A-E6F7ADC826F5}</ProjectGuid>
24+
<RootNamespace>test</RootNamespace>
25+
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
26+
<ConfigurationType>DynamicLibrary</ConfigurationType>
27+
<ResourceOnlyDll>true</ResourceOnlyDll>
28+
<AssemblyCompany>NerdBank</AssemblyCompany>
29+
</PropertyGroup>
30+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
31+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
32+
<UseDebugLibraries>true</UseDebugLibraries>
33+
<PlatformToolset>v140</PlatformToolset>
34+
<CharacterSet>MultiByte</CharacterSet>
35+
</PropertyGroup>
36+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
37+
<UseDebugLibraries>false</UseDebugLibraries>
38+
<PlatformToolset>v140</PlatformToolset>
39+
<WholeProgramOptimization>true</WholeProgramOptimization>
40+
<CharacterSet>MultiByte</CharacterSet>
41+
</PropertyGroup>
42+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
43+
<UseDebugLibraries>true</UseDebugLibraries>
44+
<PlatformToolset>v140</PlatformToolset>
45+
<CharacterSet>MultiByte</CharacterSet>
46+
</PropertyGroup>
47+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
48+
<UseDebugLibraries>false</UseDebugLibraries>
49+
<PlatformToolset>v140</PlatformToolset>
50+
<WholeProgramOptimization>true</WholeProgramOptimization>
51+
<CharacterSet>MultiByte</CharacterSet>
52+
</PropertyGroup>
53+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
54+
<ImportGroup Label="ExtensionSettings">
55+
</ImportGroup>
56+
<ImportGroup Label="Shared">
57+
</ImportGroup>
58+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
59+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
60+
</ImportGroup>
61+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
62+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
63+
</ImportGroup>
64+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
65+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
66+
</ImportGroup>
67+
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
68+
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
69+
</ImportGroup>
70+
<PropertyGroup Label="UserMacros" />
71+
<PropertyGroup />
72+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
73+
<ClCompile>
74+
<WarningLevel>Level3</WarningLevel>
75+
<Optimization>Disabled</Optimization>
76+
<SDLCheck>true</SDLCheck>
77+
</ClCompile>
78+
<Link>
79+
<NoEntryPoint>$(ResourceOnlyDll)</NoEntryPoint>
80+
</Link>
81+
</ItemDefinitionGroup>
82+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
83+
<ClCompile>
84+
<WarningLevel>Level3</WarningLevel>
85+
<Optimization>Disabled</Optimization>
86+
<SDLCheck>true</SDLCheck>
87+
</ClCompile>
88+
<Link>
89+
<NoEntryPoint>$(ResourceOnlyDll)</NoEntryPoint>
90+
</Link>
91+
</ItemDefinitionGroup>
92+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
93+
<ClCompile>
94+
<WarningLevel>Level3</WarningLevel>
95+
<Optimization>MaxSpeed</Optimization>
96+
<FunctionLevelLinking>true</FunctionLevelLinking>
97+
<IntrinsicFunctions>true</IntrinsicFunctions>
98+
<SDLCheck>true</SDLCheck>
99+
</ClCompile>
100+
<Link>
101+
<EnableCOMDATFolding>true</EnableCOMDATFolding>
102+
<OptimizeReferences>true</OptimizeReferences>
103+
<NoEntryPoint>$(ResourceOnlyDll)</NoEntryPoint>
104+
</Link>
105+
</ItemDefinitionGroup>
106+
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
107+
<ClCompile>
108+
<WarningLevel>Level3</WarningLevel>
109+
<Optimization>MaxSpeed</Optimization>
110+
<FunctionLevelLinking>true</FunctionLevelLinking>
111+
<IntrinsicFunctions>true</IntrinsicFunctions>
112+
<SDLCheck>true</SDLCheck>
113+
</ClCompile>
114+
<Link>
115+
<EnableCOMDATFolding>true</EnableCOMDATFolding>
116+
<OptimizeReferences>true</OptimizeReferences>
117+
<NoEntryPoint>$(ResourceOnlyDll)</NoEntryPoint>
118+
</Link>
119+
</ItemDefinitionGroup>
120+
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
121+
<ImportGroup Label="ExtensionTargets">
122+
</ImportGroup>
123+
</Project>

src/NerdBank.GitVersioning/CloudBuild.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public static class CloudBuild
1717
new VisualStudioTeamServices(),
1818
new TeamCity(),
1919
new AtlassianBamboo(),
20+
new Jenkins(),
2021
};
2122

2223
/// <summary>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
namespace Nerdbank.GitVersioning.CloudBuildServices
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using System.Text;
7+
8+
/// <remarks>
9+
/// The Jenkins-specific properties referenced here are documented here:
10+
/// https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin#GitPlugin-Environmentvariables
11+
/// </remarks>
12+
internal class Jenkins : ICloudBuild
13+
{
14+
private static readonly Encoding UTF8NoBOM = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
15+
16+
public string BuildingTag => null;
17+
18+
public bool IsPullRequest => false;
19+
20+
public string BuildingBranch => CloudBuild.ShouldStartWith(Branch, "refs/heads/");
21+
22+
public string GitCommitId => Environment.GetEnvironmentVariable("GIT_COMMIT");
23+
24+
public bool IsApplicable => !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("JENKINS_URL"));
25+
26+
private static string Branch =>
27+
Environment.GetEnvironmentVariable("GIT_LOCAL_BRANCH")
28+
?? Environment.GetEnvironmentVariable("GIT_BRANCH");
29+
30+
public IReadOnlyDictionary<string, string> SetCloudBuildNumber(string buildNumber, TextWriter stdout, TextWriter stderr)
31+
{
32+
WriteVersionFile(buildNumber);
33+
34+
stdout.WriteLine($"## GIT_VERSION: {buildNumber}");
35+
36+
return new Dictionary<string, string>
37+
{
38+
{ "GIT_VERSION", buildNumber }
39+
};
40+
}
41+
42+
public IReadOnlyDictionary<string, string> SetCloudBuildVariable(string name, string value, TextWriter stdout, TextWriter stderr)
43+
{
44+
return new Dictionary<string, string>
45+
{
46+
{ name, value }
47+
};
48+
}
49+
50+
private static void WriteVersionFile(string buildNumber)
51+
{
52+
var workspacePath = Environment.GetEnvironmentVariable("WORKSPACE");
53+
54+
if (string.IsNullOrEmpty(workspacePath))
55+
{
56+
return;
57+
}
58+
59+
var versionFilePath = Path.Combine(workspacePath, "jenkins_build_number.txt");
60+
61+
File.WriteAllText(versionFilePath, buildNumber, UTF8NoBOM);
62+
}
63+
}
64+
}

src/NerdBank.GitVersioning/CloudBuildServices/TeamCity.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,16 @@
44
using System.Collections.Generic;
55
using System.IO;
66

7+
/// <summary>
8+
/// TeamCity CI build support.
9+
/// </summary>
10+
/// <remarks>
11+
/// The TeamCIty-specific properties referenced here are documented here:
12+
/// https://confluence.jetbrains.com/display/TCD8/Predefined+Build+Parameters
13+
/// </remarks>
714
internal class TeamCity : ICloudBuild
815
{
9-
public string BuildingBranch => null;
16+
public string BuildingBranch => CloudBuild.ShouldStartWith(Environment.GetEnvironmentVariable("BUILD_GIT_BRANCH"), "refs/heads/");
1017

1118
public string BuildingTag => null;
1219

@@ -18,11 +25,15 @@ internal class TeamCity : ICloudBuild
1825

1926
public IReadOnlyDictionary<string, string> SetCloudBuildNumber(string buildNumber, TextWriter stdout, TextWriter stderr)
2027
{
28+
(stdout ?? Console.Out).WriteLine($"##teamcity[buildNumber '{buildNumber}']");
2129
return new Dictionary<string, string>();
2230
}
2331

2432
public IReadOnlyDictionary<string, string> SetCloudBuildVariable(string name, string value, TextWriter stdout, TextWriter stderr)
2533
{
34+
(stdout ?? Console.Out).WriteLine($"##teamcity[setParameter name='{name}' value='{value}']");
35+
(stdout ?? Console.Out).WriteLine($"##teamcity[setParameter name='system.{name}' value='{value}']");
36+
2637
return new Dictionary<string, string>();
2738
}
2839
}

0 commit comments

Comments
 (0)