From ca21c508704e5928faf188e798b1800315e7d0d6 Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Fri, 11 Sep 2026 22:11:47 +0000 Subject: [PATCH 1/2] Enable Roslyn compiler caching in CI Configure the experimental Roslyn compiler output cache alongside sccache for non-official builds. Disable SourceLink for those builds, persist the cache through Azure Pipelines, and report per-build cache statistics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ab967da8-759b-499d-a20d-d6d6c2cc355d --- eng/pipelines/common/global-build-job.yml | 5 +++- .../coreclr/templates/roslyn-cache-stats.yml | 24 +++++++++++++++ .../coreclr/templates/sccache-stats.yml | 2 ++ .../coreclr/templates/setup-roslyn-cache.yml | 30 +++++++++++++++++++ .../coreclr/templates/setup-sccache.yml | 7 +++++ 5 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 eng/pipelines/coreclr/templates/roslyn-cache-stats.yml create mode 100644 eng/pipelines/coreclr/templates/setup-roslyn-cache.yml diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index c29b03465a49c0..49a75927743738 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -141,6 +141,9 @@ jobs: - name: MSBUILDDEBUGPATH value: $(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/MsbuildDebugLogs + - name: _compilerCacheBuildArgs + value: '' + - ${{ each variableTemplate in parameters.extraVariablesTemplates }}: - template: ${{ variableTemplate.template }} parameters: @@ -224,7 +227,7 @@ jobs: # Build - template: /eng/pipelines/common/templates/global-build-step.yml parameters: - buildArgs: ${{ parameters.buildArgs }} + buildArgs: ${{ parameters.buildArgs }} $(_compilerCacheBuildArgs) useContinueOnErrorDuringBuild: ${{ parameters.useContinueOnErrorDuringBuild }} shouldContinueOnError: ${{ parameters.shouldContinueOnError }} diff --git a/eng/pipelines/coreclr/templates/roslyn-cache-stats.yml b/eng/pipelines/coreclr/templates/roslyn-cache-stats.yml new file mode 100644 index 00000000000000..cf9dc92a01b316 --- /dev/null +++ b/eng/pipelines/coreclr/templates/roslyn-cache-stats.yml @@ -0,0 +1,24 @@ +steps: + - script: | + set -euo pipefail + + dotnet="$(Build.SourcesDirectory)/.dotnet/dotnet" + if [[ -z "${ROSLYN_CACHE_PATH:-}" || + -z "${ROSLYN_CACHE_BUILD_START:-}" || + ! -x "$dotnet" ]]; then + echo "Roslyn compiler cache statistics are unavailable." + exit 0 + fi + + sdkVersion="$("$dotnet" --version)" + compilerServer="$(Build.SourcesDirectory)/.dotnet/sdk/$sdkVersion/Roslyn/bincore/VBCSCompiler.dll" + if [[ ! -f "$compilerServer" ]]; then + echo "Roslyn compiler server not found at $compilerServer." + exit 0 + fi + + "$dotnet" "$compilerServer" \ + "-cachestats:${ROSLYN_CACHE_BUILD_START}" \ + "-cachepath:${ROSLYN_CACHE_PATH}" || true + displayName: Roslyn compiler cache stats + condition: always() diff --git a/eng/pipelines/coreclr/templates/sccache-stats.yml b/eng/pipelines/coreclr/templates/sccache-stats.yml index 3f7f000ced1ae3..86bd555e568609 100644 --- a/eng/pipelines/coreclr/templates/sccache-stats.yml +++ b/eng/pipelines/coreclr/templates/sccache-stats.yml @@ -13,6 +13,8 @@ parameters: steps: - ${{ if and(or(eq(parameters.osGroup, 'linux'), eq(parameters.osGroup, 'freebsd'), eq(parameters.osGroup, 'openbsd'), eq(parameters.osGroup, 'osx')), or(eq(parameters.archType, 'x64'), eq(parameters.archType, 'arm64'))) }}: + - template: /eng/pipelines/coreclr/templates/roslyn-cache-stats.yml + - script: sccache --show-stats || true displayName: Sccache stats condition: always() diff --git a/eng/pipelines/coreclr/templates/setup-roslyn-cache.yml b/eng/pipelines/coreclr/templates/setup-roslyn-cache.yml new file mode 100644 index 00000000000000..7f8cc3ac57b5a9 --- /dev/null +++ b/eng/pipelines/coreclr/templates/setup-roslyn-cache.yml @@ -0,0 +1,30 @@ +parameters: + archType: 'x64' + osGroup: 'linux' + nameSuffix: '' + osSubgroup: '' + +steps: + # Cache entries restored by pull request builds come only from the pull + # request itself or its target branch. This lets rolling builds seed the + # cache without allowing pull requests to modify caches used by main. + # + # The managed configuration is intentionally excluded. Roslyn's + # deterministic key includes the compilation options, and some pipeline + # legs override the matrix configuration in their build arguments. + - task: Cache@2 + displayName: Roslyn compiler cache + continueOnError: true + inputs: + key: roslyn | v1 | ${{ parameters.osGroup }}${{ parameters.osSubgroup }} | ${{ parameters.archType }} | ${{ parameters.nameSuffix }} | "$(Build.BuildId)" + path: $(Pipeline.Workspace)/.roslyn-cache + restoreKeys: | + roslyn | v1 | ${{ parameters.osGroup }}${{ parameters.osSubgroup }} | ${{ parameters.archType }} | ${{ parameters.nameSuffix }} + + - script: | + set -euo pipefail + echo "##vso[task.setvariable variable=ROSLYN_CACHE_PATH]$(Pipeline.Workspace)/.roslyn-cache" + echo "##vso[task.setvariable variable=ROSLYN_CACHE_BUILD_START]$(date -u +"%Y-%m-%dT%H:%M:%SZ")" + echo "##vso[task.setvariable variable=EnableSourceLink]false" + echo "##vso[task.setvariable variable=_compilerCacheBuildArgs]/p:EnableSourceLink=false" + displayName: Configure Roslyn compiler cache diff --git a/eng/pipelines/coreclr/templates/setup-sccache.yml b/eng/pipelines/coreclr/templates/setup-sccache.yml index d133175afb5901..cf703d5da6501b 100644 --- a/eng/pipelines/coreclr/templates/setup-sccache.yml +++ b/eng/pipelines/coreclr/templates/setup-sccache.yml @@ -17,6 +17,13 @@ parameters: steps: - ${{ if and(or(eq(parameters.osGroup, 'linux'), eq(parameters.osGroup, 'freebsd'), eq(parameters.osGroup, 'openbsd'), eq(parameters.osGroup, 'osx')), or(eq(parameters.archType, 'x64'), eq(parameters.archType, 'arm64'))) }}: + - template: /eng/pipelines/coreclr/templates/setup-roslyn-cache.yml + parameters: + osGroup: ${{ parameters.osGroup }} + osSubgroup: ${{ parameters.osSubgroup }} + archType: ${{ parameters.archType }} + nameSuffix: ${{ parameters.nameSuffix }} + # Set up the Azure Pipeline Cache for sccache's local cache directory. # Use a rolling key so each build can update the cache; restoreKeys # falls back to the most recent saved entry. From e04c9061fe20d5bb367ef185a07fe1771fa2d2cf Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Thu, 17 Sep 2026 06:28:22 +0000 Subject: [PATCH 2/2] Configure SourceLink with the Roslyn cache Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 501aac83-6191-40e5-8dc2-ef3acbcb1e41 --- Directory.Build.props | 1 + eng/pipelines/common/global-build-job.yml | 5 +---- eng/pipelines/coreclr/templates/setup-roslyn-cache.yml | 2 -- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 06baa90ca2bc65..d3b28c9e287651 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -15,6 +15,7 @@ false + false diff --git a/eng/pipelines/common/global-build-job.yml b/eng/pipelines/common/global-build-job.yml index 49a75927743738..c29b03465a49c0 100644 --- a/eng/pipelines/common/global-build-job.yml +++ b/eng/pipelines/common/global-build-job.yml @@ -141,9 +141,6 @@ jobs: - name: MSBUILDDEBUGPATH value: $(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/MsbuildDebugLogs - - name: _compilerCacheBuildArgs - value: '' - - ${{ each variableTemplate in parameters.extraVariablesTemplates }}: - template: ${{ variableTemplate.template }} parameters: @@ -227,7 +224,7 @@ jobs: # Build - template: /eng/pipelines/common/templates/global-build-step.yml parameters: - buildArgs: ${{ parameters.buildArgs }} $(_compilerCacheBuildArgs) + buildArgs: ${{ parameters.buildArgs }} useContinueOnErrorDuringBuild: ${{ parameters.useContinueOnErrorDuringBuild }} shouldContinueOnError: ${{ parameters.shouldContinueOnError }} diff --git a/eng/pipelines/coreclr/templates/setup-roslyn-cache.yml b/eng/pipelines/coreclr/templates/setup-roslyn-cache.yml index 7f8cc3ac57b5a9..dcc5e6152ec062 100644 --- a/eng/pipelines/coreclr/templates/setup-roslyn-cache.yml +++ b/eng/pipelines/coreclr/templates/setup-roslyn-cache.yml @@ -25,6 +25,4 @@ steps: set -euo pipefail echo "##vso[task.setvariable variable=ROSLYN_CACHE_PATH]$(Pipeline.Workspace)/.roslyn-cache" echo "##vso[task.setvariable variable=ROSLYN_CACHE_BUILD_START]$(date -u +"%Y-%m-%dT%H:%M:%SZ")" - echo "##vso[task.setvariable variable=EnableSourceLink]false" - echo "##vso[task.setvariable variable=_compilerCacheBuildArgs]/p:EnableSourceLink=false" displayName: Configure Roslyn compiler cache