Add Microsoft.MSBuildCache (#17393)

Add Microsoft.MSBuildCache

This change adds a new pipeline which enables caching in the build. This
is added as a separate pipeline for now with the eventual goal of
enabling for PR and/or CI builds.

Documentation for Microsoft.MSBuildCache can be found in the GitHub
repo: https://github.com/microsoft/MSBuildCache

Preliminary numbers below.

*
[Baseline](https://dev.azure.com/ms/terminal/_build/results?buildId=579399&view=results):
12 min
* [0% Cache
hits](https://dev.azure.com/ms/terminal/_build/results?buildId=579419&view=results):
16 mins
* [100% cache
hits](https://dev.azure.com/ms/terminal/_build/results?buildId=579427&view=results):
3 mins
This commit is contained in:
David Federman
2024-06-20 14:02:26 -07:00
committed by GitHub
parent bd116e35b2
commit 613a539613
7 changed files with 139 additions and 20 deletions

View File

@@ -738,6 +738,7 @@ HABCDEF
Hackathon Hackathon
HALTCOND HALTCOND
HANGEUL HANGEUL
hardlinks
hashalg hashalg
HASSTRINGS HASSTRINGS
hbitmap hbitmap
@@ -1080,6 +1081,7 @@ MOUSEFIRST
MOUSEHWHEEL MOUSEHWHEEL
MOVESTART MOVESTART
msb msb
msbuildcache
msctf msctf
msctls msctls
msdata msdata
@@ -1489,6 +1491,7 @@ reparented
reparenting reparenting
replatformed replatformed
Replymessage Replymessage
reportfileaccesses
repositorypath repositorypath
Requiresx Requiresx
rerasterize rerasterize
@@ -2005,6 +2008,7 @@ wincontypes
WINCORE WINCORE
windbg windbg
WINDEF WINDEF
windir
windll windll
WINDOWALPHA WINDOWALPHA
windowdpiapi windowdpiapi

3
.gitignore vendored
View File

@@ -283,3 +283,6 @@ MSG*.bin
profiles.json profiles.json
*.metaproj *.metaproj
*.swp *.swp
# MSBuildCache
/MSBuildCacheLogs/

60
Directory.Build.props Normal file
View File

@@ -0,0 +1,60 @@
<Project>
<!--
NOTE! This file gets written-over entirely by the release builds.
Any build logic in this file must be optional and only apply to non-release builds.
-->
<!-- MsBuildCache -->
<PropertyGroup>
<!-- Off by default -->
<MsBuildCacheEnabled Condition="'$(MsBuildCacheEnabled)' == ''">false</MsBuildCacheEnabled>
<!-- Always off during package restore -->
<MsBuildCacheEnabled Condition=" '$(ExcludeRestorePackageImports)' == 'true' ">false</MsBuildCacheEnabled>
<!-- In Azure pipelines, use Pipeline Caching as the cache storage backend. Otherwise, use the local cache. -->
<MSBuildCachePackageName Condition="'$(TF_BUILD)' != ''">Microsoft.MSBuildCache.AzurePipelines</MSBuildCachePackageName>
<MSBuildCachePackageName Condition="'$(MSBuildCachePackageName)' == ''">Microsoft.MSBuildCache.Local</MSBuildCachePackageName>
</PropertyGroup>
<PropertyGroup Condition="'$(MSBuildCacheEnabled)' == 'true'">
<!-- Change this to bust the cache -->
<MSBuildCacheCacheUniverse Condition="'$(MSBuildCacheCacheUniverse)' == ''">202310210737</MSBuildCacheCacheUniverse>
<!--
Visual Studio telemetry reads various ApplicationInsights.config files and other files after the project is finished, likely in a detached process.
This is acceptable and should not impact cache correctness.
-->
<MSBuildCacheAllowFileAccessAfterProjectFinishFilePatterns>
$(MSBuildCacheAllowFileAccessAfterProjectFinishFilePatterns);
\**\ApplicationInsights.config;
$(LocalAppData)\Microsoft\VSApplicationInsights\**;
$(LocalAppData)\Microsoft\Windows\INetCache\**;
A:\;
E:\;
$(windir)\**;
</MSBuildCacheAllowFileAccessAfterProjectFinishFilePatterns>
<!--
This repo uses a common output directory with many projects writing duplicate outputs. Allow everything, but note this costs some performance in the form of requiring
the cache to use copies instead of hardlinks when pulling from cache.
-->
<MSBuildCacheIdenticalDuplicateOutputPatterns>$(MSBuildCacheIdenticalDuplicateOutputPatterns);bin\**</MSBuildCacheIdenticalDuplicateOutputPatterns>
<!-- version of MSBuildCache is not part of the cache key -->
<PackagesConfigFile>$(MSBuildThisFileDirectory)\dep\nuget\packages.config</PackagesConfigFile>
<MSBuildCacheIgnoredInputPatterns>$(MSBuildCacheIgnoredInputPatterns);$(PackagesConfigFile)</MSBuildCacheIgnoredInputPatterns>
</PropertyGroup>
<PropertyGroup Condition="'$(MSBuildCacheEnabled)' == 'true' and '$(MSBuildCachePackageRoot)' == ''">
<PackagesConfigContents>$([System.IO.File]::ReadAllText("$(PackagesConfigFile)"))</PackagesConfigContents>
<MSBuildCachePackageVersion>$([System.Text.RegularExpressions.Regex]::Match($(PackagesConfigContents), 'Microsoft.MSBuildCache.*?version="(.*?)"').Groups[1].Value)</MSBuildCachePackageVersion>
<MSBuildCachePackageRoot>$(MSBuildThisFileDirectory)packages\$(MSBuildCachePackageName).$(MSBuildCachePackageVersion)</MSBuildCachePackageRoot>
<MSBuildCacheSharedCompilationPackageRoot>$(MSBuildThisFileDirectory)packages\Microsoft.MSBuildCache.SharedCompilation.$(MSBuildCachePackageVersion)</MSBuildCacheSharedCompilationPackageRoot>
</PropertyGroup>
<ImportGroup Condition="'$(MSBuildCacheEnabled)' == 'true'">
<Import Project="$(MSBuildCachePackageRoot)\build\$(MSBuildCachePackageName).props" />
<Import Project="$(MSBuildCacheSharedCompilationPackageRoot)\build\Microsoft.MSBuildCache.SharedCompilation.props" />
</ImportGroup>
</Project>

11
Directory.Build.targets Normal file
View File

@@ -0,0 +1,11 @@
<Project>
<!--
NOTE! This file gets written-over entirely by the release builds.
Any build logic in this file must be optional and only apply to non-release builds.
-->
<ImportGroup Condition="'$(MSBuildCacheEnabled)' == 'true'">
<Import Project="$(MSBuildCachePackageRoot)\build\$(MSBuildCachePackageName).targets" />
<Import Project="$(MSBuildCacheSharedCompilationPackageRoot)\build\Microsoft.MSBuildCache.SharedCompilation.targets" />
</ImportGroup>
</Project>

View File

@@ -1,30 +1,32 @@
trigger: trigger:
batch: true batch: true
# branches: branches:
# include: include:
# - main - main
# - feature/* - feature/*
# - gh-readonly-queue/* - gh-readonly-queue/*
# paths: paths:
# exclude: exclude:
# - doc/* - doc/*
# - samples/* - samples/*
# - tools/* - tools/*
#pr: pr:
# branches: branches:
# include: include:
# - main - main
# - feature/* - feature/*
# paths: paths:
# exclude: exclude:
# - doc/* - doc/*
# - samples/* - samples/*
# - tools/* - tools/*
variables: variables:
- name: runCodesignValidationInjectionBG - name: runCodesignValidationInjectionBG
value: false value: false
- name: EnablePipelineCache
value: true
# 0.0.yyMM.dd## # 0.0.yyMM.dd##
# 0.0.1904.0900 # 0.0.1904.0900
@@ -81,6 +83,8 @@ stages:
buildConfigurations: [Release] buildConfigurations: [Release]
buildEverything: true buildEverything: true
keepAllExpensiveBuildOutputs: false keepAllExpensiveBuildOutputs: false
${{ if eq(variables['System.PullRequest.IsFork'], 'False') }}:
enableCaching: true
- ${{ if eq(parameters.runTests, true) }}: - ${{ if eq(parameters.runTests, true) }}:
- stage: Test_${{ platform }} - stage: Test_${{ platform }}

View File

@@ -68,6 +68,9 @@ parameters:
- name: signingIdentity - name: signingIdentity
type: object type: object
default: {} default: {}
- name: enableCaching
type: boolean
default: false
jobs: jobs:
- job: ${{ parameters.jobName }} - job: ${{ parameters.jobName }}
@@ -95,6 +98,7 @@ jobs:
# Yup. # Yup.
BuildTargetParameter: ' ' BuildTargetParameter: ' '
SelectedSigningFragments: ' ' SelectedSigningFragments: ' '
MSBuildCacheParameters: ' '
# When building the unpackaged distribution, build it in portable mode if it's Canary-branded # When building the unpackaged distribution, build it in portable mode if it's Canary-branded
${{ if eq(parameters.branding, 'Canary') }}: ${{ if eq(parameters.branding, 'Canary') }}:
UnpackagedBuildArguments: -PortableMode UnpackagedBuildArguments: -PortableMode
@@ -111,6 +115,7 @@ jobs:
clean: true clean: true
submodules: true submodules: true
persistCredentials: True persistCredentials: True
# This generates either nothing for BuildTargetParameter, or /t:X;Y;Z, to control targets later. # This generates either nothing for BuildTargetParameter, or /t:X;Y;Z, to control targets later.
- pwsh: |- - pwsh: |-
If (-Not [bool]::Parse("${{ parameters.buildEverything }}")) { If (-Not [bool]::Parse("${{ parameters.buildEverything }}")) {
@@ -139,6 +144,17 @@ jobs:
} }
displayName: Prepare Build and Sign Targets displayName: Prepare Build and Sign Targets
- ${{ if eq(parameters.enableCaching, true) }}:
- pwsh: |-
$MSBuildCacheParameters = ""
$MSBuildCacheParameters += " -graph"
$MSBuildCacheParameters += " -reportfileaccesses"
$MSBuildCacheParameters += " -p:MSBuildCacheEnabled=true"
$MSBuildCacheParameters += " -p:MSBuildCacheLogDirectory=$(Build.SourcesDirectory)\MSBuildCacheLogs"
Write-Host "MSBuildCacheParameters: $MSBuildCacheParameters"
Write-Host "##vso[task.setvariable variable=MSBuildCacheParameters]$MSBuildCacheParameters"
displayName: Prepare MSBuildCache variables
- pwsh: |- - pwsh: |-
.\build\scripts\Generate-ThirdPartyNotices.ps1 -MarkdownNoticePath .\NOTICE.md -OutputPath .\src\cascadia\CascadiaPackage\NOTICE.html .\build\scripts\Generate-ThirdPartyNotices.ps1 -MarkdownNoticePath .\NOTICE.md -OutputPath .\src\cascadia\CascadiaPackage\NOTICE.html
displayName: Generate NOTICE.html from NOTICE.md displayName: Generate NOTICE.html from NOTICE.md
@@ -160,21 +176,37 @@ jobs:
${{ parameters.additionalBuildOptions }} ${{ parameters.additionalBuildOptions }}
/bl:$(Build.SourcesDirectory)\msbuild.binlog /bl:$(Build.SourcesDirectory)\msbuild.binlog
$(BuildTargetParameter) $(BuildTargetParameter)
$(MSBuildCacheParameters)
platform: $(BuildPlatform) platform: $(BuildPlatform)
configuration: $(BuildConfiguration) configuration: $(BuildConfiguration)
msbuildArchitecture: x64
maximumCpuCount: true maximumCpuCount: true
${{ if eq(parameters.enableCaching, true) }}:
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
- ${{ if eq(parameters.publishArtifacts, true) }}: - ${{ if eq(parameters.publishArtifacts, true) }}:
- publish: $(Build.SourcesDirectory)/msbuild.binlog - publish: $(Build.SourcesDirectory)/msbuild.binlog
artifact: logs-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }} artifact: logs-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
condition: always() condition: always()
displayName: Publish Build Log displayName: Publish Build Log
- ${{ if eq(parameters.enableCaching, true) }}:
- publish: $(Build.SourcesDirectory)\MSBuildCacheLogs
artifact: logs-msbuildcache-$(BuildPlatform)-$(BuildConfiguration)${{ parameters.artifactStem }}
condition: always()
displayName: Publish MSBuildCache Logs
- ${{ else }}: - ${{ else }}:
- task: CopyFiles@2 - task: CopyFiles@2
displayName: Copy Build Log displayName: Copy Build Log
inputs: inputs:
contents: $(Build.SourcesDirectory)/msbuild.binlog contents: $(Build.SourcesDirectory)/msbuild.binlog
TargetFolder: $(Terminal.BinDir) TargetFolder: $(Terminal.BinDir)
- ${{ if eq(parameters.enableCaching, true) }}:
- task: CopyFiles@2
displayName: Copy MSBuildCache Logs
inputs:
contents: $(Build.SourcesDirectory)/MSBuildCacheLogs/**
TargetFolder: $(Terminal.BinDir)/MSBuildCacheLogs
# This saves ~2GiB per architecture. We won't need these later. # This saves ~2GiB per architecture. We won't need these later.
# Removes: # Removes:

View File

@@ -17,4 +17,9 @@
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net45" /> <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net45" />
<package id="Selenium.Support" version="3.5.0" targetFramework="net45" /> <package id="Selenium.Support" version="3.5.0" targetFramework="net45" />
<package id="Selenium.WebDriver" version="3.5.0" targetFramework="net45" /> <package id="Selenium.WebDriver" version="3.5.0" targetFramework="net45" />
<!-- MSBuildCache -->
<package id="Microsoft.MSBuildCache.AzurePipelines" version="0.1.273-preview" />
<package id="Microsoft.MSBuildCache.Local" version="0.1.273-preview" />
<package id="Microsoft.MSBuildCache.SharedCompilation" version="0.1.273-preview" />
</packages> </packages>