Skip to content

Commit a1d636e

Browse files
authored
Merge pull request #667 from dotnet/quickbuild2
Add property that can disable the private MSBuild task invocation
2 parents cb72788 + f0e05d1 commit a1d636e

12 files changed

+218
-67
lines changed

doc/quickbuild.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Microsoft's (internal) quickbuild
2+
3+
Nerdbank.GitVersioning supports the Microsoft-internal quickbuild/cloudbuild tool.
4+
5+
It works out of the box, but each project will recompute the version, which may accumulate to a significant increase in overall build time.
6+
7+
🚧 A future version of Nerdbank.GitVersioning will cache version information as a file so that the following instructions will be effective. 🚧
8+
9+
To calculate the version just once for an entire build, a few manual steps are required.
10+
11+
1. Create this project in your repo. The suggested location is `VersionGeneration/VersionGeneration.msbuildproj`.
12+
13+
```xml
14+
<Project Sdk="Microsoft.Build.NoTargets">
15+
<PropertyGroup>
16+
<TargetFramework>net5.0</TargetFramework>
17+
<IsPackable>false</IsPackable>
18+
<SkipCopyBuildProduct>true</SkipCopyBuildProduct>
19+
<NBGV_CacheMode>VersionGenerationTarget</NBGV_CacheMode>
20+
</PropertyGroup>
21+
</Project>
22+
```
23+
24+
The `TargetFramework` property value is not important as no assemblies are built by this project,
25+
but a value is nonetheless required for NuGet to be willing to consume the Nerdbank.GitVersioning package reference
26+
(which is referenced in Directory.Build.props as described later).
27+
28+
1. Add the SDK version to your repo-root level `global.json` file, if it is not already present.
29+
The [latest available version from nuget.org](https://www.nuget.org/packages/microsoft.build.notargets) is recommended.
30+
31+
```json
32+
{
33+
"msbuild-sdks": {
34+
"Microsoft.Build.NoTargets": "3.1.0"
35+
}
36+
}
37+
```
38+
39+
1. Modify your repo-root level `Directory.Build.props` file to contain these elements:
40+
41+
```xml
42+
<PropertyGroup>
43+
<!-- This entire repo has just one version.json file, so compute the version once and share with all projects in a large build. -->
44+
<GitVersionBaseDirectory>$(MSBuildThisFileDirectory)</GitVersionBaseDirectory>
45+
</PropertyGroup>
46+
47+
<PropertyGroup Condition=" '$(QBuild)' == '1' ">
48+
<NBGV_CacheMode>MSBuildTargetCaching</NBGV_CacheMode>
49+
<NBGV_CachingProjectReference>$(MSBuildThisFileDirectory)VersionGeneration\VersionGeneration.msbuildproj</NBGV_CachingProjectReference>
50+
</PropertyGroup>
51+
52+
<ItemGroup>
53+
<PackageReference Include="Nerdbank.GitVersioning" Version="3.5.*" PrivateAssets="all" />
54+
</ItemGroup>
55+
```

src/NerdBank.GitVersioning.Tests/BuildIntegrationTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,25 @@ protected override void ApplyGlobalProperties(IDictionary<string, string> global
3939
=> globalProperties["NBGV_GitEngine"] = "Managed";
4040
}
4141

42+
[Trait("Engine", "Managed")]
43+
[Collection("Build")] // msbuild sets current directory in the process, so we can't have it be concurrent with other build tests.
44+
public class BuildIntegrationInProjectManagedTests : BuildIntegrationTests
45+
{
46+
public BuildIntegrationInProjectManagedTests(ITestOutputHelper logger)
47+
: base(logger)
48+
{
49+
}
50+
51+
protected override GitContext CreateGitContext(string path, string committish = null)
52+
=> GitContext.Create(path, committish, writable: false);
53+
54+
protected override void ApplyGlobalProperties(IDictionary<string, string> globalProperties)
55+
{
56+
globalProperties["NBGV_GitEngine"] = "Managed";
57+
globalProperties["NBGV_CacheMode"] = "None";
58+
}
59+
}
60+
4261
[Trait("Engine", "LibGit2")]
4362
[Collection("Build")] // msbuild sets current directory in the process, so we can't have it be concurrent with other build tests.
4463
public class BuildIntegrationLibGit2Tests : BuildIntegrationTests
@@ -57,6 +76,7 @@ protected override void ApplyGlobalProperties(IDictionary<string, string> global
5776

5877
public abstract class BuildIntegrationTests : RepoTestBase, IClassFixture<MSBuildFixture>
5978
{
79+
private const string GitVersioningPropsFileName = "NerdBank.GitVersioning.props";
6080
private const string GitVersioningTargetsFileName = "NerdBank.GitVersioning.targets";
6181
private const string UnitTestCloudBuildPrefix = "UnitTest: ";
6282
private static readonly string[] ToxicEnvironmentVariablePrefixes = new string[]
@@ -1175,6 +1195,7 @@ private ProjectRootElement CreateNativeProjectRootElement(string projectDirector
11751195
{
11761196
var pre = ProjectRootElement.Create(reader, this.projectCollection);
11771197
pre.FullPath = Path.Combine(projectDirectory, projectName);
1198+
pre.InsertAfterChild(pre.CreateImportElement(Path.Combine(this.RepoPath, GitVersioningPropsFileName)), null);
11781199
pre.AddImport(Path.Combine(this.RepoPath, GitVersioningTargetsFileName));
11791200
return pre;
11801201
}
@@ -1186,6 +1207,7 @@ private ProjectRootElement CreateProjectRootElement(string projectDirectory, str
11861207
{
11871208
var pre = ProjectRootElement.Create(reader, this.projectCollection);
11881209
pre.FullPath = Path.Combine(projectDirectory, projectName);
1210+
pre.InsertAfterChild(pre.CreateImportElement(Path.Combine(this.RepoPath, GitVersioningPropsFileName)), null);
11891211
pre.AddImport(Path.Combine(this.RepoPath, GitVersioningTargetsFileName));
11901212
return pre;
11911213
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<Compile Include="..\Shared\**\*.cs" LinkBase="Shared" />
1313
</ItemGroup>
1414
<ItemGroup>
15-
<EmbeddedResource Include="..\Nerdbank.GitVersioning.Tasks\build\*.targets">
15+
<EmbeddedResource Include="..\Nerdbank.GitVersioning.Tasks\build\*.targets;..\Nerdbank.GitVersioning.Tasks\build\*.props;..\Nerdbank.GitVersioning.Tasks\build\*.proj">
1616
<Visible>false</Visible>
1717
<Link>Targets\%(FileName)%(Extension)</Link>
1818
</EmbeddedResource>

src/Nerdbank.GitVersioning.Tasks/Nerdbank.GitVersioning.nuspec

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,13 @@ IMPORTANT: The 3.x release may produce a different version height than prior maj
4848
<file src="$BaseOutputPath$netcoreapp3.1\System.Text.Json.dll" target="build\MSBuildCore\System.Text.Json.dll" />
4949
<file src="$BaseOutputPath$netcoreapp3.1\Validation.dll" target="build\MSBuildCore\Validation.dll" />
5050

51-
<file src="build\Nerdbank.GitVersioning.targets" target="build\Nerdbank.GitVersioning$LKGSuffix$.targets" />
51+
<file src="build\InProjectVersionComputation.targets" target="build\InProjectVersionComputation.targets" />
52+
<file src="build\MSBuildTargetCaching.targets" target="build\MSBuildTargetCaching.targets" />
5253
<file src="build\Nerdbank.GitVersioning.Common.targets" target="build\Nerdbank.GitVersioning.Common.targets" />
5354
<file src="build\Nerdbank.GitVersioning.Inner.targets" target="build\Nerdbank.GitVersioning.Inner.targets" />
55+
<file src="build\Nerdbank.GitVersioning.props" target="build\Nerdbank.GitVersioning$LKGSuffix$.props" />
56+
<file src="build\Nerdbank.GitVersioning.targets" target="build\Nerdbank.GitVersioning$LKGSuffix$.targets" />
57+
<file src="build\PrivateP2PCaching.proj" target="build\PrivateP2PCaching.proj" />
5458
<file src="buildCrossTargeting\Nerdbank.GitVersioning.targets" target="buildCrossTargeting\Nerdbank.GitVersioning$LKGSuffix$.targets" />
5559
<file src="readme.txt" target="readme.txt" />
5660
</files>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<Import Project="Nerdbank.GitVersioning.Inner.targets"/>
3+
4+
<Target Name="SetPropertiesForInvokeGetBuildVersionTask">
5+
<!-- Set properties required for InvokeGetBuildVersionTask here, because
6+
CallTarget invoked targets do not see properties set by the calling target. -->
7+
<PropertyGroup>
8+
<BuildMetadata>@(BuildMetadata, ',')</BuildMetadata>
9+
</PropertyGroup>
10+
</Target>
11+
12+
<Target Name="InvokeGetBuildVersionTask" DependsOnTargets="SetPropertiesForInvokeGetBuildVersionTask">
13+
<CallTarget Targets="GetBuildVersion_Properties">
14+
<Output TaskParameter="TargetOutputs" ItemName="NBGV_PropertyItems" />
15+
</CallTarget>
16+
<CallTarget Targets="GetBuildVersion_CloudBuildVersionVars">
17+
<Output TaskParameter="TargetOutputs" ItemName="CloudBuildVersionVars" />
18+
</CallTarget>
19+
</Target>
20+
</Project>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<PropertyGroup>
3+
<NBGV_InnerGlobalProperties Condition=" '$(GitRepoRoot)' != '' ">$(NBGV_InnerGlobalProperties)GitRepoRoot=$(GitRepoRoot);</NBGV_InnerGlobalProperties>
4+
<NBGV_InnerGlobalProperties Condition=" '$(PublicRelease)' != '' ">$(NBGV_InnerGlobalProperties)PublicRelease=$(PublicRelease);</NBGV_InnerGlobalProperties>
5+
<NBGV_InnerGlobalProperties Condition=" '$(_NBGV_BuildingRef)' != '' ">$(NBGV_InnerGlobalProperties)_NBGV_BuildingRef=$(_NBGV_BuildingRef);</NBGV_InnerGlobalProperties>
6+
<NBGV_InnerGlobalProperties Condition=" '$(ProjectPathRelativeToGitRepoRoot)' != '' ">$(NBGV_InnerGlobalProperties)ProjectPathRelativeToGitRepoRoot=$(ProjectPathRelativeToGitRepoRoot);</NBGV_InnerGlobalProperties>
7+
<NBGV_InnerGlobalProperties Condition=" '$(GitVersionBaseDirectory)' != '' ">$(NBGV_InnerGlobalProperties)GitVersionBaseDirectory=$(GitVersionBaseDirectory);</NBGV_InnerGlobalProperties>
8+
<NBGV_InnerGlobalProperties Condition=" '$(OverrideBuildNumberOffset)' != '' ">$(NBGV_InnerGlobalProperties)OverrideBuildNumberOffset=$(OverrideBuildNumberOffset);</NBGV_InnerGlobalProperties>
9+
</PropertyGroup>
10+
11+
<!-- Compile a list of global properties that may vary when a project builds but that would never influence the result of the GetBuildVersion task. -->
12+
<ItemGroup>
13+
<NBGV_GlobalPropertiesToRemove Include="TargetFramework" />
14+
<NBGV_GlobalPropertiesToRemove Include="RuntimeIdentifier" />
15+
16+
<_BuildMetadataSnapped Include="@(BuildMetadata)" />
17+
</ItemGroup>
18+
19+
<!-- We generally prefer to clear config|platform properties because they do not impact the version.
20+
But quickbuild doesn't like a p2p that removes these, so set them to defensible constant values in that situation. -->
21+
<PropertyGroup Condition=" '$(QBuild)' == '1' ">
22+
<NBGV_InnerGlobalProperties>$(NBGV_InnerGlobalProperties)Configuration=Release;</NBGV_InnerGlobalProperties>
23+
<NBGV_InnerGlobalProperties>$(NBGV_InnerGlobalProperties)Platform=AnyCPU;</NBGV_InnerGlobalProperties>
24+
</PropertyGroup>
25+
<ItemGroup Condition=" '$(QBuild)' != '1' ">
26+
<NBGV_GlobalPropertiesToRemove Include="Configuration" />
27+
<NBGV_GlobalPropertiesToRemove Include="Platform" />
28+
</ItemGroup>
29+
30+
<ItemGroup>
31+
<!-- Declare a P2P so that "msbuild -graph -isolate" doesn't complain when we use the MSBuild task to invoke our inner shared project. -->
32+
<ProjectReference Include="$(NBGV_CachingProjectReference)">
33+
<Targets>GetBuildVersion_Properties;GetBuildVersion_CloudBuildVersionVars</Targets>
34+
<Properties>$(NBGV_InnerGlobalProperties)BuildMetadata=@(BuildMetadata, ',');</Properties>
35+
<GlobalPropertiesToRemove>@(NBGV_GlobalPropertiesToRemove)</GlobalPropertiesToRemove>
36+
37+
<!-- Do our very best to prevent Microsoft.Common.CurrentVersion.targets or IDEs from processing this P2P. It's only here for MSBuild's static graph. -->
38+
<BuildReference>false</BuildReference>
39+
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
40+
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
41+
<Visible>false</Visible>
42+
<NBGV_InnerProject>true</NBGV_InnerProject>
43+
<PrivateAssets>all</PrivateAssets>
44+
</ProjectReference>
45+
</ItemGroup>
46+
47+
<Target Name="InvokeGetBuildVersionTask">
48+
<Error Text="BuildMetadata items changed after a copy was made. Add all BuildMetadata items before importing this file." Condition=" '@(BuildMetadata)' != '@(_BuildMetadataSnapped)' " />
49+
50+
<!-- Calculate version by invoking another "project" with global properties that will serve as a key
51+
into an msbuild cache to ensure we only invoke the GetBuildVersion task as many times as will produce a unique value. -->
52+
<MSBuild Projects="@(ProjectReference)"
53+
Condition=" '%(ProjectReference.NBGV_InnerProject)' == 'true' "
54+
Properties="%(ProjectReference.Properties)"
55+
RemoveProperties="%(ProjectReference.GlobalPropertiesToRemove)"
56+
Targets="GetBuildVersion_Properties">
57+
<Output TaskParameter="TargetOutputs" ItemName="NBGV_PropertyItems" />
58+
</MSBuild>
59+
60+
<!-- Also get other items. -->
61+
<MSBuild Projects="@(ProjectReference)"
62+
Condition=" '%(ProjectReference.NBGV_InnerProject)' == 'true' "
63+
Properties="%(ProjectReference.Properties)"
64+
RemoveProperties="%(ProjectReference.GlobalPropertiesToRemove)"
65+
Targets="GetBuildVersion_CloudBuildVersionVars">
66+
<Output TaskParameter="TargetOutputs" ItemName="CloudBuildVersionVars" />
67+
</MSBuild>
68+
</Target>
69+
</Project>

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<PropertyGroup>
4+
<_NBGV_Common_Targets_Imported>true</_NBGV_Common_Targets_Imported>
45
<_NBGV_PlatformSuffix Condition=" '$(_NBGV_PlatformSuffix)' == '' and '$(MSBuildRuntimeType)' == 'Core' ">MSBuildCore/</_NBGV_PlatformSuffix>
56
<_NBGV_PlatformSuffix Condition=" '$(_NBGV_PlatformSuffix)' == '' ">MSBuildFull/</_NBGV_PlatformSuffix>
67
<NerdbankGitVersioningTasksPath Condition=" '$(NerdbankGitVersioningTasksPath)' == '' ">$(MSBuildThisFileDirectory)$(_NBGV_PlatformSuffix)</NerdbankGitVersioningTasksPath>

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

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33

4-
<Import Project="Nerdbank.GitVersioning.Common.targets"/>
4+
<Import Project="Nerdbank.GitVersioning.Common.targets" Condition=" '$(_NBGV_Common_Targets_Imported)' != 'true' "/>
55

66
<UsingTask AssemblyFile="$(NerdbankGitVersioningTasksPath)Nerdbank.GitVersioning.Tasks.dll" TaskName="Nerdbank.GitVersioning.Tasks.GetBuildVersion"/>
77

@@ -18,7 +18,7 @@
1818
BuildingRef="$(_NBGV_BuildingRef)"
1919
BuildMetadata="$(BuildMetadata.Replace(',',';'))"
2020
DefaultPublicRelease="$(PublicRelease)"
21-
ProjectDirectory="$(ProjectDirectory)"
21+
ProjectDirectory="$(GitVersionBaseDirectory)"
2222
GitRepoRoot="$(GitRepoRoot)"
2323
ProjectPathRelativeToGitRepoRoot="$(ProjectPathRelativeToGitRepoRoot)"
2424
OverrideBuildNumberOffset="$(OverrideBuildNumberOffset)"
@@ -42,11 +42,5 @@
4242
<Message Importance="low" Text="AssemblyInformationalVersion: $(AssemblyInformationalVersion)" />
4343
<Message Importance="low" Text="NuGetPackageVersion: $(NuGetPackageVersion)" />
4444
</Target>
45-
46-
<!-- These targets are called by MSBuild static graph because we declare a ProjectReference item to this file. -->
47-
<Target Name="GetTargetFrameworks" />
48-
<Target Name="GetNativeManifest" />
49-
<Target Name="GetCopyToOutputDirectoryItems" />
50-
<Target Name="GetTargetFrameworksWithPlatformForSingleTargetFramework" />
5145

5246
</Project>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<PropertyGroup>
3+
<!-- Cache modes include:
4+
MSBuildTargetCaching
5+
This is the default.
6+
Versions will be computed by an MSBuild target which can be shared across an entire build session via MSBuild target output caching.
7+
None
8+
Every project will compute its own version.
9+
10+
Note that the choice in caching should have no bearing on the result of the versions computed - only on build perf and which systems it can work with.
11+
-->
12+
<NBGV_CacheMode Condition=" '$(NBGV_CacheMode)' == '' and '$(QBuild)' == '1' ">None</NBGV_CacheMode>
13+
<NBGV_CacheMode Condition=" '$(NBGV_CacheMode)' == '' ">MSBuildTargetCaching</NBGV_CacheMode>
14+
15+
<!-- This property may be overridden in environments where all P2P references must be a project actually defined within the git repo directory.
16+
Learn more at :/doc/quickbuild.md.
17+
-->
18+
<NBGV_CachingProjectReference Condition=" '$(NBGV_CachingProjectReference)' == '' ">$(MSBuildThisFileDirectory)PrivateP2PCaching.proj</NBGV_CachingProjectReference>
19+
</PropertyGroup>
20+
</Project>

0 commit comments

Comments
 (0)