Skip to content

Commit 2dfd066

Browse files
authored
Merge pull request #1153 from dotnet/addPrereleaseIdentifiers
Add msbuild-provided prerelease identifiers
2 parents 6a6124a + 96122d1 commit 2dfd066

File tree

8 files changed

+175
-7
lines changed

8 files changed

+175
-7
lines changed

docfx/docs/build-systems/msbuild.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ Property | Default | Description
5151
`NBGV_ThisAssemblyIncludesPackageVersion` | `false` | When `true`, a `NuGetPackageVersion` property is added to the `ThisAssembly` class.
5252
`NBGV_UseAssemblyVersionInNativeVersion` | `true` | When `false`, uses the `AssemblyFileVersion` as a native `PRODUCTVERSION`.
5353

54+
### Items
55+
56+
The following MSBuild items may be declared in your project to customize the computed version:
57+
58+
Item type | Description
59+
--|--
60+
`BuildMetadata` | Adds `+ItemName` build metadata for each item to the computed version.
61+
`PrereleaseIdentifier` | Adds `-ItemName` build metadata for each item to the computed version.
62+
5463
### Custom `ThisAssembly` static fields and constants
5564

5665
Custom constants may be added to the `ThisAssembly` class through `AdditionalThisAssemblyFields` items defined in your project.

src/NerdBank.GitVersioning/VersionOracle.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,31 @@ public IEnumerable<string> BuildMetadataWithCommitId
208208
/// <summary>
209209
/// Gets the prerelease version information, including a leading hyphen.
210210
/// </summary>
211-
public string PrereleaseVersion => this.ReplaceMacros(this.VersionOptions?.Version?.Prerelease ?? string.Empty);
211+
/// <value>An empty string for a stable release, or a string like <c>-beta</c>.</value>
212+
public string PrereleaseVersion
213+
{
214+
get
215+
{
216+
string result = this.ReplaceMacros(this.VersionOptions?.Version?.Prerelease ?? string.Empty);
217+
218+
foreach (string identifier in this.ExtraPrereleaseIdentifiers)
219+
{
220+
if (result.Length == 0)
221+
{
222+
result = "-";
223+
}
224+
else
225+
{
226+
// In semver v2, identifiers should be separated by periods.
227+
result += this.VersionOptions?.NuGetPackageVersionOrDefault.SemVerOrDefault >= 2 ? '.' : '-';
228+
}
229+
230+
result += identifier;
231+
}
232+
233+
return result;
234+
}
235+
}
212236

213237
/// <summary>
214238
/// Gets the prerelease version information, omitting the leading hyphen, if any.
@@ -379,6 +403,12 @@ public IDictionary<string, string> CloudBuildVersionVars
379403
[Ignore]
380404
public List<string> BuildMetadata { get; } = new List<string>();
381405

406+
/// <summary>
407+
/// Gets a list of prerelease identifiers to add to whatever the default prerelease identifiers are.
408+
/// </summary>
409+
[Ignore]
410+
public List<string> ExtraPrereleaseIdentifiers { get; } = new List<string>();
411+
382412
/// <summary>
383413
/// Gets the +buildMetadata fragment for the semantic version.
384414
/// </summary>

src/Nerdbank.GitVersioning.Tasks/GetBuildVersion.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
// Copyright (c) .NET Foundation and Contributors. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4-
using System;
5-
using System.Collections.Generic;
64
using System.Globalization;
7-
using System.IO;
8-
using System.Linq;
9-
using System.Reflection;
105
using Microsoft.Build.Framework;
116
using Microsoft.Build.Utilities;
127
using MSBuildExtensionTask;
@@ -28,6 +23,11 @@ public GetBuildVersion()
2823
/// </summary>
2924
public string BuildMetadata { get; set; }
3025

26+
/// <summary>
27+
/// Gets or sets an array of prerelease identifiers to append to whatever else may be determined by default.
28+
/// </summary>
29+
public string PrereleaseIdentifiers { get; set; }
30+
3131
/// <summary>
3232
/// Gets or sets the value of the PublicRelease property in MSBuild at the
3333
/// start of this Task.
@@ -256,6 +256,11 @@ protected override bool ExecuteInner()
256256
oracle.BuildMetadata.AddRange(this.BuildMetadata.Split(';'));
257257
}
258258

259+
if (this.PrereleaseIdentifiers is { Length: > 0 })
260+
{
261+
oracle.ExtraPrereleaseIdentifiers.AddRange(this.PrereleaseIdentifiers.Split(';'));
262+
}
263+
259264
if (IsMisconfiguredPrereleaseAndSemVer1(oracle))
260265
{
261266
this.Log.LogWarning("The 'nugetPackageVersion' is explicitly set to 'semVer': 1 but the prerelease version '{0}' is not SemVer1 compliant. Change the 'nugetPackageVersion'.'semVer' value to 2 or change the 'version' member to follow SemVer1 rules (e.g.: '{1}').", oracle.PrereleaseVersion, GetSemVer1WithoutPaddingOrBuildMetadata(oracle));

src/Nerdbank.GitVersioning.Tasks/build/InProjectVersionComputation.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
CallTarget invoked targets do not see properties set by the calling target. -->
77
<PropertyGroup>
88
<BuildMetadata>@(BuildMetadata, ',')</BuildMetadata>
9+
<PrereleaseIdentifiers>@(PrereleaseIdentifier, ',')</PrereleaseIdentifiers>
910
</PropertyGroup>
1011
</Target>
1112

src/Nerdbank.GitVersioning.Tasks/build/MSBuildTargetCaching.targets

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616
<NBGV_GlobalPropertiesToRemove Include="RuntimeIdentifier" />
1717

1818
<_BuildMetadataSnapped Include="@(BuildMetadata)" />
19+
<_PrereleaseIdentifierSnapped Include="@(PrereleaseIdentifier)" />
1920
</ItemGroup>
2021

2122
<ItemGroup>
2223
<NBGV_CachingProjectReference Include="$(NBGV_CachingProjectReference)">
2324
<Targets>GetBuildVersion_Properties;GetBuildVersion_CloudBuildVersionVars</Targets>
24-
<Properties>$(NBGV_InnerGlobalProperties)BuildMetadata=@(BuildMetadata, ',');</Properties>
25+
<Properties>$(NBGV_InnerGlobalProperties)BuildMetadata=@(BuildMetadata, ',');PrereleaseIdentifiers=@(PrereleaseIdentifier, ',')</Properties>
2526
<SetConfiguration>Configuration=Release</SetConfiguration>
2627
<SetPlatform>Platform=AnyCPU</SetPlatform>
2728
<GlobalPropertiesToRemove>@(NBGV_GlobalPropertiesToRemove)</GlobalPropertiesToRemove>
@@ -44,6 +45,7 @@
4445

4546
<Target Name="InvokeGetBuildVersionTask">
4647
<Error Text="BuildMetadata items changed after a copy was made. Add all BuildMetadata items before importing this file." Condition=" '@(BuildMetadata)' != '@(_BuildMetadataSnapped)' " />
48+
<Error Text="PrereleaseIdentifier items changed after a copy was made. Add all PrereleaseIdentifier items before importing this file." Condition=" '@(PrereleaseIdentifier)' != '@(_PrereleaseIdentifierSnapped)' " />
4749

4850
<!-- Calculate version by invoking another "project" with global properties that will serve as a key
4951
into an msbuild cache to ensure we only invoke the GetBuildVersion task as many times as will produce a unique value. -->

src/Nerdbank.GitVersioning.Tasks/build/Nerdbank.GitVersioning.Inner.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<Nerdbank.GitVersioning.Tasks.GetBuildVersion
1818
BuildingRef="$(_NBGV_BuildingRef)"
1919
BuildMetadata="$(BuildMetadata.Replace(',',';'))"
20+
PrereleaseIdentifiers="$(PrereleaseIdentifiers.Replace(',',';'))"
2021
DefaultPublicRelease="$(PublicRelease)"
2122
ProjectDirectory="$(GitVersionBaseDirectory)"
2223
GitRepoRoot="$(GitRepoRoot)"

test/Nerdbank.GitVersioning.Tests/BuildIntegrationTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,21 @@ public async Task GetBuildVersion_Without_Git_HighPrecisionAssemblyVersion()
155155
Assert.Equal("3.4.0", buildResult.AssemblyInformationalVersion);
156156
}
157157

158+
[Fact]
159+
public async Task WithExtraPrereleaseIdentifiers()
160+
{
161+
this.WriteVersionFile(new VersionOptions
162+
{
163+
Version = SemanticVersion.Parse("3.4"),
164+
});
165+
this.InitializeSourceControl();
166+
this.testProject.AddItem("PrereleaseIdentifier", "i1");
167+
this.testProject.AddItem("PrereleaseIdentifier", "i2");
168+
this.globalProperties["PublicRelease"] = "true";
169+
BuildResults buildResult = await this.BuildAsync();
170+
Assert.Matches(@"^3\.4\.[01]-i1-i2$", buildResult.NuGetPackageVersion);
171+
}
172+
158173
// TODO: add key container test.
159174
[Theory]
160175
[InlineData("keypair.snk", false)]

test/Nerdbank.GitVersioning.Tests/VersionOracleTests.cs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,111 @@ public void SemVerStableNonPublicVersionShortened()
291291
Assert.Matches(@"^2.3.1-g[a-f0-9]{7}$", oracle.ChocolateyPackageVersion);
292292
}
293293

294+
[Fact]
295+
public void ExtraPrereleaseIdentifiers_StableBase_V1()
296+
{
297+
var workingCopyVersion = new VersionOptions
298+
{
299+
Version = SemanticVersion.Parse("2.3"),
300+
NuGetPackageVersion = new VersionOptions.NuGetPackageVersionOptions
301+
{
302+
SemVer = 1,
303+
},
304+
};
305+
this.WriteVersionFile(workingCopyVersion);
306+
this.InitializeSourceControl();
307+
VersionOracle oracle = new(this.Context)
308+
{
309+
ExtraPrereleaseIdentifiers = { "i1", "i2" },
310+
PublicRelease = true,
311+
};
312+
Assert.Equal(@"2.3.1-i1-i2", oracle.NuGetPackageVersion);
313+
}
314+
315+
[Fact]
316+
public void ExtraPrereleaseIdentifiers_StableBase_V2()
317+
{
318+
var workingCopyVersion = new VersionOptions
319+
{
320+
Version = SemanticVersion.Parse("2.3"),
321+
NuGetPackageVersion = new VersionOptions.NuGetPackageVersionOptions
322+
{
323+
SemVer = 2,
324+
},
325+
};
326+
this.WriteVersionFile(workingCopyVersion);
327+
this.InitializeSourceControl();
328+
VersionOracle oracle = new(this.Context)
329+
{
330+
ExtraPrereleaseIdentifiers = { "i1", "i2" },
331+
PublicRelease = true,
332+
};
333+
Assert.Equal(@"2.3.1-i1.i2", oracle.NuGetPackageVersion);
334+
}
335+
336+
[Fact]
337+
public void ExtraPrereleaseIdentifiers_StableBase_V2_NonPublic()
338+
{
339+
var workingCopyVersion = new VersionOptions
340+
{
341+
Version = SemanticVersion.Parse("2.3"),
342+
NuGetPackageVersion = new VersionOptions.NuGetPackageVersionOptions
343+
{
344+
SemVer = 2,
345+
},
346+
};
347+
this.WriteVersionFile(workingCopyVersion);
348+
this.InitializeSourceControl();
349+
VersionOracle oracle = new(this.Context)
350+
{
351+
ExtraPrereleaseIdentifiers = { "i1", "i2" },
352+
PublicRelease = false,
353+
};
354+
Assert.Matches(@"^2\.3\.1-i1\.i2\.g", oracle.NuGetPackageVersion);
355+
}
356+
357+
[Fact]
358+
public void ExtraPrereleaseIdentifiers_UnstableBase_V1()
359+
{
360+
var workingCopyVersion = new VersionOptions
361+
{
362+
Version = SemanticVersion.Parse("2.3-abc"),
363+
NuGetPackageVersion = new VersionOptions.NuGetPackageVersionOptions
364+
{
365+
SemVer = 1,
366+
},
367+
};
368+
this.WriteVersionFile(workingCopyVersion);
369+
this.InitializeSourceControl();
370+
VersionOracle oracle = new(this.Context)
371+
{
372+
ExtraPrereleaseIdentifiers = { "i1", "i2" },
373+
PublicRelease = true,
374+
};
375+
Assert.Equal(@"2.3.1-abc-i1-i2", oracle.NuGetPackageVersion);
376+
}
377+
378+
[Fact]
379+
public void ExtraPrereleaseIdentifiers_UnstableBase_V2()
380+
{
381+
var workingCopyVersion = new VersionOptions
382+
{
383+
Version = SemanticVersion.Parse("2.3-abc"),
384+
NuGetPackageVersion = new VersionOptions.NuGetPackageVersionOptions
385+
{
386+
SemVer = 2,
387+
},
388+
};
389+
this.WriteVersionFile(workingCopyVersion);
390+
this.InitializeSourceControl();
391+
VersionOracle oracle = new(this.Context)
392+
{
393+
ExtraPrereleaseIdentifiers = { "i1", "i2" },
394+
PublicRelease = true,
395+
};
396+
Assert.Equal(@"2.3.1-abc.i1.i2", oracle.NuGetPackageVersion);
397+
}
398+
294399
[Theory]
295400
[InlineData("1.2.0.0", null, null)]
296401
[InlineData("1.0.0.0", null, VersionOptions.VersionPrecision.Major)]

0 commit comments

Comments
 (0)