Skip to content

Commit 20d98e5

Browse files
xperiandriclaude
andcommitted
fix(build): restore the tools once per build instead of once per project
A solution restores its projects in parallel, so `ToolRestore` ran `dotnet tool restore` in every project at the same time and all of them touched the same marker file. The `Restore dependencies` step of the Copilot setup, which restores the solution, failed on Linux after `ToolRestore` started to run on every restore. Every project now delegates to one instance of `Directory.Build.targets`, which MSBuild builds once per build, so the tools are restored once and the other projects wait for that run. The Copilot setup no longer restores the tools on its own before restoring the solution. `Format` says why it runs Fantomas twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent d926785 commit 20d98e5

2 files changed

Lines changed: 15 additions & 5 deletions

File tree

‎.github/workflows/copilot-setup-steps.yml‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,5 @@ jobs:
3737
10.x
3838
3939
- name: Restore dependencies
40-
run: |
41-
dotnet tool restore
42-
dotnet restore FSharp.Collections.Immutable.slnx
40+
# Restoring the solution restores the local tools first (see Directory.Build.targets)
41+
run: dotnet restore FSharp.Collections.Immutable.slnx

‎Directory.Build.targets‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,18 @@ See https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-by-director
1111
<_DotnetFantomasOutputFile>$(BaseIntermediateOutputPath)dotnet-fantomas-msbuild-$(NETCoreSdkVersion)-$(OS)</_DotnetFantomasOutputFile>
1212
</PropertyGroup>
1313

14-
<!-- Make sure that dotnet tools are restored before restoring any project -->
15-
<Target Name="ToolRestore" BeforeTargets="Restore;CollectPackageReferences" Inputs="$(_DotnetToolManifestFile)" Outputs="$(_DotnetToolRestoreOutputFile)">
14+
<!--
15+
Make sure that dotnet tools are restored before restoring any project.
16+
A solution restores its projects in parallel, so restoring the tools in each of them ran `dotnet tool restore`
17+
concurrently and raced on the marker file.
18+
Every project therefore delegates to one instance of this file: MSBuild runs a target once per project instance,
19+
so the tools are restored once per build, and the projects that ask at the same time wait for that one run.
20+
-->
21+
<Target Name="ToolRestore" BeforeTargets="Restore;CollectPackageReferences">
22+
<MSBuild Projects="$(MSBuildThisFileFullPath)" Targets="ToolRestoreOnce" Properties="_DotnetToolRestoreOutputFile=$(_DotnetToolRestoreOutputFile)" RemoveProperties="TargetFramework;RuntimeIdentifier" />
23+
</Target>
24+
25+
<Target Name="ToolRestoreOnce" Inputs="$(_DotnetToolManifestFile)" Outputs="$(_DotnetToolRestoreOutputFile)">
1626
<Exec Command="dotnet tool restore" WorkingDirectory="$(MSBuildThisFileDirectory)" StandardOutputImportance="High" StandardErrorImportance="High" />
1727
<MakeDir Directories="$(_BuildProjBaseIntermediateOutputPath)"/>
1828
<Touch Files="$(_DotnetToolRestoreOutputFile)" AlwaysCreate="True" ForceTouch="True" />
@@ -51,6 +61,7 @@ See https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-by-director
5161
<MSBuild Projects="$(MSBuildProjectFullPath)" Targets="Format" Properties="_FantomasFormatInstance=true" RemoveProperties="TargetFramework;RuntimeIdentifier" />
5262
</Target>
5363

64+
<!-- Fantomas runs twice on purpose: one pass is not always idempotent, and the second one settles what the first moved -->
5465
<Target Name="Format" Inputs="@(Compile)" Outputs="$(_DotnetFantomasOutputFile)">
5566
<Exec Command="dotnet fantomas $(MSBuildProjectDirectory)" StandardOutputImportance="High" StandardErrorImportance="High" WorkingDirectory="$(MSBuildThisFileDirectory)" ContinueOnError="WarnAndContinue" />
5667
<Exec Command="dotnet fantomas $(MSBuildProjectDirectory)" StandardOutputImportance="High" StandardErrorImportance="High" WorkingDirectory="$(MSBuildThisFileDirectory)" ContinueOnError="WarnAndContinue" />

0 commit comments

Comments
 (0)