Skip to content

Commit

Permalink
Allow sharing version computation with a user-owned project
Browse files Browse the repository at this point in the history
Quickbuild requires that every P2P be to a git-controlled project. This makes it incompatible with NB.GV's running the MSBuild task to one of its own .targets files.
To workaround this, a quickbuild user will have to define their own project that does nothing but compute the version using NB.GV, and then set `NBGV_CachingProjectReference` to the full path to this custom project.

Note that no actual *caching* occurs at this stage when under quickbuild because quickbuild uses a new top-level msbuild call for every project. We'll need to combine this with caching version info to a file on disk for this to be a perf improvement in quickbuild.
  • Loading branch information
AArnott committed Oct 9, 2021
1 parent bc15604 commit f0e05d1
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 9 deletions.
55 changes: 55 additions & 0 deletions doc/quickbuild.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Microsoft's (internal) quickbuild

Nerdbank.GitVersioning supports the Microsoft-internal quickbuild/cloudbuild tool.

It works out of the box, but each project will recompute the version, which may accumulate to a significant increase in overall build time.

🚧 A future version of Nerdbank.GitVersioning will cache version information as a file so that the following instructions will be effective. 🚧

To calculate the version just once for an entire build, a few manual steps are required.

1. Create this project in your repo. The suggested location is `VersionGeneration/VersionGeneration.msbuildproj`.

```xml
<Project Sdk="Microsoft.Build.NoTargets">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
<SkipCopyBuildProduct>true</SkipCopyBuildProduct>
<NBGV_CacheMode>VersionGenerationTarget</NBGV_CacheMode>
</PropertyGroup>
</Project>
```

The `TargetFramework` property value is not important as no assemblies are built by this project,
but a value is nonetheless required for NuGet to be willing to consume the Nerdbank.GitVersioning package reference
(which is referenced in Directory.Build.props as described later).

1. Add the SDK version to your repo-root level `global.json` file, if it is not already present.
The [latest available version from nuget.org](https://www.nuget.org/packages/microsoft.build.notargets) is recommended.

```json
{
"msbuild-sdks": {
"Microsoft.Build.NoTargets": "3.1.0"
}
}
```

1. Modify your repo-root level `Directory.Build.props` file to contain these elements:

```xml
<PropertyGroup>
<!-- This entire repo has just one version.json file, so compute the version once and share with all projects in a large build. -->
<GitVersionBaseDirectory>$(MSBuildThisFileDirectory)</GitVersionBaseDirectory>
</PropertyGroup>

<PropertyGroup Condition=" '$(QBuild)' == '1' ">
<NBGV_CacheMode>MSBuildTargetCaching</NBGV_CacheMode>
<NBGV_CachingProjectReference>$(MSBuildThisFileDirectory)VersionGeneration\VersionGeneration.msbuildproj</NBGV_CachingProjectReference>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Nerdbank.GitVersioning" Version="3.5.*" PrivateAssets="all" />
</ItemGroup>
```
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<Compile Include="..\Shared\**\*.cs" LinkBase="Shared" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\Nerdbank.GitVersioning.Tasks\build\*.targets;..\Nerdbank.GitVersioning.Tasks\build\*.props">
<EmbeddedResource Include="..\Nerdbank.GitVersioning.Tasks\build\*.targets;..\Nerdbank.GitVersioning.Tasks\build\*.props;..\Nerdbank.GitVersioning.Tasks\build\*.proj">
<Visible>false</Visible>
<Link>Targets\%(FileName)%(Extension)</Link>
</EmbeddedResource>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ IMPORTANT: The 3.x release may produce a different version height than prior maj
<file src="build\MSBuildTargetCaching.targets" target="build\MSBuildTargetCaching.targets" />
<file src="build\Nerdbank.GitVersioning.Common.targets" target="build\Nerdbank.GitVersioning.Common.targets" />
<file src="build\Nerdbank.GitVersioning.Inner.targets" target="build\Nerdbank.GitVersioning.Inner.targets" />
<file src="build\Nerdbank.GitVersioning.Inner.Empty.targets" target="build\Nerdbank.GitVersioning.Inner.Empty.targets" />
<file src="build\Nerdbank.GitVersioning.props" target="build\Nerdbank.GitVersioning$LKGSuffix$.props" />
<file src="build\Nerdbank.GitVersioning.targets" target="build\Nerdbank.GitVersioning$LKGSuffix$.targets" />
<file src="build\PrivateP2PCaching.proj" target="build\PrivateP2PCaching.proj" />
<file src="buildCrossTargeting\Nerdbank.GitVersioning.targets" target="buildCrossTargeting\Nerdbank.GitVersioning$LKGSuffix$.targets" />
<file src="readme.txt" target="readme.txt" />
</files>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,30 @@
<NBGV_InnerGlobalProperties Condition=" '$(ProjectPathRelativeToGitRepoRoot)' != '' ">$(NBGV_InnerGlobalProperties)ProjectPathRelativeToGitRepoRoot=$(ProjectPathRelativeToGitRepoRoot);</NBGV_InnerGlobalProperties>
<NBGV_InnerGlobalProperties Condition=" '$(GitVersionBaseDirectory)' != '' ">$(NBGV_InnerGlobalProperties)GitVersionBaseDirectory=$(GitVersionBaseDirectory);</NBGV_InnerGlobalProperties>
<NBGV_InnerGlobalProperties Condition=" '$(OverrideBuildNumberOffset)' != '' ">$(NBGV_InnerGlobalProperties)OverrideBuildNumberOffset=$(OverrideBuildNumberOffset);</NBGV_InnerGlobalProperties>
<NBGV_InnerGlobalProperties Condition=" '$(NBGV_CacheMode)' != '' ">$(NBGV_InnerGlobalProperties)NBGV_CacheMode=$(NBGV_CacheMode);</NBGV_InnerGlobalProperties>
</PropertyGroup>

<!-- Compile a list of global properties that may vary when a project builds but that would never influence the result of the GetBuildVersion task. -->
<ItemGroup>
<NBGV_GlobalPropertiesToRemove Include="TargetFramework" />
<NBGV_GlobalPropertiesToRemove Include="RuntimeIdentifier" />
<NBGV_GlobalPropertiesToRemove Include="Configuration" />
<NBGV_GlobalPropertiesToRemove Include="Platform" />

<_BuildMetadataSnapped Include="@(BuildMetadata)" />
</ItemGroup>

<!-- We generally prefer to clear config|platform properties because they do not impact the version.
But quickbuild doesn't like a p2p that removes these, so set them to defensible constant values in that situation. -->
<PropertyGroup Condition=" '$(QBuild)' == '1' ">
<NBGV_InnerGlobalProperties>$(NBGV_InnerGlobalProperties)Configuration=Release;</NBGV_InnerGlobalProperties>
<NBGV_InnerGlobalProperties>$(NBGV_InnerGlobalProperties)Platform=AnyCPU;</NBGV_InnerGlobalProperties>
</PropertyGroup>
<ItemGroup Condition=" '$(QBuild)' != '1' ">
<NBGV_GlobalPropertiesToRemove Include="Configuration" />
<NBGV_GlobalPropertiesToRemove Include="Platform" />
</ItemGroup>

<ItemGroup>
<!-- Declare a P2P so that "msbuild -graph -isolate" doesn't complain when we use the MSBuild task to invoke our inner shared project. -->
<ProjectReference Include="$(MSBuildThisFileDirectory)Nerdbank.GitVersioning.Inner.targets">
<ProjectReference Include="$(NBGV_CachingProjectReference)">
<Targets>GetBuildVersion_Properties;GetBuildVersion_CloudBuildVersionVars</Targets>
<Properties>$(NBGV_InnerGlobalProperties)BuildMetadata=@(BuildMetadata, ',');</Properties>
<GlobalPropertiesToRemove>@(NBGV_GlobalPropertiesToRemove)</GlobalPropertiesToRemove>
Expand All @@ -32,6 +40,7 @@
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
<Visible>false</Visible>
<NBGV_InnerProject>true</NBGV_InnerProject>
<PrivateAssets>all</PrivateAssets>
</ProjectReference>
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,4 @@
<Message Importance="low" Text="NuGetPackageVersion: $(NuGetPackageVersion)" />
</Target>

<Import Project="Nerdbank.GitVersioning.Inner.Empty.targets" Condition=" '$(NBGV_CacheMode)' == 'MSBuildTargetCaching' " />

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,10 @@
-->
<NBGV_CacheMode Condition=" '$(NBGV_CacheMode)' == '' and '$(QBuild)' == '1' ">None</NBGV_CacheMode>
<NBGV_CacheMode Condition=" '$(NBGV_CacheMode)' == '' ">MSBuildTargetCaching</NBGV_CacheMode>

<!-- This property may be overridden in environments where all P2P references must be a project actually defined within the git repo directory.
Learn more at :/doc/quickbuild.md.
-->
<NBGV_CachingProjectReference Condition=" '$(NBGV_CachingProjectReference)' == '' ">$(MSBuildThisFileDirectory)PrivateP2PCaching.proj</NBGV_CachingProjectReference>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<!-- $(TargetExt) isn't set at evaluation time for us when built in wpftmp.csproj with manual imports -->
<!-- Suppress assembly version info generation if not obviously compiling an assembly. -->
<GenerateAssemblyVersionInfo Condition=" '$(GenerateAssemblyVersionInfo)' == '' and '$(TargetExt)' != '.dll' and '$(TargetExt)' != '.exe' ">false</GenerateAssemblyVersionInfo>
<GenerateAssemblyVersionInfo Condition=" '$(GenerateAssemblyVersionInfo)' == '' and '$(NBGV_CacheMode)' == 'VersionGenerationTarget' ">false</GenerateAssemblyVersionInfo>

<!-- Workaround the property stomping that msbuild does (see https://github.com/microsoft/msbuild/pull/4922) with manual imports. -->
<PrepareForBuildDependsOn>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<Import Project="Nerdbank.GitVersioning.Inner.targets" />

<!-- These targets are called by MSBuild static graph because we declare a ProjectReference item to this file. -->
<Target Name="GetTargetFrameworks" />
Expand Down

0 comments on commit f0e05d1

Please sign in to comment.