Skip to content

Commit

Permalink
Support DotNetBuildPass property in Arcade's Build.proj
Browse files Browse the repository at this point in the history
1. Support DotNetBuildPass property
   Only build ProjectToBuild items with DotNetBuildPass
   metadata matching the passed-in value of DotNetBuildPass
   Don't glob for solution files in that build mode.
   Don't invoke the Execute target when nothing should be built.
2. Add SkipProjectToBuildError property to not
   error out when ProjectToBuild items are empty.
   This makes clean-up in source-build's outer build
   infrastructure possible (i.e. removal of Noop.proj)
3. Simplify Publish.proj Exec conditions in Build.proj
4. Add the DotNetBuildPass metadata to the asset manifest
   name when set. Also respect TargetArchitecture and
   TargetOS in the manifest name over Platform and OS.
5. Allow repos to invoke Arcade's Build.proj with the
   `-restore -sign -publish` actions only. For that to
   work, skip the ProjectToBuild empty error check when
   none of the build actions are passed in.
  • Loading branch information
ViktorHofer committed Mar 27, 2024
1 parent cd27fcf commit 1b58721
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 77 deletions.
77 changes: 39 additions & 38 deletions src/Microsoft.DotNet.Arcade.Sdk/tools/Build.proj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
Optional parameters:
Configuration Build configuration: "Debug", "Release", etc.
DotNetBuildPass The build pass number. Set to a number other than '1' when performing a join build.
This makes ProjectToBuild items only be built when the `DotNetBuildPass` metadata matches.
DotNetBuildRepo Build the repo as part of the entire .NET stack.
DotNetBuildInnerRepo Build the repo as part of the entire .NET stack. This switch is used on the inner repo invocation and should not be passed by the user.
DotNetBuildOrchestrator Build the entire .NET stack.
Expand Down Expand Up @@ -58,27 +60,35 @@
<Import Project="$(RepositoryEngineeringDir)Build.props" Condition="Exists('$(RepositoryEngineeringDir)Build.props')" />

<PropertyGroup>
<_ProjectsPropertyWasUpdatedInBuildProps Condition="'$(_OriginalProjectsValue)' != '$(Projects)'">true</_ProjectsPropertyWasUpdatedInBuildProps>
<_DotNetBuildPassSet Condition="'$(DotNetBuildPass)' != '' and '$(DotNetBuildPass)' != '1'">true</_DotNetBuildPassSet>
</PropertyGroup>

<ItemGroup Condition="'$(Projects)' != ''">
<!-- Copy the original list so we can log diagnostics later. -->
<_OriginalProjectToBuild Include="@(ProjectToBuild)" />
<!-- Setting 'Projects' overrides the ProjectToBuild list. -->
<ProjectToBuild Remove="@(ProjectToBuild)" />
<ProjectToBuild Include="$(Projects)" />
</ItemGroup>

<!--
Default values.
-->
<!-- If Projects is unspecified and ProjectToBuild was not set via Build.props, fallback to building .sln files in the repo root. -->
<ItemGroup Condition="'@(ProjectToBuild)' == ''">
<ProjectToBuild Include="$(RepoRoot)*.sln" />
<!-- Don't glob and build solution files from the repo root by default when DotNetBuildPass is set to a value other than 1. -->
<EnableDefaultSolutionItems Condition="'$(EnableDefaultSolutionItems)' == '' and '$(_DotNetBuildPassSet)' == 'true'">false</EnableDefaultSolutionItems>
<EnableDefaultSolutionItems Condition="'$(EnableDefaultSolutionItems)' == ''">true</EnableDefaultSolutionItems>
<ProjectToBuild Include="$(RepoRoot)*.sln" Condition="'$(EnableDefaultSolutionItems)' == 'true'" />
</ItemGroup>

<Target Name="Execute">
<Error Text="No projects were found to build. Either the 'Projects' property or 'ProjectToBuild' item group must be specified." Condition="'@(ProjectToBuild)' == ''"/>
<!-- Only build the projects for the passed in build pass numer in when DotNetBuildPass is set to a value other than 1. -->
<ItemGroup Condition="'@(ProjectToBuild)' != '' and '$(_DotNetBuildPassSet)' == 'true'">
<_ProjectToBuildKeep Include="@(ProjectToBuild->WithMetadataValue('DotNetBuildPass', '$(DotNetBuildPass)'))" />
<_ProjectToBuildRemove Include="@(ProjectToBuild)" Exclude="@(_ProjectToBuildKeep)" />
<ProjectToBuild Remove="@(_ProjectToBuildRemove)" />
</ItemGroup>

<!-- Skip execution when DotNetBuildPass is set and ProjectToBuild is empty.
This can happen whenever a repository gets built as part of a VMR join vertical but already built
all components in the non-join build. -->
<Target Name="Execute"
Condition="'$(_DotNetBuildPassSet)' != 'true' or '@(ProjectToBuild)' != ''">
<Error Text="Property 'RepoRoot' must be specified" Condition="'$(RepoRoot)' == ''"/>
<Error Text="File 'global.json' must exist in directory specified by RepoRoot: '$(RepoRoot)'" Condition="'$(RepoRoot)' != '' and !Exists('$(RepoRoot)global.json')"/>

Expand Down Expand Up @@ -110,6 +120,9 @@
<_SolutionBuildTargets Include="PerformanceTest" Condition="'$(PerformanceTest)' == 'true'" />
</ItemGroup>

<Error Text="No projects were found to build. Either the 'Projects' property or 'ProjectToBuild' item group must be specified."
Condition="'@(ProjectToBuild)' == '' and '@(_SolutionBuildTargets)' != '' and '$(SkipProjectToBuildError)' != 'true'"/>

<PropertyGroup>
<_RemoveProps>Projects;Restore;Deploy;Sign;Publish;NETCORE_ENGINEERING_TELEMETRY;@(_SolutionBuildTargets)</_RemoveProps>
</PropertyGroup>
Expand Down Expand Up @@ -177,9 +190,7 @@
<_SolutionBuildProps Include="__ImportPackTargets=true" Condition="'$(Pack)' == 'true'" />
</ItemGroup>

<!--
Restore built-in tools.
-->
<!-- Restore built-in tools -->
<MSBuild Projects="Tools.proj"
Targets="Restore"
Properties="@(_RestoreToolsProps);_NETCORE_ENGINEERING_TELEMETRY=Restore"
Expand Down Expand Up @@ -226,7 +237,7 @@
Targets="_IsProjectRestoreSupported"
SkipNonexistentTargets="true"
BuildInParallel="true"
Condition="'$(RestoreUsingNuGetTargets)' != 'false' and '%(ProjectToBuild.Extension)' != '.sln' and '%(ProjectToBuild.Extension)' != '.slnf' and '$(RestoreUseStaticGraphEvaluation)' != 'true' and '$(Restore)' == 'true'">
Condition="'$(RestoreUsingNuGetTargets)' != 'false' and '@(ProjectToBuild)' != '' and '%(ProjectToBuild.Extension)' != '.sln' and '%(ProjectToBuild.Extension)' != '.slnf' and '$(RestoreUseStaticGraphEvaluation)' != 'true' and '$(Restore)' == 'true'">

<Output TaskParameter="TargetOutputs" ItemName="_ProjectToRestoreWithNuGet" />
</MSBuild>
Expand Down Expand Up @@ -259,26 +270,22 @@
Targets="Restore"
SkipNonexistentTargets="true"
BuildInParallel="%(_ProjectToRestore.RestoreInParallel)"
Condition="'$(Restore)' == 'true'"/>
Condition="'$(Restore)' == 'true' and '@(_ProjectToRestore)' != ''" />

<!--
Build solution.
-->
<!-- Build ProjectToBuild items -->
<MSBuild Projects="@(ProjectToBuild)"
Properties="@(_SolutionBuildProps);__BuildPhase=SolutionBuild;_NETCORE_ENGINEERING_TELEMETRY=Build"
RemoveProperties="$(_RemoveProps)"
Targets="@(_SolutionBuildTargets)"
BuildInParallel="%(ProjectToBuild.BuildInParallel)"
Condition="'@(_SolutionBuildTargets)' != ''" />
Condition="'@(_SolutionBuildTargets)' != '' and '@(ProjectToBuild)' != ''" />

<MSBuild Projects="AfterSolutionBuild.proj"
Properties="@(_CommonProps);_NETCORE_ENGINEERING_TELEMETRY=Build"
Targets="@(_SolutionBuildTargets)"
Condition="'@(_SolutionBuildTargets)' != ''" />

<!--
Sign artifacts.
-->
<!-- Sign artifacts -->
<MSBuild Projects="Sign.proj"
Properties="@(_CommonProps)"
Targets="Sign"
Expand All @@ -297,30 +304,24 @@
Properties="@(_CommonProps);_NETCORE_ENGINEERING_TELEMETRY=AfterSourceBuild"
Condition="'$(ArcadeBuildFromSource)' == 'true' or '$(DotNetBuildRepo)' == 'true'"/>

<!--
Publish artifacts. This should run in the following situations:
- Regular single repo builds
- When running in the outer build phase of a source-only repo build, to properly publish the source-build intermediate nupkg.
- VMR builds
- When running in the inner build phase
It shouldn't run:
- In an inner build if running from single repo build.
- In an outer build if running from the full product build.
-->

<PropertyGroup>
<PropertyGroup Condition="'$(Publish)' == 'true'">
<_VmrBuild Condition="'$(DotNetBuildFromSourceFlavor)' == 'Product' or '$(DotNetBuildOrchestrator)' == 'true'">true</_VmrBuild>

<_OuterRepoBuild Condition="'$(ArcadeInnerBuildFromSource)' != 'true' and '$(DotNetBuildPhase)' != 'InnerRepo'">true</_OuterRepoBuild>
<_InnerRepoBuild Condition="'$(ArcadeInnerBuildFromSource)' == 'true' or '$(DotNetBuildPhase)' == 'InnerRepo'">true</_InnerRepoBuild>
<_ShouldRunPublish Condition="'$(_InnerRepoBuild)' == 'true' and '$(_VmrBuild)' == 'true'">true</_ShouldRunPublish>
<_ShouldRunPublish Condition="'$(_InnerRepoBuild)' != 'true' and '$(_VmrBuild)' != 'true'">true</_ShouldRunPublish>

<!-- Don't publish inside the VMR in the outer repo build. -->
<_ShouldRunPublish Condition="'$(_VmrBuild)' == 'true' and '$(_OuterRepoBuild)' == 'true'">false</_ShouldRunPublish>
<!-- Don't publish outside of the VRM in an inner build (source-only). -->
<_ShouldRunPublish Condition="'$(_VmrBuild)' != 'true' and '$(_InnerRepoBuild)' == 'true'">false</_ShouldRunPublish>
<!-- Otherwise, publish -->
<_ShouldRunPublish Condition="'$(_ShouldRunPublish)' == ''">true</_ShouldRunPublish>
</PropertyGroup>

<!-- Make sure we always publish in VMR build - working around runtime repo which sets Publish to false. -->
<MSBuild Projects="Publish.proj"
Properties="@(_PublishProps);_NETCORE_ENGINEERING_TELEMETRY=Publish"
Targets="Publish"
Condition="'$(Publish)' == 'true' and '$(_ShouldRunPublish)' == 'true'"/>
Condition="'$(_ShouldRunPublish)' == 'true'"/>
</Target>

</Project>
19 changes: 14 additions & 5 deletions src/Microsoft.DotNet.Arcade.Sdk/tools/Publish.proj
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@
('$(DotNetBuildSourceOnly)' != 'true' or
('$(ArcadeInnerBuildFromSource)' == 'true' and '$(DotNetBuildFromSourceFlavor)' != 'Product'))">true</AutoGenerateSymbolPackages>

<AssetManifestOS Condition="'$(AssetManifestOS)' == ''">$(OS)</AssetManifestOS>

<AssetManifestFileName>$(AssetManifestOS)-$(PlatformName).xml</AssetManifestFileName>
<AssetManifestFilePath>$(ArtifactsLogDir)AssetManifest\$(AssetManifestFileName)</AssetManifestFilePath>

<SymbolPackagesDir>$(ArtifactsTmpDir)SymbolPackages\</SymbolPackagesDir>

<PublishDependsOnTargets Condition="$(PublishToSymbolServer)">$(PublishDependsOnTargets);PublishSymbols</PublishDependsOnTargets>
Expand All @@ -78,6 +73,20 @@
<PublishDependsOnTargets>BeforePublish;$(PublishDependsOnTargets)</PublishDependsOnTargets>
</PropertyGroup>

<PropertyGroup>
<!-- Prefer TargetOS when set over OS -->
<AssetManifestOS Condition="'$(AssetManifestOS)' == ''">$([MSBuild]::ValueOrDefault('$(TargetOS)', '$(OS)'))</AssetManifestOS>

<!-- Prefer TargetArchitecture when set over PlatformName -->
<AssetManifestFileName>$(AssetManifestOS)-$([MSBuild]::ValueOrDefault('$(TargetArchitecture)', '$(PlatformName)'))</AssetManifestFileName>

<!-- Join build when DotNetBuildPass is set to a value other than 1. Add a marker to the asset manifest file name. -->
<AssetManifestFileName Condition="'$(DotNetBuildPass)' != '' and '$(DotNetBuildPass)' != '1'">$(AssetManifestFileName)-Pass$(DotNetBuildPass)</AssetManifestFileName>

<AssetManifestFileName>$(AssetManifestFileName).xml</AssetManifestFileName>
<AssetManifestFilePath>$(ArtifactsLogDir)AssetManifest\$(AssetManifestFileName)</AssetManifestFilePath>
</PropertyGroup>

<Import Project="$(NuGetPackageRoot)microsoft.dotnet.build.tasks.feed\$(MicrosoftDotNetBuildTasksFeedVersion)\build\Microsoft.DotNet.Build.Tasks.Feed.targets"/>
<Import Project="$(NuGetPackageRoot)microsoft.symboluploader.build.task\$(MicrosoftSymbolUploaderBuildTaskVersion)\build\PublishSymbols.targets" Condition="$(PublishToSymbolServer)"/>

Expand Down
14 changes: 0 additions & 14 deletions src/Microsoft.DotNet.Arcade.Sdk/tools/SourceBuild/Noop.proj

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ call an inner build after some setup. The targets work roughly like this:
* Create intermediate nupkg that contains the inner source-build's artifacts.
* MSBuild `Projects=SourceBuildIntermediate.proj Targets=Restore;Pack`
* Empty out the list of `ProjectToBuild`, because we already built them from source.
* Put `Noop.proj` in the list as a sentinel value.
* During **Outer Execute**:
* MSBuild `Projects=Tools.proj Targets=Restore`
* Does nothing interesting.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,21 @@

<_DirSeparatorEscapedCharForExecArg Condition="'$(OS)' == 'Windows_NT'">\</_DirSeparatorEscapedCharForExecArg>
<_DirSeparatorEscapedCharForExecArg Condition="'$(OS)' != 'Windows_NT'" />

<RunInnerSourceBuildCommand Condition="('$(ArcadeBuildFromSource)' == 'true' and
'$(ArcadeInnerBuildFromSource)' != 'true')
or '$(DotNetBuildPhase)' == 'Repo'">true</RunInnerSourceBuildCommand>
<SkipProjectToBuildError Condition="'$(RunInnerSourceBuildCommand)' == 'true'">true</SkipProjectToBuildError>
</PropertyGroup>

<!-- Prevent projects from building in the outer build: they would use prebuilts. -->
<ItemGroup Condition="'$(RunInnerSourceBuildCommand)' == 'true'">
<ProjectToBuild Remove="@(ProjectToBuild)" />
</ItemGroup>

<Target Name="ExecuteWithSourceBuiltTooling"
DependsOnTargets="
GetSourceBuildCommandConfiguration;
RunInnerSourceBuildCommand"
Condition="
('$(ArcadeBuildFromSource)' == 'true' and '$(ArcadeInnerBuildFromSource)' != 'true') or
'$(DotNetBuildPhase)' == 'Repo'"
DependsOnTargets="GetSourceBuildCommandConfiguration;RunInnerSourceBuildCommand"
Condition="'$(RunInnerSourceBuildCommand)' == 'true'"
BeforeTargets="Execute" />

<!--
Expand Down Expand Up @@ -114,9 +120,6 @@
<Target Name="RunInnerSourceBuildCommand"
DependsOnTargets="PrepareInnerSourceBuildRepoRoot">
<PropertyGroup>
<!-- Prevent any projects from building in the outside build: they would use prebuilts. -->
<PreventPrebuiltBuild>true</PreventPrebuiltBuild>

<!--
Normally, the inner build should run using the original build command with some extra args
appended. Allow the repo to override this default behavior if the repo is e.g. not onboarded
Expand All @@ -132,14 +135,4 @@
EnvironmentVariables="@(InnerBuildEnv)" />
</Target>

<Target Name="PreventPrebuiltBuild"
DependsOnTargets="ExecuteWithSourceBuiltTooling"
Condition="'$(PreventPrebuiltBuild)' == 'true'"
BeforeTargets="Execute">
<ItemGroup>
<ProjectToBuild Remove="@(ProjectToBuild)" />
<ProjectToBuild Include="$(MSBuildThisFileDirectory)Noop.proj" />
</ItemGroup>
</Target>

</Project>

0 comments on commit 1b58721

Please sign in to comment.