From 234e34d4def6efd24740488c3cab887dc5a1793b Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sat, 27 Sep 2025 14:56:47 -0600 Subject: [PATCH 001/174] Switch to NuGet Trusted Publishing --- .github/workflows/release.yml | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1b4e25c..b84d907 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,17 +15,10 @@ jobs: release: runs-on: ubuntu-24.04 permissions: - actions: read - contents: write + actions: read # Required to download artifacts + contents: write # Upload artifacts to Release + id-token: write # Required for NuGet CLI Login steps: - - name: โš™๏ธ Initialization - shell: pwsh - run: | - if ('${{ secrets.NUGET_API_KEY }}') { - Write-Host "NUGET_API_KEY secret detected. NuGet packages will be pushed." - echo "NUGET_API_KEY_DEFINED=true" >> $env:GITHUB_ENV - } - - name: ๐Ÿ”Ž Search for build of ${{ github.ref }} shell: pwsh id: findrunid @@ -82,6 +75,11 @@ jobs: gh release -R ${{ github.repository }} upload "${{ github.ref_name }}" $_.FullName } + - name: ๐Ÿชช Authorize NuGet package push + uses: NuGet/login@d22cc5f58ff5b88bf9bd452535b4335137e24544 # v1 + id: nuget-login + with: + user: ${{ secrets.NUGET_USER }} + - name: ๐Ÿš€ Push NuGet packages - run: dotnet nuget push ${{ runner.temp }}/deployables/*.nupkg --source https://api.nuget.org/v3/index.json -k '${{ secrets.NUGET_API_KEY }}' - if: ${{ env.NUGET_API_KEY_DEFINED == 'true' }} + run: dotnet nuget push ${{ runner.temp }}/deployables/*.nupkg --source https://api.nuget.org/v3/index.json -k '${{ steps.nuget-login.outputs.NUGET_API_KEY }}' From e574cb5e19a217eeebf29b71a572c153fefbb855 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 27 Sep 2025 21:04:27 -0600 Subject: [PATCH 002/174] Update xunit (#417) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Directory.Packages.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 8cbe694..aa5788c 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,8 +10,8 @@ - - + + From 8712b0e13085e2603f6bb3d61f644395b5b2e268 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 06:41:55 -0700 Subject: [PATCH 003/174] Update dependency dotnet-coverage to v18 (#419) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index bdb0ed4..f8c4a26 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -10,7 +10,7 @@ "rollForward": false }, "dotnet-coverage": { - "version": "17.14.2", + "version": "18.0.4", "commands": [ "dotnet-coverage" ], From 11ec88f1d866e5c246e3a91690d1adfaf9227ad8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Oct 2025 02:21:26 +0000 Subject: [PATCH 004/174] Update mcr.microsoft.com/dotnet/sdk:9.0.305-noble Docker digest to 8a26226 Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 4a440ef..2c0bd56 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:9.0.305-noble@sha256:604ef064c6d91068eeb9d946036d8ffadbe25589c4cd77a230fc96e0f6d01d72 +FROM mcr.microsoft.com/dotnet/sdk:9.0.305-noble@sha256:8a26226e58ec52c5defb37b876584df99f94bec70f1081c4014fdf25c994d51e # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. From 86903f81179e9d6649b834eb619075b9dbbec4ba Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 1 Oct 2025 09:13:20 -0700 Subject: [PATCH 005/174] Drop devcontainer folder from microbuild repos The pinned Docker image changes too frequently, causing high severity security alerts, and we don't even hardly use this file. --- .devcontainer/Dockerfile | 14 -------------- .devcontainer/devcontainer.json | 25 ------------------------- 2 files changed, 39 deletions(-) delete mode 100644 .devcontainer/Dockerfile delete mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index 2c0bd56..0000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -# Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:9.0.305-noble@sha256:8a26226e58ec52c5defb37b876584df99f94bec70f1081c4014fdf25c994d51e - -# Installing mono makes `dotnet test` work without errors even for net472. -# But installing it takes a long time, so it's excluded by default. -#RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF -#RUN echo "deb https://download.mono-project.com/repo/ubuntu stable-bionic main" | tee /etc/apt/sources.list.d/mono-official-stable.list -#RUN apt-get update -#RUN DEBIAN_FRONTEND=noninteractive apt-get install -y mono-devel - -# Clear the NUGET_XMLDOC_MODE env var so xml api doc files get unpacked, allowing a rich experience in Intellisense. -# See https://github.com/dotnet/dotnet-docker/issues/2790 for a discussion on this, where the prioritized use case -# was *not* devcontainers, sadly. -ENV NUGET_XMLDOC_MODE= diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 1a3a008..0000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "Dev space", - "dockerFile": "Dockerfile", - "customizations": { - "vscode": { - "settings": { - "terminal.integrated.shell.linux": "/usr/bin/pwsh" - }, - "extensions": [ - "ms-azure-devops.azure-pipelines", - "ms-dotnettools.csharp", - "k--kato.docomment", - "editorconfig.editorconfig", - "esbenp.prettier-vscode", - "pflannery.vscode-versionlens", - "davidanson.vscode-markdownlint", - "dotjoshjohnson.xml", - "ms-vscode-remote.remote-containers", - "ms-azuretools.vscode-docker", - "tintoy.msbuild-project-tools" - ] - } - }, - "postCreateCommand": "./init.ps1 -InstallLocality machine" -} From 97119efc181001bec8a68705f817a354f91f983b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 10:52:49 -0700 Subject: [PATCH 006/174] Update dependency Microsoft.NET.Test.Sdk to v18 (#422) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index aa5788c..91c1e03 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -9,7 +9,7 @@ - + From 870263bde71884ab9cc7492ad73cac298b789063 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Oct 2025 10:53:05 -0700 Subject: [PATCH 007/174] Update mcr.microsoft.com/dotnet/sdk:9.0.305-noble Docker digest to 9ae2f68 Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 2c0bd56..5edfe78 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:9.0.305-noble@sha256:8a26226e58ec52c5defb37b876584df99f94bec70f1081c4014fdf25c994d51e +FROM mcr.microsoft.com/dotnet/sdk:9.0.305-noble@sha256:9ae2f68485dc3385e76e38524806fd159988b6e525ea5f27a4870bdf8bc0fe72 # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. From 184e741e11a04a5801fe63434de0e83e590fbbf4 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 7 Oct 2025 10:58:46 -0600 Subject: [PATCH 008/174] Add `repo` command as a CLI tool --- .config/dotnet-tools.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index f8c4a26..3972456 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -29,6 +29,13 @@ "docfx" ], "rollForward": false + }, + "nerdbank.dotnetrepotools": { + "version": "1.0.92", + "commands": [ + "repo" + ], + "rollForward": false } } -} +} \ No newline at end of file From 705966a7b1e897d7dcef98528b8ec1132eec90d5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 06:19:47 -0600 Subject: [PATCH 009/174] Update dependency dotnet-coverage to v18.1.0 Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 3972456..859d3f4 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -10,7 +10,7 @@ "rollForward": false }, "dotnet-coverage": { - "version": "18.0.4", + "version": "18.1.0", "commands": [ "dotnet-coverage" ], From 217b879a0d5f4fa1148c69daf46efa35d306dc40 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 13 Oct 2025 12:26:43 -0600 Subject: [PATCH 010/174] Activate CFSClean network isolation policy This will prevent all Library.Template pipelines from accessing nuget.org or other public package feeds directly. Instead, Azure Artifacts feeds should be used. --- azure-pipelines/archive-sourcecode.yml | 2 ++ azure-pipelines/libtemplate-update.yml | 2 ++ azure-pipelines/official.yml | 2 ++ azure-pipelines/release.yml | 2 ++ azure-pipelines/unofficial.yml | 2 ++ azure-pipelines/vs-insertion.yml | 2 ++ azure-pipelines/vs-validation.yml | 2 ++ 7 files changed, 14 insertions(+) diff --git a/azure-pipelines/archive-sourcecode.yml b/azure-pipelines/archive-sourcecode.yml index 77f243b..7f35de4 100644 --- a/azure-pipelines/archive-sourcecode.yml +++ b/azure-pipelines/archive-sourcecode.yml @@ -35,6 +35,8 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate parameters: + settings: + networkIsolationPolicy: Permissive,CFSClean sdl: sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES diff --git a/azure-pipelines/libtemplate-update.yml b/azure-pipelines/libtemplate-update.yml index 384be7c..a0421bd 100644 --- a/azure-pipelines/libtemplate-update.yml +++ b/azure-pipelines/libtemplate-update.yml @@ -30,6 +30,8 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Unofficial.yml@MicroBuildTemplate parameters: + settings: + networkIsolationPolicy: Permissive,CFSClean sdl: sourceAnalysisPool: name: AzurePipelines-EO diff --git a/azure-pipelines/official.yml b/azure-pipelines/official.yml index 6d7c021..ab66443 100644 --- a/azure-pipelines/official.yml +++ b/azure-pipelines/official.yml @@ -45,6 +45,8 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate parameters: + settings: + networkIsolationPolicy: Permissive,CFSClean sdl: sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES codeSignValidation: diff --git a/azure-pipelines/release.yml b/azure-pipelines/release.yml index 3100e4b..73418a9 100644 --- a/azure-pipelines/release.yml +++ b/azure-pipelines/release.yml @@ -20,6 +20,8 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate parameters: + settings: + networkIsolationPolicy: Permissive,CFSClean sdl: sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES diff --git a/azure-pipelines/unofficial.yml b/azure-pipelines/unofficial.yml index d723273..bc2e88e 100644 --- a/azure-pipelines/unofficial.yml +++ b/azure-pipelines/unofficial.yml @@ -55,6 +55,8 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Unofficial.yml@MicroBuildTemplate parameters: + settings: + networkIsolationPolicy: Permissive,CFSClean sdl: sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES credscan: diff --git a/azure-pipelines/vs-insertion.yml b/azure-pipelines/vs-insertion.yml index c19331d..71c9041 100644 --- a/azure-pipelines/vs-insertion.yml +++ b/azure-pipelines/vs-insertion.yml @@ -23,6 +23,8 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate parameters: + settings: + networkIsolationPolicy: Permissive,CFSClean sdl: sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES diff --git a/azure-pipelines/vs-validation.yml b/azure-pipelines/vs-validation.yml index b9d46b7..b6c79ab 100644 --- a/azure-pipelines/vs-validation.yml +++ b/azure-pipelines/vs-validation.yml @@ -26,6 +26,8 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Unofficial.yml@MicroBuildTemplate parameters: + settings: + networkIsolationPolicy: Permissive,CFSClean sdl: sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES credscan: From 461d00fbb95eabbf2f268a70ca29c5239adddb21 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 14 Oct 2025 18:17:34 -0600 Subject: [PATCH 011/174] Update Dockerfile and global.json updates to v9.0.306 Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- global.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 5edfe78..5d19722 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:9.0.305-noble@sha256:9ae2f68485dc3385e76e38524806fd159988b6e525ea5f27a4870bdf8bc0fe72 +FROM mcr.microsoft.com/dotnet/sdk:9.0.306-noble@sha256:953b8dd2d8e25c934579905b00d7077c5622632ff617f471a211ce9b72013205 # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. diff --git a/global.json b/global.json index 6fea1e9..cfaecd0 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.305", + "version": "9.0.306", "rollForward": "patch", "allowPrerelease": false } From 3f2ca0571b4cbaa166f81be9dfcf3ba149571bd8 Mon Sep 17 00:00:00 2001 From: Pierson Lee Date: Thu, 16 Oct 2025 16:49:50 -0700 Subject: [PATCH 012/174] Update InsertJsonValues to handle folders (#391) * Update InsertJsonValues to handle folders If the VSMan is in a nested folder, then the folder becomes part of the upload. Updated the InsertJsonValues to handle that. * Move BasePath Resolve-Path inside the test-path * Update comments and logic to make it cleaner --- tools/variables/InsertJsonValues.ps1 | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/tools/variables/InsertJsonValues.ps1 b/tools/variables/InsertJsonValues.ps1 index 7aa8d30..fb9390c 100644 --- a/tools/variables/InsertJsonValues.ps1 +++ b/tools/variables/InsertJsonValues.ps1 @@ -8,11 +8,25 @@ $BasePath = "$PSScriptRoot\..\..\bin\Packages\$BuildConfiguration\Vsix" if (Test-Path $BasePath) { $vsmanFiles = @() - Get-ChildItem $BasePath *.vsman -Recurse -File |% { + Get-ChildItem $BasePath *.vsman -Recurse -File | % { $version = (Get-Content $_.FullName | ConvertFrom-Json).info.buildVersion + $fullPath = (Resolve-Path $_.FullName).Path + $basePath = (Resolve-Path $BasePath).Path + # Cannot use RelativePath or GetRelativePath due to Powershell Core v2.0 limitation + if ($fullPath.StartsWith($basePath, [StringComparison]::OrdinalIgnoreCase)) { + # Get the relative paths then make sure the directory separators match URL format. + $rfn = $fullPath.Substring($basePath.Length).TrimStart('\', '/').Replace('\', '/') + } + else { + $rfn = $fullPath # fallback to full path if it doesn't start with base path + } + $fn = $_.Name - $vsmanFiles += "$fn{$version}=https://vsdrop.corp.microsoft.com/file/v1/$vstsDropNames;$fn" + + # The left side is filename followed by the version and the right side is the drop url and the relative filename + $thisVsManFile = "$fn{$version}=https://vsdrop.corp.microsoft.com/file/v1/$vstsDropNames;$rfn" + $vsmanFiles += $thisVsManFile } - [string]::join(',',$vsmanFiles) + [string]::join(',', $vsmanFiles) } From 206b88c3d7a08d32f10a7c964257fec455f5544a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 Oct 2025 23:55:50 +0000 Subject: [PATCH 013/174] Update dependency powershell to v7.5.4 (#427) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 859d3f4..c52d110 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "powershell": { - "version": "7.5.3", + "version": "7.5.4", "commands": [ "pwsh" ], From f0720455725ef509d7c5fcafb0b467d4db2b6410 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Oct 2025 07:17:41 -0600 Subject: [PATCH 014/174] Update mcr.microsoft.com/dotnet/sdk:9.0.306-noble Docker digest to d88e637 (#428) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 5d19722..f988758 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:9.0.306-noble@sha256:953b8dd2d8e25c934579905b00d7077c5622632ff617f471a211ce9b72013205 +FROM mcr.microsoft.com/dotnet/sdk:9.0.306-noble@sha256:d88e637d15248531967111fba05c6725ad45ea1dace3d35d8cfe2c4d4094e25d # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. From 03563e49fb6f4bc99cb768e8659869a82d7fb683 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 20 Oct 2025 17:03:00 -0600 Subject: [PATCH 015/174] Move `GitHubRelease` task to a release job --- azure-pipelines/release.yml | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/azure-pipelines/release.yml b/azure-pipelines/release.yml index 73418a9..aea1a2d 100644 --- a/azure-pipelines/release.yml +++ b/azure-pipelines/release.yml @@ -28,7 +28,8 @@ extends: stages: - stage: release jobs: - - job: release + - job: nuget + displayName: ๐Ÿ“ฆ Push nuget.org packages pool: name: AzurePipelines-EO demands: @@ -45,6 +46,28 @@ extends: publishFeedCredentials: VisualStudioExtensibility (nuget.org) steps: - checkout: none + - download: CI + artifact: deployables-Windows + displayName: ๐Ÿ”ป Download deployables-Windows artifact + patterns: 'NuGet/*' + - job: github + displayName: ๐Ÿ“ข GitHub release + dependsOn: nuget + pool: + name: AzurePipelines-EO + demands: + - ImageOverride -equals 1ESPT-Ubuntu22.04 + os: Linux + templateContext: + type: releaseJob + isProduction: true + inputs: + - input: pipelineArtifact + pipeline: CI + artifactName: deployables-Windows + targetPath: $(Pipeline.Workspace)/CI/deployables-Windows + steps: + - checkout: none - powershell: | Write-Host "##vso[build.updatebuildnumber]$(resources.pipeline.CI.runName)" if ('$(resources.pipeline.CI.runName)'.Contains('-')) { @@ -53,10 +76,6 @@ extends: Write-Host "##vso[task.setvariable variable=IsPrerelease]false" } displayName: โš™ Set up pipeline - - download: CI - artifact: deployables-Windows - displayName: ๐Ÿ”ป Download deployables-Windows artifact - patterns: 'NuGet/*' - task: GitHubRelease@1 displayName: ๐Ÿ“ข GitHub release (create) inputs: From a880a38116eedf9893cbb9afcaaa8f633e98b357 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 22 Oct 2025 07:53:58 -0600 Subject: [PATCH 016/174] Drop EnableOptProf parameter where it is unused --- azure-pipelines/build.yml | 2 -- azure-pipelines/microbuild.after.yml | 3 --- azure-pipelines/microbuild.before.yml | 3 --- 3 files changed, 8 deletions(-) diff --git a/azure-pipelines/build.yml b/azure-pipelines/build.yml index 3db1add..b68abbc 100644 --- a/azure-pipelines/build.yml +++ b/azure-pipelines/build.yml @@ -191,7 +191,6 @@ jobs: - template: microbuild.before.yml parameters: EnableLocalization: ${{ parameters.EnableLocalization }} - EnableOptProf: ${{ parameters.EnableOptProf }} IsOptProf: ${{ parameters.IsOptProf }} ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }} RealSign: ${{ parameters.RealSign }} @@ -211,7 +210,6 @@ jobs: - ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}: - template: microbuild.after.yml parameters: - EnableOptProf: ${{ parameters.EnableOptProf }} IsOptProf: ${{ parameters.IsOptProf }} SkipCodesignVerify: ${{ parameters.SkipCodesignVerify }} diff --git a/azure-pipelines/microbuild.after.yml b/azure-pipelines/microbuild.after.yml index 025de4f..67ba900 100644 --- a/azure-pipelines/microbuild.after.yml +++ b/azure-pipelines/microbuild.after.yml @@ -1,7 +1,4 @@ parameters: -- name: EnableOptProf - type: boolean - default: false - name: IsOptProf type: boolean default: false diff --git a/azure-pipelines/microbuild.before.yml b/azure-pipelines/microbuild.before.yml index d09310b..b169460 100644 --- a/azure-pipelines/microbuild.before.yml +++ b/azure-pipelines/microbuild.before.yml @@ -2,9 +2,6 @@ parameters: - name: EnableLocalization type: boolean default: false -- name: EnableOptProf - type: boolean - default: false - name: IsOptProf type: boolean default: false From a16d3f4213237f1b70c1f592edb466a4acac8bab Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 22 Oct 2025 10:17:23 -0600 Subject: [PATCH 017/174] Add SBOM to `deployables` pipeline artifact This is required for consumption from production release jobs. --- azure-pipelines/build.yml | 60 ++++++++++++++++++++++-------------- azure-pipelines/official.yml | 1 + 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/azure-pipelines/build.yml b/azure-pipelines/build.yml index b68abbc..c23a028 100644 --- a/azure-pipelines/build.yml +++ b/azure-pipelines/build.yml @@ -29,14 +29,17 @@ parameters: - name: artifact_names type: object default: - - build_logs - - coverageResults - - deployables - - projectAssetsJson - - symbols - - testResults - - test_symbols - - Variables + - name: build_logs + - name: coverageResults + - name: deployables + sbomEnabled: true + - name: projectAssetsJson + - name: symbols + - name: testResults + testOnly: true + - name: test_symbols + testOnly: true + - name: Variables # The Enable*Build parameters turn non-Windows agents on or off. # Their default value should be based on whether the build and tests are expected/required to pass on that platform. # Callers (e.g. Official.yml) *may* expose these parameters at queue-time in order to turn OFF optional agents. @@ -57,6 +60,11 @@ parameters: - name: Is1ESPT type: boolean +# Indicates whether the 'official' 1ES PT templates are being used (as opposed to the unofficial ones). +- name: Is1ESPTOfficial + type: boolean + default: false + - name: RealSign type: boolean default: false @@ -148,12 +156,14 @@ jobs: outputParentDirectory: $(Build.ArtifactStagingDirectory) outputs: - - ${{ each artifact_name in parameters.artifact_names }}: - - ${{ if or(ne(artifact_name, 'testResults'), parameters.RunTests) }}: + - ${{ each artifact in parameters.artifact_names }}: + - ${{ if or(ne(artifact.testOnly, 'true'), parameters.RunTests) }}: - output: pipelineArtifact - displayName: ๐Ÿ“ข Publish ${{ artifact_name }}-Windows - targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact_name }}-Windows - artifactName: ${{ artifact_name }}-Windows + displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-Windows + targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-Windows + artifactName: ${{ artifact.name }}-Windows + ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: + sbomEnabled: true condition: succeededOrFailed() - output: pipelineArtifact displayName: ๐Ÿ“ข Publish VSInsertion-Windows @@ -229,12 +239,14 @@ jobs: signWithProd: true outputParentDirectory: $(Build.ArtifactStagingDirectory) outputs: - - ${{ each artifact_name in parameters.artifact_names }}: - - ${{ if or(ne(artifact_name, 'testResults'), parameters.RunTests) }}: + - ${{ each artifact in parameters.artifact_names }}: + - ${{ if or(ne(artifact.testOnly, 'true'), parameters.RunTests) }}: - output: pipelineArtifact - displayName: ๐Ÿ“ข Publish ${{ artifact_name }}-Linux - targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact_name }}-Linux - artifactName: ${{ artifact_name }}-Linux + displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-Linux + targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-Linux + artifactName: ${{ artifact.name }}-Linux + ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: + sbomEnabled: true condition: succeededOrFailed() steps: - checkout: self @@ -266,12 +278,14 @@ jobs: signWithProd: true outputParentDirectory: $(Build.ArtifactStagingDirectory) outputs: - - ${{ each artifact_name in parameters.artifact_names }}: - - ${{ if or(ne(artifact_name, 'testResults'), parameters.RunTests) }}: + - ${{ each artifact in parameters.artifact_names }}: + - ${{ if or(ne(artifact.testOnly, 'true'), parameters.RunTests) }}: - output: pipelineArtifact - displayName: ๐Ÿ“ข Publish ${{ artifact_name }}-macOS - targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact_name }}-macOS - artifactName: ${{ artifact_name }}-macOS + displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-macOS + targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-macOS + artifactName: ${{ artifact.name }}-macOS + ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: + sbomEnabled: true condition: succeededOrFailed() steps: - checkout: self diff --git a/azure-pipelines/official.yml b/azure-pipelines/official.yml index ab66443..5404962 100644 --- a/azure-pipelines/official.yml +++ b/azure-pipelines/official.yml @@ -68,6 +68,7 @@ extends: - template: /azure-pipelines/build.yml@self parameters: Is1ESPT: true + Is1ESPTOfficial: true RealSign: true # ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }} EnableAPIScan: ${{ parameters.EnableAPIScan }} From f3393ad1756b2fb45ba906632e1f7d5c328fa9e6 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 22 Oct 2025 18:08:09 -0600 Subject: [PATCH 018/174] Bump MicroBuildVersion to 2.0.208 --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 36dfba2..a8f5bc9 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,7 +5,7 @@ true true - 2.0.201 + 2.0.208 From dd97dcaf812067a5568d7642a2ac5882cb159873 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 23 Oct 2025 07:07:24 -0600 Subject: [PATCH 019/174] Fix artifact publishing failures due to prior failed attempts --- azure-pipelines/build.yml | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/azure-pipelines/build.yml b/azure-pipelines/build.yml index c23a028..078cb83 100644 --- a/azure-pipelines/build.yml +++ b/azure-pipelines/build.yml @@ -164,7 +164,13 @@ jobs: artifactName: ${{ artifact.name }}-Windows ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: sbomEnabled: true - condition: succeededOrFailed() + - output: pipelineArtifact + displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-Windows (for failed attempts) + targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-Windows + artifactName: ${{ artifact.name }}-Windows-$(System.PhaseAttempt) + ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: + sbomEnabled: true + condition: failed() - output: pipelineArtifact displayName: ๐Ÿ“ข Publish VSInsertion-Windows targetPath: $(Build.ArtifactStagingDirectory)/VSInsertion-Windows @@ -247,7 +253,13 @@ jobs: artifactName: ${{ artifact.name }}-Linux ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: sbomEnabled: true - condition: succeededOrFailed() + - output: pipelineArtifact + displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-Linux (for failed attempts) + targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-Linux + artifactName: ${{ artifact.name }}-Linux-$(System.PhaseAttempt) + ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: + sbomEnabled: true + condition: failed() steps: - checkout: self fetchDepth: 0 # avoid shallow clone so nbgv can do its work. @@ -286,7 +298,13 @@ jobs: artifactName: ${{ artifact.name }}-macOS ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: sbomEnabled: true - condition: succeededOrFailed() + - output: pipelineArtifact + displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-macOS (for failed attempts) + targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-macOS + artifactName: ${{ artifact.name }}-macOS-$(System.PhaseAttempt) + ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: + sbomEnabled: true + condition: failed() steps: - checkout: self fetchDepth: 0 # avoid shallow clone so nbgv can do its work. From 9389c4868a594ea30efa805cb40781ac4c80a29f Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 23 Oct 2025 09:50:09 -0600 Subject: [PATCH 020/174] Switch from sln to slnx --- Library.sln | 63 ---------------------------------------------------- Library.slnx | 26 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 63 deletions(-) delete mode 100644 Library.sln create mode 100644 Library.slnx diff --git a/Library.sln b/Library.sln deleted file mode 100644 index 5c81b30..0000000 --- a/Library.sln +++ /dev/null @@ -1,63 +0,0 @@ -๏ปฟ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 18 -VisualStudioVersion = 18.0.11023.372 main -MinimumVisualStudioVersion = 15.0.26124.0 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Library", "src\Library\Library.csproj", "{C06D702E-6FC7-453B-BDDF-608F825EC003}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Library.Tests", "test\Library.Tests\Library.Tests.csproj", "{DC5F3D1C-A9A3-44B7-A3C0-82C1FF4C3336}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1CE9670B-D5FF-46A7-9D00-24E70E6ED48B}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - Directory.Build.props = Directory.Build.props - Directory.Build.targets = Directory.Build.targets - Directory.Packages.props = Directory.Packages.props - .config\dotnet-tools.json = .config\dotnet-tools.json - global.json = global.json - nuget.config = nuget.config - README.md = README.md - stylecop.json = stylecop.json - version.json = version.json - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9E154A29-1796-4B85-BD81-B6A385D8FF71}" - ProjectSection(SolutionItems) = preProject - src\.editorconfig = src\.editorconfig - src\Directory.Build.props = src\Directory.Build.props - src\Directory.Build.targets = src\Directory.Build.targets - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{36CCE840-6FE5-4DB9-A8D5-8CF3CB6D342A}" - ProjectSection(SolutionItems) = preProject - test\.editorconfig = test\.editorconfig - test\Directory.Build.props = test\Directory.Build.props - test\Directory.Build.targets = test\Directory.Build.targets - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C06D702E-6FC7-453B-BDDF-608F825EC003}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C06D702E-6FC7-453B-BDDF-608F825EC003}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C06D702E-6FC7-453B-BDDF-608F825EC003}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C06D702E-6FC7-453B-BDDF-608F825EC003}.Release|Any CPU.Build.0 = Release|Any CPU - {DC5F3D1C-A9A3-44B7-A3C0-82C1FF4C3336}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DC5F3D1C-A9A3-44B7-A3C0-82C1FF4C3336}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DC5F3D1C-A9A3-44B7-A3C0-82C1FF4C3336}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DC5F3D1C-A9A3-44B7-A3C0-82C1FF4C3336}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {9E154A29-1796-4B85-BD81-B6A385D8FF71} = {1CE9670B-D5FF-46A7-9D00-24E70E6ED48B} - {36CCE840-6FE5-4DB9-A8D5-8CF3CB6D342A} = {1CE9670B-D5FF-46A7-9D00-24E70E6ED48B} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {E3944F6A-384B-4B0F-B93F-3BD513DC57BD} - EndGlobalSection -EndGlobal diff --git a/Library.slnx b/Library.slnx new file mode 100644 index 0000000..dc016d9 --- /dev/null +++ b/Library.slnx @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + From 68801e8c8d8c4d1a32e797447da3bbb0f45dbf72 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 23 Oct 2025 10:39:16 -0600 Subject: [PATCH 021/174] Clarify that symbols should be only 1st party --- ...rdPartySymbolFiles.ps1 => Get-ExternalSymbolFiles.ps1} | 8 +++++--- tools/artifacts/symbols.ps1 | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) rename tools/{Get-3rdPartySymbolFiles.ps1 => Get-ExternalSymbolFiles.ps1} (93%) diff --git a/tools/Get-3rdPartySymbolFiles.ps1 b/tools/Get-ExternalSymbolFiles.ps1 similarity index 93% rename from tools/Get-3rdPartySymbolFiles.ps1 rename to tools/Get-ExternalSymbolFiles.ps1 index ef6bbef..5ad2a19 100644 --- a/tools/Get-3rdPartySymbolFiles.ps1 +++ b/tools/Get-ExternalSymbolFiles.ps1 @@ -79,11 +79,13 @@ Function Get-PackageVersion($id) { $version } -# All 3rd party packages for which symbols packages are expected should be listed here. +# All 1st party packages for which symbols packages are expected should be listed here. # These must all be sourced from nuget.org, as it is the only feed that supports symbol packages. -$3rdPartyPackageIds = @() +# We should NOT add 3rd party packages to this list because PDBs may be unsafe for our debuggers to load, +# so we should only archive 1st party symbols. +$1stPartyPackageIds = @() -$3rdPartyPackageIds | % { +$1stPartyPackageIds | % { $version = Get-PackageVersion $_ if ($version) { Get-SymbolsFromPackage -id $_ -version $version diff --git a/tools/artifacts/symbols.ps1 b/tools/artifacts/symbols.ps1 index b588267..91f83f0 100644 --- a/tools/artifacts/symbols.ps1 +++ b/tools/artifacts/symbols.ps1 @@ -1,10 +1,10 @@ $BinPath = [System.IO.Path]::GetFullPath("$PSScriptRoot/../../bin") -$3rdPartyPath = [System.IO.Path]::GetFullPath("$PSScriptRoot/../../obj/SymbolsPackages") +$ExternalPath = [System.IO.Path]::GetFullPath("$PSScriptRoot/../../obj/SymbolsPackages") if (!(Test-Path $BinPath)) { return } $symbolfiles = & "$PSScriptRoot/../Get-SymbolFiles.ps1" -Path $BinPath | Get-Unique -$3rdPartyFiles = & "$PSScriptRoot/../Get-3rdPartySymbolFiles.ps1" +$ExternalFiles = & "$PSScriptRoot/../Get-ExternalSymbolFiles.ps1" @{ "$BinPath" = $SymbolFiles; - "$3rdPartyPath" = $3rdPartyFiles; + "$ExternalPath" = $ExternalFiles; } From d1ffba297bb3b6d7b9a0ce0c6e996d28f0189085 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Fri, 24 Oct 2025 06:54:09 -0600 Subject: [PATCH 022/174] Fix template expansion after slnx rename --- Expand-Template.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Expand-Template.ps1 b/Expand-Template.ps1 index ae16231..c71e462 100755 --- a/Expand-Template.ps1 +++ b/Expand-Template.ps1 @@ -99,7 +99,7 @@ try { git config core.safecrlf false # Avoid warnings when adding files with mangled line endings # Rename project directories and solution - git mv Library.sln "$LibraryName.sln" + git mv Library.slnx "$LibraryName.slnx" if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } git mv src/Library/Library.csproj "src/Library/$LibraryName.csproj" if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } From b725deef78ecaa3a392d7b1042e6851af326d13a Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Fri, 24 Oct 2025 09:52:21 -0600 Subject: [PATCH 023/174] Another template expansion fix --- Expand-Template.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Expand-Template.ps1 b/Expand-Template.ps1 index c71e462..04cf503 100755 --- a/Expand-Template.ps1 +++ b/Expand-Template.ps1 @@ -119,7 +119,7 @@ try { if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } dotnet sln add "test/$LibraryName.Tests" if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - git add "$LibraryName.sln" + git add "$LibraryName.slnx" if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } # Update project reference in test project. Add before removal to keep the same ItemGroup in place. From cbf20ad05664311e9c7bc8e45bcccf78958b56c3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Oct 2025 16:01:39 +0000 Subject: [PATCH 024/174] Update dependency docfx to v2.78.4 (#429) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index c52d110..536052f 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -24,7 +24,7 @@ "rollForward": false }, "docfx": { - "version": "2.78.3", + "version": "2.78.4", "commands": [ "docfx" ], From 4ee59042346577d75dc6e81f567115d9182c8acb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Oct 2025 21:12:23 -0600 Subject: [PATCH 025/174] Update GitHub Artifact Actions Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/actions/publish-artifacts/action.yaml | 14 +++++++------- .github/workflows/release.yml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/actions/publish-artifacts/action.yaml b/.github/actions/publish-artifacts/action.yaml index 1f345fe..3b267f3 100644 --- a/.github/actions/publish-artifacts/action.yaml +++ b/.github/actions/publish-artifacts/action.yaml @@ -14,46 +14,46 @@ runs: - name: ๐Ÿ“ข Upload project.assets.json files if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 with: name: projectAssetsJson-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/projectAssetsJson continue-on-error: true - name: ๐Ÿ“ข Upload variables - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 with: name: variables-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/Variables continue-on-error: true - name: ๐Ÿ“ข Upload build_logs if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 with: name: build_logs-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/build_logs continue-on-error: true - name: ๐Ÿ“ข Upload testResults if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 with: name: testResults-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/testResults continue-on-error: true - name: ๐Ÿ“ข Upload coverageResults if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 with: name: coverageResults-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/coverageResults continue-on-error: true - name: ๐Ÿ“ข Upload symbols - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 with: name: symbols-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/symbols continue-on-error: true - name: ๐Ÿ“ข Upload deployables - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 with: name: deployables-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/deployables diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b84d907..ee4159b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,7 +57,7 @@ jobs: Echo "runid=$runid" >> $env:GITHUB_OUTPUT - name: ๐Ÿ”ป Download deployables artifacts - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5 + uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6 with: name: deployables-Linux path: ${{ runner.temp }}/deployables From 20dc055e095214d84947a77cb77bfae11ffe7d1e Mon Sep 17 00:00:00 2001 From: Sandy Armstrong Date: Wed, 29 Oct 2025 09:09:49 -0700 Subject: [PATCH 026/174] Increase retry count on NOTICE task failure to 10 We have seen this task fail as many as 9 times in a row. It has various issues and has recently been handed to a new team. Hopefully reliability will improve, but for now, it may be helpful to increase retries more broadly. --- azure-pipelines/microbuild.before.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines/microbuild.before.yml b/azure-pipelines/microbuild.before.yml index b169460..fd47d1b 100644 --- a/azure-pipelines/microbuild.before.yml +++ b/azure-pipelines/microbuild.before.yml @@ -23,7 +23,7 @@ steps: inputs: outputfile: $(System.DefaultWorkingDirectory)/obj/NOTICE outputformat: text - retryCountOnTaskFailure: 3 # fails when the cloud service is overloaded + retryCountOnTaskFailure: 10 # fails when the cloud service is overloaded continueOnError: ${{ not(parameters.RealSign) }} # Tolerate failures when we're not building something that may ship. - ${{ if parameters.IsOptProf }}: From fe333c17a9ee6c538907695905703cbd7fcea3d1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 2 Nov 2025 20:50:53 -0700 Subject: [PATCH 027/174] Update dependency xunit.v3 to 3.2.0 Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 91c1e03..6760e38 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -11,7 +11,7 @@ - + From ccb8e49efe28bf8939880cb01220e191bf712f99 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Nov 2025 15:45:22 +0000 Subject: [PATCH 028/174] Update nbgv and nerdbank.gitversioning updates to 3.9.50 Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- Directory.Packages.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 536052f..9f9de05 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -17,7 +17,7 @@ "rollForward": false }, "nbgv": { - "version": "3.8.118", + "version": "3.9.50", "commands": [ "nbgv" ], diff --git a/Directory.Packages.props b/Directory.Packages.props index 6760e38..78310fd 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -20,7 +20,7 @@ - + From 26a3acc0e34835e40614962ca3594b3d6e82d4c5 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 5 Nov 2025 13:40:10 -0700 Subject: [PATCH 029/174] Fix variable persistence when value includes a single quote --- tools/artifacts/Variables.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/artifacts/Variables.ps1 b/tools/artifacts/Variables.ps1 index 7a320c7..c4d9766 100644 --- a/tools/artifacts/Variables.ps1 +++ b/tools/artifacts/Variables.ps1 @@ -26,7 +26,7 @@ Get-ChildItem "$PSScriptRoot/../variables" |% { if ($value) { # We got something, so wrap it with quotes so it's treated like a literal value. - $value = "'$value'" + $value = "'" + $value.Replace("'", "''") + "'" } } From 17d786e15cfe285e84290df77c2d695721daa8c3 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sat, 8 Nov 2025 08:10:21 -0700 Subject: [PATCH 030/174] Drop redundant condition from YAML --- .github/workflows/docs_validate.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docs_validate.yml b/.github/workflows/docs_validate.yml index 7ac73e7..c3e76e5 100644 --- a/.github/workflows/docs_validate.yml +++ b/.github/workflows/docs_validate.yml @@ -27,4 +27,3 @@ jobs: shell: pwsh - name: ๐Ÿ“š Verify docfx build run: dotnet docfx docfx/docfx.json --warningsAsErrors --disableGitFeatures - if: runner.os == 'Linux' From d6be5cffe1ea7fbcc71f8f07b6ff1a3b62f65a40 Mon Sep 17 00:00:00 2001 From: trevors20 <49179298+trevors20@users.noreply.github.com> Date: Mon, 10 Nov 2025 12:08:36 -0800 Subject: [PATCH 031/174] Merge pull request 435 from trevors20/dev/trevors/microbuild/updateinsert251110 Add the VSDrop service connection to the insert vs payload --- azure-pipelines/OptProf.yml | 4 ++++ azure-pipelines/vs-insertion.yml | 5 +++++ azure-pipelines/vs-validation.yml | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/azure-pipelines/OptProf.yml b/azure-pipelines/OptProf.yml index a70b936..515e72a 100644 --- a/azure-pipelines/OptProf.yml +++ b/azure-pipelines/OptProf.yml @@ -97,6 +97,10 @@ stages: TeamEmail: $(TeamEmail) SkipCreatePR: true CustomScriptExecutionCommand: src\VSSDK\NuGet\AllowUnstablePackages.ps1 + ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}: + ConnectedVSDropServiceName: 'VSEng-VSDrop-MI' + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - task: benjhuser.tfs-extensions-build-tasks.trigger-build-task.TriggerBuild@3 displayName: Trigger a new build of DD-CB-TestSignVS-devCI inputs: diff --git a/azure-pipelines/vs-insertion.yml b/azure-pipelines/vs-insertion.yml index 71c9041..2899a6a 100644 --- a/azure-pipelines/vs-insertion.yml +++ b/azure-pipelines/vs-insertion.yml @@ -69,6 +69,11 @@ extends: AutoCompletePR: true AutoCompleteMergeStrategy: Squash ShallowClone: true + ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}: + ConnectedVSDropServiceName: 'VSEng-VSDrop-MI' + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + - powershell: | $contentType = 'application/json'; $headers = @{ Authorization = 'Bearer $(System.AccessToken)' }; diff --git a/azure-pipelines/vs-validation.yml b/azure-pipelines/vs-validation.yml index b6c79ab..bd6a0aa 100644 --- a/azure-pipelines/vs-validation.yml +++ b/azure-pipelines/vs-validation.yml @@ -111,6 +111,10 @@ extends: DraftPR: false # set to true and update InsertionBuildPolicy when we can specify all the validations we want to run (https://dev.azure.com/devdiv/DevDiv/_workitems/edit/2224288) AutoCompletePR: false ShallowClone: true + ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}: + ConnectedVSDropServiceName: 'VSEng-VSDrop-MI' + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - powershell: | $insertionPRId = azure-pipelines/Get-InsertionPRId.ps1 $Markdown = @" From 74d3a45218a42251990819333ce3470b4a2b6fdd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Nov 2025 06:04:00 -0800 Subject: [PATCH 032/174] Update dependency Microsoft.NET.Test.Sdk to 18.0.1 Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 78310fd..c0924a5 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -9,7 +9,7 @@ - + From aaccf733763ee03b1b0458fafaaf2d1739537a77 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 11 Nov 2025 15:02:09 -0700 Subject: [PATCH 033/174] Build with the .NET 10 SDK --- .devcontainer/Dockerfile | 2 +- Directory.Build.props | 1 + global.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index f988758..de69782 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:9.0.306-noble@sha256:d88e637d15248531967111fba05c6725ad45ea1dace3d35d8cfe2c4d4094e25d +FROM mcr.microsoft.com/dotnet/sdk:10.0.100 # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. diff --git a/Directory.Build.props b/Directory.Build.props index 02d4180..e1e9ee7 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -12,6 +12,7 @@ true true true + true true diff --git a/global.json b/global.json index cfaecd0..895d51b 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.306", + "version": "10.0.100", "rollForward": "patch", "allowPrerelease": false } From adb7870d664a6215b965398d549c3c9a84df8fd9 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 11 Nov 2025 15:23:14 -0700 Subject: [PATCH 034/174] Adapt to breaking .NET 10 SDK change Workaround for https://github.com/dotnet/sdk/issues/51666 --- Expand-Template.ps1 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Expand-Template.ps1 b/Expand-Template.ps1 index 04cf503..5b08d84 100755 --- a/Expand-Template.ps1 +++ b/Expand-Template.ps1 @@ -110,6 +110,14 @@ try { git mv test/Library.Tests "test/$LibraryName.Tests" if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + # Update project reference in test project. Add before removal to keep the same ItemGroup in place. + dotnet add "test/$LibraryName.Tests" reference "src/$LibraryName" + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + dotnet remove "test/$LibraryName.Tests" reference src/Library/Library.csproj + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + git add "test/$LibraryName.Tests/$LibraryName.Tests.csproj" + if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } + # Refresh solution file both to update paths and give the projects unique GUIDs dotnet sln remove src/Library/Library.csproj if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } @@ -122,14 +130,6 @@ try { git add "$LibraryName.slnx" if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - # Update project reference in test project. Add before removal to keep the same ItemGroup in place. - dotnet add "test/$LibraryName.Tests" reference "src/$LibraryName" - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - dotnet remove "test/$LibraryName.Tests" reference src/Library/Library.csproj - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - git add "test/$LibraryName.Tests/$LibraryName.Tests.csproj" - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - # Establish a new strong-name key & $sn.Path -k 2048 strongname.snk if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } From 4a6f64196cdffe0b3d5a1dd8da1a836d9e9fd824 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 11 Nov 2025 20:15:45 -0700 Subject: [PATCH 035/174] Fix ARM64 detection on macOS --- tools/Install-DotNetSdk.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/Install-DotNetSdk.ps1 b/tools/Install-DotNetSdk.ps1 index 402b430..3d13e81 100644 --- a/tools/Install-DotNetSdk.ps1 +++ b/tools/Install-DotNetSdk.ps1 @@ -197,7 +197,7 @@ if ($InstallLocality -eq 'machine') { $restartRequired = $false $sdks |% { if ($_.Version) { $version = $_.Version } else { $version = $_.Channel } - if ($PSCmdlet.ShouldProcess(".NET SDK $_", "Install")) { + if ($PSCmdlet.ShouldProcess(".NET SDK $version ($arch)", "Install")) { Install-DotNet -Version $version -Architecture $arch $restartRequired = $restartRequired -or ($LASTEXITCODE -eq 3010) @@ -281,10 +281,10 @@ if ($IncludeX86) { } if ($IsMacOS -or $IsLinux) { - $DownloadUri = "https://raw.githubusercontent.com/dotnet/install-scripts/0b09de9bc136cacb5f849a6957ebd4062173c148/src/dotnet-install.sh" + $DownloadUri = "https://raw.githubusercontent.com/dotnet/install-scripts/a3fbd0fd625032bac207f1f590e5353fe26faa59/src/dotnet-install.sh" $DotNetInstallScriptPath = "$DotNetInstallScriptRoot/dotnet-install.sh" } else { - $DownloadUri = "https://raw.githubusercontent.com/dotnet/install-scripts/0b09de9bc136cacb5f849a6957ebd4062173c148/src/dotnet-install.ps1" + $DownloadUri = "https://raw.githubusercontent.com/dotnet/install-scripts/a3fbd0fd625032bac207f1f590e5353fe26faa59/src/dotnet-install.ps1" $DotNetInstallScriptPath = "$DotNetInstallScriptRoot/dotnet-install.ps1" } @@ -306,7 +306,7 @@ $global:LASTEXITCODE = 0 $sdks |% { if ($_.Version) { $parameters = '-Version', $_.Version } else { $parameters = '-Channel', $_.Channel } - if ($PSCmdlet.ShouldProcess(".NET SDK $_", "Install")) { + if ($PSCmdlet.ShouldProcess(".NET SDK $_ ($arch)", "Install")) { $anythingInstalled = $true Invoke-Expression -Command "$DotNetInstallScriptPathExpression $parameters -Architecture $arch -InstallDir $DotNetInstallDir $switches" From e1aa37c4508bd87df71cf503dedd78fe839a7eb9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 12 Nov 2025 03:58:26 +0000 Subject: [PATCH 036/174] Pin mcr.microsoft.com/dotnet/sdk Docker tag to c7445f1 Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index de69782..6637ad8 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.100 +FROM mcr.microsoft.com/dotnet/sdk:10.0.100@sha256:c7445f141c04f1a6b454181bd098dcfa606c61ba0bd213d0a702489e5bd4cd71 # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. From ed20107e2ccdd1842353ecc0bf108f9ae4fc5824 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 12 Nov 2025 07:04:29 -0700 Subject: [PATCH 037/174] Bump C# language version to 14 --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index e1e9ee7..a3d5fb8 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -44,7 +44,7 @@ - 13 + 14 16.9 From c8fa88850cc7bf314a2f07bdf217cb60dafc3ec1 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 17 Nov 2025 11:07:53 -0700 Subject: [PATCH 038/174] Drop `auto-insertion` tag handling Now that official and unofficial pipelines are distinct, there's no real reason to avoid triggering an insertion with every official build. --- azure-pipelines/build.yml | 3 --- azure-pipelines/schedule-only-steps.yml | 3 --- azure-pipelines/vs-insertion.yml | 1 - 3 files changed, 7 deletions(-) delete mode 100644 azure-pipelines/schedule-only-steps.yml diff --git a/azure-pipelines/build.yml b/azure-pipelines/build.yml index 078cb83..86d11fe 100644 --- a/azure-pipelines/build.yml +++ b/azure-pipelines/build.yml @@ -194,9 +194,6 @@ jobs: - powershell: Write-Host "##vso[task.setvariable variable=PROFILINGINPUTSDROPNAME]$(tools/variables/ProfilingInputsDropName.ps1)" displayName: โš™ Set ProfilingInputsDropName for optprof - - ${{ if eq(variables['Build.Reason'], 'Schedule') }}: - - template: schedule-only-steps.yml - - template: install-dependencies.yml - script: dotnet nbgv cloud -ca diff --git a/azure-pipelines/schedule-only-steps.yml b/azure-pipelines/schedule-only-steps.yml deleted file mode 100644 index ad07a34..0000000 --- a/azure-pipelines/schedule-only-steps.yml +++ /dev/null @@ -1,3 +0,0 @@ -steps: -- powershell: echo "##vso[build.addbuildtag]auto-insertion" - displayName: Tag for auto-insertion diff --git a/azure-pipelines/vs-insertion.yml b/azure-pipelines/vs-insertion.yml index 2899a6a..bb5332e 100644 --- a/azure-pipelines/vs-insertion.yml +++ b/azure-pipelines/vs-insertion.yml @@ -15,7 +15,6 @@ resources: trigger: tags: - Real signed - - auto-insertion variables: - template: GlobalVariables.yml From e95eb88acf602a6c46a2720650f0e2509cf542f3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 17 Nov 2025 12:28:49 -0700 Subject: [PATCH 039/174] Update actions/checkout digest to 93cb6ef Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/copilot-setup-steps.yml | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/libtemplate-update.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 717342e..f290509 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,7 +29,7 @@ jobs: - windows-2022 steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites @@ -74,7 +74,7 @@ jobs: name: ๐Ÿ“ƒ Docs runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - name: ๐Ÿ”— Markup Link Checker (mlc) uses: becheran/mlc@18a06b3aa2901ca197de59c8b0b1f54fdba6b3fa # v1.0.0 with: diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index eb69d92..52dfafa 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -26,7 +26,7 @@ jobs: # You can define any steps you want, and they will run before the agent starts. # If you do not check out your code, Copilot will do this for you. steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a7155c4..d784263 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -24,7 +24,7 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/libtemplate-update.yml b/.github/workflows/libtemplate-update.yml index f5cf866..1f64e09 100644 --- a/.github/workflows/libtemplate-update.yml +++ b/.github/workflows/libtemplate-update.yml @@ -17,7 +17,7 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. From 91ee72eba1eed6090d83d93f0dcba4bd53ac655f Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 17 Nov 2025 14:40:18 -0700 Subject: [PATCH 040/174] Replace hard-coded codecov_token with secrets/variables --- .github/workflows/build.yml | 7 ++++--- Expand-Template.ps1 | 10 ---------- azure-pipelines.yml | 1 - azure-pipelines/dotnet.yml | 7 +++++-- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f290509..5c06d5d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,6 @@ on: env: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true BUILDCONFIGURATION: Release - # codecov_token: 4dc9e7e2-6b01-4932-a180-847b52b43d35 # Get a new one from https://codecov.io/ NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages/ jobs: @@ -64,11 +63,13 @@ jobs: uses: ./.github/actions/publish-artifacts if: cancelled() == false - name: ๐Ÿ“ข Publish code coverage results to codecov.io - run: ./tools/publish-CodeCov.ps1 -CodeCovToken "${{ env.codecov_token }}" -PathToCodeCoverage "${{ runner.temp }}/_artifacts/coverageResults" -Name "${{ runner.os }} Coverage Results" -Flags "${{ runner.os }}" + run: | + if ('${{ secrets.CODECOV_TOKEN }}') { + ./tools/publish-CodeCov.ps1 -CodeCovToken '${{ secrets.CODECOV_TOKEN }}' -PathToCodeCoverage "${{ runner.temp }}/_artifacts/coverageResults" -Name "${{ runner.os }} Coverage Results" -Flags "${{ runner.os }}" + } shell: pwsh timeout-minutes: 3 continue-on-error: true - if: env.codecov_token != '' docs: name: ๐Ÿ“ƒ Docs diff --git a/Expand-Template.ps1 b/Expand-Template.ps1 index 5b08d84..39bbd2c 100755 --- a/Expand-Template.ps1 +++ b/Expand-Template.ps1 @@ -7,9 +7,6 @@ Expands this template into an actual project, taking values for placeholders The name of the library. Should consist only of alphanumeric characters and periods. .PARAMETER Author The name to use in copyright and owner notices. -.PARAMETER CodeCovToken -A token obtained from codecov.io for your repo. If not specified, code coverage results will not be published to codecov.io, -but can be added later by editing the Azure Pipelines YAML file. .PARAMETER CIFeed The `/{guid}` path to the Azure Pipelines artifact feed to push your nuget package to as part of your CI. .PARAMETER Squash @@ -22,8 +19,6 @@ Param( [Parameter(Mandatory=$true)] [string]$Author, [Parameter()] - [string]$CodeCovToken, - [Parameter()] [string]$CIFeed, [Parameter()] [switch]$Squash @@ -179,11 +174,6 @@ try { } $YmlReplacements = @{} - if ($CodeCovToken) { - $YmlReplacements['(codecov_token: ).*(#.*)'] = "`$1$CodeCovToken" - } else { - $YmlReplacements['(codecov_token: ).*(#.*)'] = "#`$1`$2" - } if ($CIFeed) { $YmlReplacements['(ci_feed: ).*(#.*)'] = "`$1$CIFeed" } else { diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 4d372fe..8c2ddec 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -26,7 +26,6 @@ parameters: variables: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true BuildConfiguration: Release - codecov_token: 4dc9e7e2-6b01-4932-a180-847b52b43d35 # Get a new one from https://codecov.io/ ci_feed: https://pkgs.dev.azure.com/andrewarnott/_packaging/CI/nuget/v3/index.json # Azure Artifacts feed URL NUGET_PACKAGES: $(Agent.TempDirectory)/.nuget/packages/ diff --git a/azure-pipelines/dotnet.yml b/azure-pipelines/dotnet.yml index 30bb410..9a572af 100644 --- a/azure-pipelines/dotnet.yml +++ b/azure-pipelines/dotnet.yml @@ -20,11 +20,14 @@ steps: displayName: ๐Ÿ“ข Publish artifacts condition: succeededOrFailed() -- ${{ if and(ne(variables['codecov_token'], ''), parameters.RunTests) }}: +- ${{ if parameters.RunTests }}: - powershell: | $ArtifactStagingFolder = & "tools/Get-ArtifactsStagingDirectory.ps1" $CoverageResultsFolder = Join-Path $ArtifactStagingFolder "coverageResults-$(Agent.JobName)" - tools/publish-CodeCov.ps1 -CodeCovToken "$(codecov_token)" -PathToCodeCoverage "$CoverageResultsFolder" -Name "$(Agent.JobName) Coverage Results" -Flags "$(Agent.JobName)" + tools/publish-CodeCov.ps1 -CodeCovToken "$(CODECOV_TOKEN)" -PathToCodeCoverage "$CoverageResultsFolder" -Name "$(Agent.JobName) Coverage Results" -Flags "$(Agent.JobName)" displayName: ๐Ÿ“ข Publish code coverage results to codecov.io timeoutInMinutes: 3 continueOnError: true + # Set the CODECOV_TOKEN variable in your Azure Pipeline to enable code coverage reporting + # Get a token from https://codecov.io/ + condition: and(succeeded(), ne(variables['CODECOV_TOKEN'], '')) From 32a3cdd0dbc5773b67517f9b97b86c42198f4cbb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 20 Nov 2025 21:13:36 +0000 Subject: [PATCH 041/174] Update actions/checkout action to v6 (443) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/copilot-setup-steps.yml | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/libtemplate-update.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5c06d5d..376a52f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ jobs: - windows-2022 steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites @@ -75,7 +75,7 @@ jobs: name: ๐Ÿ“ƒ Docs runs-on: ubuntu-latest steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 - name: ๐Ÿ”— Markup Link Checker (mlc) uses: becheran/mlc@18a06b3aa2901ca197de59c8b0b1f54fdba6b3fa # v1.0.0 with: diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 52dfafa..8bbf7b0 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -26,7 +26,7 @@ jobs: # You can define any steps you want, and they will run before the agent starts. # If you do not check out your code, Copilot will do this for you. steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d784263..28313d1 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -24,7 +24,7 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/libtemplate-update.yml b/.github/workflows/libtemplate-update.yml index 1f64e09..f7d0b54 100644 --- a/.github/workflows/libtemplate-update.yml +++ b/.github/workflows/libtemplate-update.yml @@ -17,7 +17,7 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. From 585a2dfec55c77a7fa62afe086ac131ad93187fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Fri, 21 Nov 2025 15:44:28 +0100 Subject: [PATCH 042/174] Use official URLs in Install-DotNetSdk.ps1 The blob storage URLs will stop working, see https://github.com/dotnet/announcements/issues/336 --- tools/Install-DotNetSdk.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/Install-DotNetSdk.ps1 b/tools/Install-DotNetSdk.ps1 index 3d13e81..590581e 100644 --- a/tools/Install-DotNetSdk.ps1 +++ b/tools/Install-DotNetSdk.ps1 @@ -125,14 +125,14 @@ Function Get-InstallerExe( } if ($TypedVersion.Build -eq -1) { - $versionInfo = -Split (Invoke-WebRequest -Uri "https://dotnetcli.blob.core.windows.net/dotnet/$sku/$Version/latest.version" -UseBasicParsing) + $versionInfo = -Split (Invoke-WebRequest -Uri "https://builds.dotnet.microsoft.com/dotnet/$sku/$Version/latest.version" -UseBasicParsing) $Version = $versionInfo[-1] } $majorMinor = "$($TypedVersion.Major).$($TypedVersion.Minor)" $ReleasesFile = Join-Path $DotNetInstallScriptRoot "$majorMinor\releases.json" if (!(Test-Path $ReleasesFile)) { - Get-FileFromWeb -Uri "https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/$majorMinor/releases.json" -OutDir (Split-Path $ReleasesFile) | Out-Null + Get-FileFromWeb -Uri "https://builds.dotnet.microsoft.com/dotnet/release-metadata/$majorMinor/releases.json" -OutDir (Split-Path $ReleasesFile) | Out-Null } $releases = Get-Content $ReleasesFile | ConvertFrom-Json From 1439223d98460542839efa8c8c9c19a011c72e98 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 28 Nov 2025 18:34:34 -0700 Subject: [PATCH 043/174] Update dependency xunit.v3 to 3.2.1 (445) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index c0924a5..d4cbbbb 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -11,7 +11,7 @@ - + From 5a412a0c542cd02716f3c9e1460e6b98c63cdb69 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 1 Dec 2025 18:25:17 -0700 Subject: [PATCH 044/174] Switch out our own OptProf profiling pipeline for the VS one --- azure-pipelines/OptProf.yml | 125 -------- azure-pipelines/OptProf_part2.yml | 91 ------ azure-pipelines/build.yml | 269 +++++++++--------- azure-pipelines/dotnet.yml | 14 +- azure-pipelines/microbuild.after.yml | 21 -- azure-pipelines/microbuild.before.yml | 28 +- azure-pipelines/vs-insertion-script.ps1 | 17 ++ azure-pipelines/vs-insertion.yml | 1 + azure-pipelines/vs-validation.yml | 2 +- src/OptProf.targets | 8 +- .../Library.VSInsertionMetadata.proj | 11 - src/VSInsertionMetadata/ProfilingInputs.props | 5 - .../VSInsertionMetadata.targets | 71 ----- tools/artifacts/VSInsertion.ps1 | 12 +- tools/variables/ProfilingInputsPropsName.ps1 | 6 + 15 files changed, 176 insertions(+), 505 deletions(-) delete mode 100644 azure-pipelines/OptProf.yml delete mode 100644 azure-pipelines/OptProf_part2.yml create mode 100644 azure-pipelines/vs-insertion-script.ps1 delete mode 100644 src/VSInsertionMetadata/Library.VSInsertionMetadata.proj delete mode 100644 src/VSInsertionMetadata/ProfilingInputs.props delete mode 100644 src/VSInsertionMetadata/VSInsertionMetadata.targets create mode 100644 tools/variables/ProfilingInputsPropsName.ps1 diff --git a/azure-pipelines/OptProf.yml b/azure-pipelines/OptProf.yml deleted file mode 100644 index 515e72a..0000000 --- a/azure-pipelines/OptProf.yml +++ /dev/null @@ -1,125 +0,0 @@ -trigger: none -pr: none -schedules: -- cron: "0 3 * * Fri" # Thu @ 8 or 9 PM Mountain Time (depending on DST) - displayName: Weekly OptProf run - branches: - include: - - 'v*.*' - - main - always: true # we must keep data fresh since optimizationdata drops are purged after 30 days - -# Avoid errant CI builds: https://developercommunity.visualstudio.com/content/problem/1154409/azure-pipeline-is-triggering-due-to-events-that-ne.html -#resources: -# repositories: -# - repository: scripts -# type: git -# name: DeploymentScripts -# ref: refs/heads/test - -parameters: - - name: ShouldSkipOptimize - displayName: Skip OptProf optimization - type: boolean - default: false # Should usually be false so that optprof LKG can apply when tests fail, but may need to be set to true in a manually queued pipeline run if all drops have expired. - -variables: -- template: GlobalVariables.yml -- name: PublicRelease - value: false # avoid using nice version since we're building a preliminary/unoptimized package -- name: IsOptProf - value: true -- name: MicroBuild_NuPkgSigningEnabled - value: false # test-signed nuget packages fail to restore in the VS insertion PR validations. Just don't sign them *at all*. - -stages: -- stage: Library - variables: - - name: OptProf - value: true - - template: BuildStageVariables.yml - jobs: - - template: build.yml - parameters: - Is1ESPT: false - RealSign: false - windowsPool: VSEngSS-MicroBuild2022-1ES - EnableMacOSBuild: false - ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }} - IsOptProf: true - RunTests: false - SkipCodesignVerify: true -- stage: QueueVSBuild - jobs: - - job: QueueOptProf - pool: VSEngSS-MicroBuild2022-1ES - variables: - InsertPayloadName: LibraryName - InsertTopicBranch: team/VS-IDE/LibraryName-OptProf-run-$(Build.BuildId) - steps: - - checkout: none # We don't need source from our own repo - clean: true - - # Pipeline YAML does not yet support checking out other repos. So we'll do it by hand. -# - checkout: scripts # We DO need source from the DeploymentScripts repo -# clean: true -# path: $(Agent.TempDirectory)/DeploymentScripts -# fetchDepth: 1 - - script: 'git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" clone https://devdiv.visualstudio.com/DevDiv/_git/DeploymentScripts --depth 1 --branch test "$(Agent.TempDirectory)/DeploymentScripts"' - displayName: Download DeploymentScripts repo - - - task: DownloadBuildArtifacts@0 - displayName: Download insertion artifacts - inputs: - artifactName: VSInsertion-Windows - downloadPath: $(Agent.TempDirectory) - - task: DownloadBuildArtifacts@0 - displayName: Download variables artifacts - inputs: - artifactName: Variables-Windows - downloadPath: $(Agent.TempDirectory) - - task: PowerShell@2 - displayName: Set pipeline variables based on artifacts - inputs: - targetType: filePath - filePath: $(Agent.TempDirectory)/Variables-Windows/_define.ps1 - - task: NuGetCommand@2 - displayName: Push VS-repo packages to VS feed - inputs: - command: push - packagesToPush: $(Agent.TempDirectory)/VSInsertion-Windows/*.nupkg - publishVstsFeed: 97a41293-2972-4f48-8c0e-05493ae82010 # VS feed - allowPackageConflicts: true - - task: MicroBuildInsertVsPayload@5 - displayName: Insert VS Payload - inputs: - TeamName: $(TeamName) - TeamEmail: $(TeamEmail) - SkipCreatePR: true - CustomScriptExecutionCommand: src\VSSDK\NuGet\AllowUnstablePackages.ps1 - ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}: - ConnectedVSDropServiceName: 'VSEng-VSDrop-MI' - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - - task: benjhuser.tfs-extensions-build-tasks.trigger-build-task.TriggerBuild@3 - displayName: Trigger a new build of DD-CB-TestSignVS-devCI - inputs: - buildDefinition: DD-CB-TestSignVS-devCI - useSameBranch: false - branchToUse: $(InsertTopicBranch) - storeInEnvironmentVariable: true - queueBuildForUserThatTriggeredBuild: false - authenticationMethod: OAuth Token - password: $(System.AccessToken) - - task: PowerShell@2 - displayName: Associate InsertionOutputs artifacts with CloudBuild - inputs: - targetType: filePath - filePath: $(Agent.TempDirectory)/DeploymentScripts/Scripts/Insertion/WriteArtifact.ps1 - arguments: '-oldBuildID $(Build.BuildId) -newBuildID $(TriggeredBuildIds) -artifactName "InsertionOutputs" -accessToken $(System.AccessToken)' - - task: PowerShell@2 - displayName: Tag the build with LibraryName-insertion - inputs: - targetType: filePath - filePath: $(Agent.TempDirectory)/DeploymentScripts/Scripts/Insertion/TagBuild.ps1 - arguments: '-buildID $(TriggeredBuildIds) -tagName "LibraryName-insertion" -accessToken $(System.AccessToken)' diff --git a/azure-pipelines/OptProf_part2.yml b/azure-pipelines/OptProf_part2.yml deleted file mode 100644 index c59d699..0000000 --- a/azure-pipelines/OptProf_part2.yml +++ /dev/null @@ -1,91 +0,0 @@ -trigger: none -pr: none - -resources: - pipelines: - - pipeline: VisualStudioBuildUnderTest - source: DD-CB-TestSignVS-devCI - trigger: - tags: - - LibraryName-insertion - - pipeline: DartLab - source: DartLab - branch: main - - pipeline: DartLab.OptProf - source: DartLab.OptProf - branch: main - tags: - - production - repositories: - - repository: DartLabTemplates - type: git - name: DartLab.Templates - ref: refs/heads/main - - repository: DartLabOptProfTemplates - type: git - name: DartLab.OptProf - ref: refs/tags/Production - -parameters: - -# The prefix naming of the OptimizationInputs drop -- name: optimizationDropPrefix - type: string - default: OptimizationInputs/$(System.TeamProject)/$(Build.Repository.Name) - -stages: -- template: \templates\stages\visual-studio\single-runsettings.yml@DartLabOptProfTemplates - parameters: - ##### Required ##### - runSettingsURI: $(Pipeline.Workspace)\VisualStudioBuildUnderTest\BuildArtifacts\runsettings\LibraryName.OptProf.runsettings - visualStudioBootstrapperURI: https://vsdrop.corp.microsoft.com/file/v1/$(VisualStudio.BuildUnderTest.ProductsDropName);bootstrappers/Enterprise/vs_enterprise.exe - ##### Optional ##### - name: OptProfProfilingWorkflow - displayName: OptProf Profiling Workflow - optOptimizationInputsDropName: $(OptimizationInputsDropName) - previousOptimizationInputsDropName: $(PreviousOptimizationInputsDropName) - testLabPoolName: VS-Platform - ##### Step Hooks ##### - preTestMachineConfigurationStepList: - - download: VisualStudioBuildUnderTest - - task: PowerShell@2 - name: SetProductsDropName - displayName: Set 'VisualStudio.BuildUnderTest.ProductsDropName' - inputs: - filePath: $(DartLab.Path)\Scripts\VisualStudio\Build\Get-VisualStudioDropName.ps1 - arguments: -DropNamePrefix 'Products' -VstsDropUrlsJson '$(Pipeline.Workspace)\VisualStudioBuildUnderTest\BuildArtifacts\VstsDropUrls.json' -OutVariableName 'VisualStudio.BuildUnderTest.ProductsDropName' - preDeployAndRunTestsStepList: - - download: VisualStudioBuildUnderTest - prePublishOptimizationInputsDropStepList: - # Set parameter for PreviousOptimizationInputsDropName, MicroBuildCommitID, and OptimizationInputsDropName - - powershell: | - try { - $artifactName = 'InsertionOutputs' - $BuildID = $(resources.pipeline.VisualStudioBuildUnderTest.runID) - $artifact = Get-BuildArtifact -InstanceURL 'https://dev.azure.com/devdiv' -ProjectName 'DevDiv' -BuildID $BuildID -ArtifactName $artifactName -OAuthAccessToken (ConvertTo-SecureString '$(System.AccessToken)' -AsPlainText -Force) - $containerName = $artifact.Resource.Data -Split '/' | Select-Object -Last 1 - $fileName = Join-Path $containerName 'Metadata.json' - $jsonString = Read-BuildArtifactFile -InstanceURL 'https://dev.azure.com/devdiv' -ProjectName 'DevDiv' -BuildID $BuildID -ArtifactName $artifactName -FileName $fileName -OAuthAccessToken (ConvertTo-SecureString '$(System.AccessToken)' -AsPlainText -Force) - $json = $jsonString | ConvertFrom-Json - - Write-Host "The content of the metadata.json file was $json" - - $dropname = $json.OptimizationData - $commitID = $json.CommitID - $OptimizationInputsDropName = "${{parameters.optimizationDropPrefix}}/$($commitID)/$(Build.BuildId)/$(System.StageId)/$(System.StageAttempt)" - - Write-Host "PreviousOptimizationInputsDropName: $dropname" - Set-AzurePipelinesVariable 'PreviousOptimizationInputsDropName' $dropname - - Write-Host "MicroBuildCommitID: $commitID" - Set-AzurePipelinesVariable 'MicroBuildCommitID' $commitID - - Write-Host "OptimizationInputsDropName: $OptimizationInputsDropName" - Set-AzurePipelinesVariable 'OptimizationInputsDropName' $OptimizationInputsDropName - } - catch { - Write-Host $_ - Write-Error "Failed to set OptimizationInputsDropName pipeline variable" - throw - } - displayName: Set MicroBuildCommitID, PreviousOptimizationInputsDropName, and OptimizationInputsDropName diff --git a/azure-pipelines/build.yml b/azure-pipelines/build.yml index 86d11fe..a1f64b8 100644 --- a/azure-pipelines/build.yml +++ b/azure-pipelines/build.yml @@ -69,12 +69,6 @@ parameters: type: boolean default: false -# Whether this particular run is an OptProf profiling run. -# This is used to skip unit tests and other non-essential work to improve reliability of the OptProf pipeline. -- name: IsOptProf - type: boolean - default: false - - name: RunTests type: boolean default: true @@ -139,8 +133,11 @@ jobs: optprof: enabled: ${{ parameters.EnableOptProf }} ProfilingInputsDropName: $(ProfilingInputsDropName) - OptimizationInputsLookupMethod: DropPrefix - DropNamePrefix: OptimizationInputs/$(System.TeamProject)/$(Build.Repository.Name) + GeneratePropsFile: true + PropsPath: $(Build.ArtifactStagingDirectory)/InsertionOutputs/$(ProfilingInputsPropsName) + OptimizationInputsLookupMethod: GitTagRepo + GitTagProject: DevDiv + GitTagRepo: VS ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }} AccessToken: $(System.AccessToken) mbpresteps: @@ -148,8 +145,10 @@ jobs: fetchDepth: 0 # avoid shallow clone so nbgv can do its work. clean: true - ${{ if parameters.EnableOptProf }}: - - powershell: Write-Host "##vso[task.setvariable variable=PROFILINGINPUTSDROPNAME]$(tools/variables/ProfilingInputsDropName.ps1)" - displayName: โš™ Set ProfilingInputsDropName for optprof + - powershell: | + Write-Host "##vso[task.setvariable variable=PROFILINGINPUTSDROPNAME]$(tools/variables/ProfilingInputsDropName.ps1)" + Write-Host "##vso[task.setvariable variable=PROFILINGINPUTSPROPSNAME]$(tools/variables/ProfilingInputsPropsName.ps1)" + displayName: โš™ Setting variables for optprof sdl: binskim: analyzeTargetGlob: $(Build.ArtifactStagingDirectory)\symbols-Windows\** @@ -185,6 +184,15 @@ jobs: displayName: ๐Ÿ“ข Publish APIScanInputs targetPath: $(Build.ArtifactStagingDirectory)/APIScanInputs-Windows artifactName: APIScanInputs + - ${{ if parameters.EnableOptProf }}: + - output: artifactsDrop + displayName: ๐Ÿ“ข Publish to Artifact Services - ProfilingInputs + dropServiceURI: https://devdiv.artifacts.visualstudio.com + buildNumber: $(ProfilingInputsDropName) + sourcePath: $(Build.ArtifactStagingDirectory)\OptProf\ProfilingInputs + toLowerCase: false + retentionDays: 500 + condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) steps: - ${{ if not(parameters.Is1ESPT) }}: - checkout: self @@ -204,7 +212,6 @@ jobs: - template: microbuild.before.yml parameters: EnableLocalization: ${{ parameters.EnableLocalization }} - IsOptProf: ${{ parameters.IsOptProf }} ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }} RealSign: ${{ parameters.RealSign }} @@ -212,7 +219,6 @@ jobs: parameters: Is1ESPT: ${{ parameters.Is1ESPT }} RunTests: ${{ parameters.RunTests }} - IsOptProf: ${{ parameters.IsOptProf }} - ${{ if and(parameters.EnableDotNetFormatCheck, not(parameters.EnableLinuxBuild)) }}: - script: dotnet format --verify-no-changes @@ -223,142 +229,139 @@ jobs: - ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}: - template: microbuild.after.yml parameters: - IsOptProf: ${{ parameters.IsOptProf }} SkipCodesignVerify: ${{ parameters.SkipCodesignVerify }} - template: expand-template.yml +- ${{ if parameters.EnableLinuxBuild }}: + - job: Linux + pool: ${{ parameters.linuxPool }} + ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}: + templateContext: + mb: + ${{ if parameters.RealSign }}: + signing: + enabled: false # enable when building unique artifacts on this agent that must be signed + signType: real + signWithProd: true + outputParentDirectory: $(Build.ArtifactStagingDirectory) + outputs: + - ${{ each artifact in parameters.artifact_names }}: + - ${{ if or(ne(artifact.testOnly, 'true'), parameters.RunTests) }}: + - output: pipelineArtifact + displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-Linux + targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-Linux + artifactName: ${{ artifact.name }}-Linux + ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: + sbomEnabled: true + - output: pipelineArtifact + displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-Linux (for failed attempts) + targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-Linux + artifactName: ${{ artifact.name }}-Linux-$(System.PhaseAttempt) + ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: + sbomEnabled: true + condition: failed() + steps: + - checkout: self + fetchDepth: 0 # avoid shallow clone so nbgv can do its work. + clean: true + - template: install-dependencies.yml + - template: dotnet.yml + parameters: + Is1ESPT: ${{ parameters.Is1ESPT }} + RunTests: ${{ parameters.RunTests }} + BuildRequiresAccessToken: ${{ parameters.RealSign }} # Real signing on non-Windows machines requires passing through access token to build steps that sign + - ${{ if parameters.EnableDotNetFormatCheck }}: + - script: dotnet format --verify-no-changes + displayName: ๐Ÿ’… Verify formatted code + env: + dotnetformat: true # part of a workaround for https://github.com/dotnet/sdk/issues/44951 + - template: expand-template.yml -- ${{ if not(parameters.IsOptProf) }}: - - ${{ if parameters.EnableLinuxBuild }}: - - job: Linux - pool: ${{ parameters.linuxPool }} - ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}: - templateContext: - mb: - ${{ if parameters.RealSign }}: - signing: - enabled: false # enable when building unique artifacts on this agent that must be signed - signType: real - signWithProd: true - outputParentDirectory: $(Build.ArtifactStagingDirectory) - outputs: - - ${{ each artifact in parameters.artifact_names }}: - - ${{ if or(ne(artifact.testOnly, 'true'), parameters.RunTests) }}: - - output: pipelineArtifact - displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-Linux - targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-Linux - artifactName: ${{ artifact.name }}-Linux - ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: - sbomEnabled: true - - output: pipelineArtifact - displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-Linux (for failed attempts) - targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-Linux - artifactName: ${{ artifact.name }}-Linux-$(System.PhaseAttempt) - ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: - sbomEnabled: true - condition: failed() - steps: - - checkout: self - fetchDepth: 0 # avoid shallow clone so nbgv can do its work. - clean: true - - template: install-dependencies.yml - - template: dotnet.yml - parameters: - Is1ESPT: ${{ parameters.Is1ESPT }} - RunTests: ${{ parameters.RunTests }} - BuildRequiresAccessToken: ${{ parameters.RealSign }} # Real signing on non-Windows machines requires passing through access token to build steps that sign - - ${{ if parameters.EnableDotNetFormatCheck }}: - - script: dotnet format --verify-no-changes - displayName: ๐Ÿ’… Verify formatted code - env: - dotnetformat: true # part of a workaround for https://github.com/dotnet/sdk/issues/44951 - - template: expand-template.yml - - - ${{ if parameters.EnableMacOSBuild }}: - - job: macOS - pool: ${{ parameters.macOSPool }} - ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}: - templateContext: - mb: - ${{ if parameters.RealSign }}: - signing: - enabled: false # enable when building unique artifacts on this agent that must be signed - signType: real - signWithProd: true - outputParentDirectory: $(Build.ArtifactStagingDirectory) - outputs: - - ${{ each artifact in parameters.artifact_names }}: - - ${{ if or(ne(artifact.testOnly, 'true'), parameters.RunTests) }}: - - output: pipelineArtifact - displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-macOS - targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-macOS - artifactName: ${{ artifact.name }}-macOS - ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: - sbomEnabled: true - - output: pipelineArtifact - displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-macOS (for failed attempts) - targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-macOS - artifactName: ${{ artifact.name }}-macOS-$(System.PhaseAttempt) - ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: - sbomEnabled: true - condition: failed() - steps: - - checkout: self - fetchDepth: 0 # avoid shallow clone so nbgv can do its work. - clean: true - - template: install-dependencies.yml - - template: dotnet.yml - parameters: - Is1ESPT: ${{ parameters.Is1ESPT }} - RunTests: ${{ parameters.RunTests }} - BuildRequiresAccessToken: ${{ parameters.RealSign }} # Real signing on non-Windows machines requires passing through access token to build steps that sign - - template: expand-template.yml - - - job: WrapUp - dependsOn: - - Windows - - ${{ if parameters.EnableLinuxBuild }}: - - Linux - - ${{ if parameters.EnableMacOSBuild }}: - - macOS - pool: ${{ parameters.windowsPool }} # Use Windows agent because PublishSymbols task requires it (https://github.com/microsoft/azure-pipelines-tasks/issues/13821). - condition: succeededOrFailed() - variables: - ONEES_ENFORCED_CODEQL_ENABLED: false # CodeQL runs on build jobs, we don't need it here +- ${{ if parameters.EnableMacOSBuild }}: + - job: macOS + pool: ${{ parameters.macOSPool }} ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}: templateContext: - ${{ if not(parameters.RealSign) }}: - mb: - signing: # if the build is test-signed, install the signing plugin so that CSVTestSignPolicy.xml is available - enabled: true - zipSources: false - signType: test + mb: + ${{ if parameters.RealSign }}: + signing: + enabled: false # enable when building unique artifacts on this agent that must be signed + signType: real + signWithProd: true outputParentDirectory: $(Build.ArtifactStagingDirectory) outputs: - - output: pipelineArtifact - displayName: ๐Ÿ“ข Publish symbols-legacy - targetPath: $(Build.ArtifactStagingDirectory)/symbols-legacy - artifactName: symbols-legacy - condition: succeededOrFailed() + - ${{ each artifact in parameters.artifact_names }}: + - ${{ if or(ne(artifact.testOnly, 'true'), parameters.RunTests) }}: + - output: pipelineArtifact + displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-macOS + targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-macOS + artifactName: ${{ artifact.name }}-macOS + ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: + sbomEnabled: true + - output: pipelineArtifact + displayName: ๐Ÿ“ข Publish ${{ artifact.name }}-macOS (for failed attempts) + targetPath: $(Build.ArtifactStagingDirectory)/${{ artifact.name }}-macOS + artifactName: ${{ artifact.name }}-macOS-$(System.PhaseAttempt) + ${{ if and(parameters.Is1ESPTOfficial, eq(artifact.sbomEnabled, 'true')) }}: + sbomEnabled: true + condition: failed() steps: - checkout: self fetchDepth: 0 # avoid shallow clone so nbgv can do its work. clean: true - template: install-dependencies.yml + - template: dotnet.yml parameters: - initArgs: -NoRestore - - template: publish-symbols.yml + Is1ESPT: ${{ parameters.Is1ESPT }} + RunTests: ${{ parameters.RunTests }} + BuildRequiresAccessToken: ${{ parameters.RealSign }} # Real signing on non-Windows machines requires passing through access token to build steps that sign + - template: expand-template.yml + +- job: WrapUp + dependsOn: + - Windows + - ${{ if parameters.EnableLinuxBuild }}: + - Linux + - ${{ if parameters.EnableMacOSBuild }}: + - macOS + pool: ${{ parameters.windowsPool }} # Use Windows agent because PublishSymbols task requires it (https://github.com/microsoft/azure-pipelines-tasks/issues/13821). + condition: succeededOrFailed() + variables: + ONEES_ENFORCED_CODEQL_ENABLED: false # CodeQL runs on build jobs, we don't need it here + ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}: + templateContext: + ${{ if not(parameters.RealSign) }}: + mb: + signing: # if the build is test-signed, install the signing plugin so that CSVTestSignPolicy.xml is available + enabled: true + zipSources: false + signType: test + outputParentDirectory: $(Build.ArtifactStagingDirectory) + outputs: + - output: pipelineArtifact + displayName: ๐Ÿ“ข Publish symbols-legacy + targetPath: $(Build.ArtifactStagingDirectory)/symbols-legacy + artifactName: symbols-legacy + condition: succeededOrFailed() + steps: + - checkout: self + fetchDepth: 0 # avoid shallow clone so nbgv can do its work. + clean: true + - template: install-dependencies.yml + parameters: + initArgs: -NoRestore + - template: publish-symbols.yml + parameters: + EnableLinuxBuild: ${{ parameters.EnableLinuxBuild }} + EnableMacOSBuild: ${{ parameters.EnableMacOSBuild }} + - ${{ if and(parameters.RunTests, parameters.PublishCodeCoverage) }}: + - template: publish-codecoverage.yml parameters: EnableLinuxBuild: ${{ parameters.EnableLinuxBuild }} EnableMacOSBuild: ${{ parameters.EnableMacOSBuild }} - - ${{ if and(parameters.RunTests, parameters.PublishCodeCoverage) }}: - - template: publish-codecoverage.yml - parameters: - EnableLinuxBuild: ${{ parameters.EnableLinuxBuild }} - EnableMacOSBuild: ${{ parameters.EnableMacOSBuild }} - - ${{ if parameters.EnableAPIScan }}: - - template: apiscan.yml - parameters: - windowsPool: ${{ parameters.windowsPool }} - RealSign: ${{ parameters.RealSign }} +- ${{ if parameters.EnableAPIScan }}: + - template: apiscan.yml + parameters: + windowsPool: ${{ parameters.windowsPool }} + RealSign: ${{ parameters.RealSign }} diff --git a/azure-pipelines/dotnet.yml b/azure-pipelines/dotnet.yml index b1f7625..b67b4a6 100644 --- a/azure-pipelines/dotnet.yml +++ b/azure-pipelines/dotnet.yml @@ -1,8 +1,5 @@ parameters: - name: RunTests -- name: IsOptProf - type: boolean - default: false - name: Is1ESPT type: boolean - name: BuildRequiresAccessToken @@ -17,14 +14,9 @@ steps: env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) -- ${{ if not(parameters.IsOptProf) }}: - - powershell: tools/dotnet-test-cloud.ps1 -Configuration $(BuildConfiguration) -Agent $(Agent.JobName) -PublishResults - displayName: ๐Ÿงช dotnet test - condition: and(succeeded(), ${{ parameters.RunTests }}) - -- ${{ if parameters.IsOptProf }}: - - script: dotnet pack src\VSInsertionMetadata -c $(BuildConfiguration) -warnaserror /bl:"$(Build.ArtifactStagingDirectory)/build_logs/VSInsertion-Pack.binlog" - displayName: ๐Ÿ”ง dotnet pack VSInsertionMetadata +- powershell: tools/dotnet-test-cloud.ps1 -Configuration $(BuildConfiguration) -Agent $(Agent.JobName) -PublishResults + displayName: ๐Ÿงช dotnet test + condition: and(succeeded(), ${{ parameters.RunTests }}) - powershell: tools/variables/_define.ps1 failOnStderr: true diff --git a/azure-pipelines/microbuild.after.yml b/azure-pipelines/microbuild.after.yml index 67ba900..c0e1e7b 100644 --- a/azure-pipelines/microbuild.after.yml +++ b/azure-pipelines/microbuild.after.yml @@ -1,7 +1,4 @@ parameters: -- name: IsOptProf - type: boolean - default: false - name: SkipCodesignVerify type: boolean @@ -15,21 +12,3 @@ steps: TargetFolders: | $(Build.SourcesDirectory)/bin/Packages/$(BuildConfiguration) condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT')) - -- ${{ if parameters.IsOptProf }}: - - task: ms-vscs-artifact.build-tasks.artifactDropTask-1.artifactDropTask@0 - inputs: - dropServiceURI: https://devdiv.artifacts.visualstudio.com - buildNumber: $(ProfilingInputsDropName) - sourcePath: $(Build.ArtifactStagingDirectory)\OptProf\ProfilingInputs - toLowerCase: false - usePat: true - displayName: ๐Ÿ“ข Publish to Artifact Services - ProfilingInputs - condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) - - - task: PublishBuildArtifacts@1 - inputs: - PathtoPublish: $(Build.ArtifactStagingDirectory)/InsertionOutputs - ArtifactName: InsertionOutputs - ArtifactType: Container - displayName: ๐Ÿ“ข Publish InsertionOutputs as Azure DevOps artifacts diff --git a/azure-pipelines/microbuild.before.yml b/azure-pipelines/microbuild.before.yml index fd47d1b..2982353 100644 --- a/azure-pipelines/microbuild.before.yml +++ b/azure-pipelines/microbuild.before.yml @@ -2,9 +2,6 @@ parameters: - name: EnableLocalization type: boolean default: false -- name: IsOptProf - type: boolean - default: false - name: ShouldSkipOptimize type: boolean default: false @@ -12,7 +9,7 @@ parameters: type: boolean steps: -- ${{ if and(not(parameters.IsOptProf), ne(variables['Build.Reason'], 'PullRequest')) }}: +- ${{ if ne(variables['Build.Reason'], 'PullRequest') }}: # notice@0 requires CG detection to run first, and non-default branches don't inject it automatically. # default branch injection (main) is happening too late for notice@0 to run successfully. Adding this as a workaround. - task: ComponentGovernanceComponentDetection@0 @@ -25,26 +22,3 @@ steps: outputformat: text retryCountOnTaskFailure: 10 # fails when the cloud service is overloaded continueOnError: ${{ not(parameters.RealSign) }} # Tolerate failures when we're not building something that may ship. - -- ${{ if parameters.IsOptProf }}: - # We have to install these plugins ourselves for Optprof runs because those pipelines haven't migrated to 1ES PT yet. - - task: MicroBuildOptProfPlugin@6 - inputs: - ProfilingInputsDropName: $(ProfilingInputsDropName) - OptimizationInputsLookupMethod: DropPrefix - DropNamePrefix: OptimizationInputs/$(System.TeamProject)/$(Build.Repository.Name) - ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }} - AccessToken: $(System.AccessToken) - displayName: ๐Ÿ”ง Install OptProf Plugin - - - task: MicroBuildSigningPlugin@4 - inputs: - signType: Test - zipSources: false - displayName: ๐Ÿ”ง Install MicroBuild Signing Plugin - - - ${{ if parameters.EnableLocalization }}: - - task: MicroBuildLocalizationPlugin@4 - inputs: - languages: $(LocLanguages) - displayName: ๐Ÿ”ง Install MicroBuild Localization Plugin diff --git a/azure-pipelines/vs-insertion-script.ps1 b/azure-pipelines/vs-insertion-script.ps1 new file mode 100644 index 0000000..5307625 --- /dev/null +++ b/azure-pipelines/vs-insertion-script.ps1 @@ -0,0 +1,17 @@ +# List of build artifact files [Source => Destination] to be committed into the VS repo. +$FilesToCommit = @{ + "$env:PROFILINGINPUTSPROPSNAME" = "src/Tests/config/runsettings/Official/OptProf/External/$env:PROFILINGINPUTSPROPSNAME"; +} + +foreach ($File in $FilesToCommit.GetEnumerator()) { + $SourcePath = Join-Path $PSScriptRoot $File.Key + if (Test-Path $SourcePath) { + $DestinationPath = Join-Path (Get-Location) $File.Value + Write-Host "Copying $SourcePath to $DestinationPath" + Copy-Item -Path $SourcePath -Destination $DestinationPath + git add $DestinationPath + } + else { + Write-Host "$SourcePath is not present, skipping" + } +} diff --git a/azure-pipelines/vs-insertion.yml b/azure-pipelines/vs-insertion.yml index bb5332e..e9cb178 100644 --- a/azure-pipelines/vs-insertion.yml +++ b/azure-pipelines/vs-insertion.yml @@ -65,6 +65,7 @@ extends: InsertionPayloadName: $(Build.Repository.Name) $(Build.BuildNumber) InsertionBuildPolicies: Request Perf DDRITs InsertionReviewers: $(Build.RequestedFor) # Append `,Your team name` (without quotes) + CustomScriptExecutionCommand: $(Pipeline.Workspace)\CI\VSInsertion-Windows\vs-insertion-script.ps1 AutoCompletePR: true AutoCompleteMergeStrategy: Squash ShallowClone: true diff --git a/azure-pipelines/vs-validation.yml b/azure-pipelines/vs-validation.yml index bd6a0aa..c03fdaa 100644 --- a/azure-pipelines/vs-validation.yml +++ b/azure-pipelines/vs-validation.yml @@ -105,7 +105,7 @@ extends: InsertionPayloadName: $(Build.Repository.Name) VALIDATION BUILD $(Build.BuildNumber) ($(Build.SourceBranch)) [Skip-SymbolCheck] [Skip-HashCheck] [Skip-SignCheck] InsertionDescription: | This PR is for **validation purposes only** for !$(System.PullRequest.PullRequestId). **Do not complete**. - CustomScriptExecutionCommand: src/VSSDK/NuGet/AllowUnstablePackages.ps1 + CustomScriptExecutionCommand: $(Pipeline.Workspace)\VSInsertion-Windows\vs-insertion-script.ps1; src\VSSDK\NuGet\AllowUnstablePackages.ps1 InsertionBuildPolicies: Request Perf DDRITs InsertionReviewers: $(Build.RequestedFor) DraftPR: false # set to true and update InsertionBuildPolicy when we can specify all the validations we want to run (https://dev.azure.com/devdiv/DevDiv/_workitems/edit/2224288) diff --git a/src/OptProf.targets b/src/OptProf.targets index d0167d7..0757df2 100644 --- a/src/OptProf.targets +++ b/src/OptProf.targets @@ -2,14 +2,12 @@ IBC - Common7\IDE\PrivateAssemblies\$(TargetFileName) + Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.Threading.17.x\$(TargetFileName) /ExeConfig:"%VisualStudio.InstallationUnderTest.Path%\Common7\IDE\vsn.exe" - - - + + - diff --git a/src/VSInsertionMetadata/Library.VSInsertionMetadata.proj b/src/VSInsertionMetadata/Library.VSInsertionMetadata.proj deleted file mode 100644 index 0caaedb..0000000 --- a/src/VSInsertionMetadata/Library.VSInsertionMetadata.proj +++ /dev/null @@ -1,11 +0,0 @@ - - - netstandard2.0 - true - $(RepoRootPath)bin\Packages\$(Configuration)\VSRepo\ - false - false - Contains metadata for insertion into VS. - - - diff --git a/src/VSInsertionMetadata/ProfilingInputs.props b/src/VSInsertionMetadata/ProfilingInputs.props deleted file mode 100644 index fb19d60..0000000 --- a/src/VSInsertionMetadata/ProfilingInputs.props +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/VSInsertionMetadata/VSInsertionMetadata.targets b/src/VSInsertionMetadata/VSInsertionMetadata.targets deleted file mode 100644 index 84ebb5a..0000000 --- a/src/VSInsertionMetadata/VSInsertionMetadata.targets +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - $(TargetsForTfmSpecificContentInPackage); - SubstituteProfilingInputsMacro; - - - - - - - - - - - - - - - - - - - - - - $(PackageVersion).$(Build_BuildId) - - - - - - diff --git a/tools/artifacts/VSInsertion.ps1 b/tools/artifacts/VSInsertion.ps1 index a5b940b..700b24f 100644 --- a/tools/artifacts/VSInsertion.ps1 +++ b/tools/artifacts/VSInsertion.ps1 @@ -19,6 +19,10 @@ if (!$BuildConfiguration) { $PackagesRoot = "$RepoRoot/bin/Packages/$BuildConfiguration" $NuGetPackages = "$PackagesRoot/NuGet" $VsixPackages = "$PackagesRoot/Vsix" +$AzurePipelinesPath = "$RepoRoot/azure-pipelines" +if ($env:BUILD_ARTIFACTSTAGINGDIRECTORY) { + $InsertionOutputs = "$env:BUILD_ARTIFACTSTAGINGDIRECTORY/InsertionOutputs" +} if (!(Test-Path $NuGetPackages) -and !(Test-Path $VsixPackages)) { Write-Warning "Skipping because NuGet and VSIX packages haven't been built yet." @@ -26,16 +30,16 @@ if (!(Test-Path $NuGetPackages) -and !(Test-Path $VsixPackages)) { } $result = @{ - "$NuGetPackages" = (Get-ChildItem $NuGetPackages -Recurse) + "$AzurePipelinesPath" = (Get-ChildItem "$AzurePipelinesPath/vs-insertion-script.ps1"); + "$NuGetPackages" = (Get-ChildItem $NuGetPackages -Recurse); } if (Test-Path $VsixPackages) { $result["$PackagesRoot"] += Get-ChildItem $VsixPackages -Recurse } -if ($env:IsOptProf) { - $VSRepoPackages = "$PackagesRoot/VSRepo" - $result["$VSRepoPackages"] = (Get-ChildItem "$VSRepoPackages\*.VSInsertionMetadata.*.nupkg"); +if ($InsertionOutputs -and $env:PROFILINGINPUTSPROPSNAME -and (Test-Path "$InsertionOutputs/$env:PROFILINGINPUTSPROPSNAME")) { + $result[$InsertionOutputs] = (Get-ChildItem "$InsertionOutputs/$env:PROFILINGINPUTSPROPSNAME"); # OptProf ProfilingInputs } $result diff --git a/tools/variables/ProfilingInputsPropsName.ps1 b/tools/variables/ProfilingInputsPropsName.ps1 new file mode 100644 index 0000000..e66cce0 --- /dev/null +++ b/tools/variables/ProfilingInputsPropsName.ps1 @@ -0,0 +1,6 @@ +if ($env:SYSTEM_TEAMPROJECT) { + $repoName = $env:BUILD_REPOSITORY_NAME.Replace('/', '.') + "$env:SYSTEM_TEAMPROJECT.$repoName.props" +} else { + Write-Warning "No Azure Pipelines build detected. No Azure Pipelines drop name will be computed." +} From a23eb8db15455b3dd935f85bca1eb71a86aef416 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 2 Dec 2025 10:38:04 -0700 Subject: [PATCH 045/174] Merge pull request 447 to Build on newer agents --- .github/workflows/build.yml | 6 +++--- Expand-Template.ps1 | 2 +- azure-pipelines/build.yml | 6 +++--- azure-pipelines/expand-template.yml | 12 ++++++++++++ 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 376a52f..b379610 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,9 +23,9 @@ jobs: fail-fast: false matrix: os: - - ubuntu-22.04 - - macos-14 - - windows-2022 + - ubuntu-24.04 + - macOS-15 + - windows-2025 steps: - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 diff --git a/Expand-Template.ps1 b/Expand-Template.ps1 index 39bbd2c..568ee79 100755 --- a/Expand-Template.ps1 +++ b/Expand-Template.ps1 @@ -52,7 +52,7 @@ function Replace-Placeholders { $sn = Get-Command sn -ErrorAction SilentlyContinue if (-not $sn) { if ($IsMacOS -or $IsLinux) { - Write-Error "sn command not found on PATH. Install mono and/or vote up this issue: https://github.com/dotnet/sdk/issues/13560" + Write-Error 'sn command not found on PATH. Install mono, use "sudo apt-get install strong-name-tool" and/or vote up this issue: https://github.com/dotnet/sdk/issues/13560' exit(1) } $snExes = Get-ChildItem -Recurse "${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\sn.exe" diff --git a/azure-pipelines/build.yml b/azure-pipelines/build.yml index 5c106ad..7d808ed 100644 --- a/azure-pipelines/build.yml +++ b/azure-pipelines/build.yml @@ -2,7 +2,7 @@ parameters: - name: windowsPool type: object default: - vmImage: windows-2022 + vmImage: windows-2025 - name: includeMacOS type: boolean - name: RunTests @@ -28,7 +28,7 @@ jobs: - job: Linux pool: - vmImage: Ubuntu-22.04 + vmImage: ubuntu-24.04 steps: - checkout: self fetchDepth: 0 # avoid shallow clone so nbgv can do its work. @@ -46,7 +46,7 @@ jobs: - job: macOS condition: ${{ parameters.includeMacOS }} pool: - vmImage: macOS-14 + vmImage: macOS-15 steps: - checkout: self fetchDepth: 0 # avoid shallow clone so nbgv can do its work. diff --git a/azure-pipelines/expand-template.yml b/azure-pipelines/expand-template.yml index d843f1e..3f4897b 100644 --- a/azure-pipelines/expand-template.yml +++ b/azure-pipelines/expand-template.yml @@ -6,6 +6,18 @@ steps: - powershell: | git config user.name "test user" git config user.email "andrewarnott@gmail.com" + if ($IsLinux) { + Write-Host "##[group]strong-name-tool installation" + Write-Host "##[command]sudo apt-get install strong-name-tool" + sudo apt-get install strong-name-tool 2>&1 + Write-Host "##[endgroup]" + } + if ($IsMacOS) { + Write-Host "##[group]mono installation" + Write-Host "##[command]brew install mono" + brew install mono 2>&1 + Write-Host "##[endgroup]" + } ./Expand-Template.ps1 -LibraryName Calc -Author "Andrew Arnott" displayName: ๐Ÿงช Expanding template failOnStderr: true From 064bff7e1380cbfab683d3d424b3360b4d6c2395 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 17:45:23 +0000 Subject: [PATCH 046/174] Update actions/checkout digest to 8e8c483 (448) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/copilot-setup-steps.yml | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/libtemplate-update.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b379610..11a8eb3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ jobs: - windows-2025 steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites @@ -75,7 +75,7 @@ jobs: name: ๐Ÿ“ƒ Docs runs-on: ubuntu-latest steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - name: ๐Ÿ”— Markup Link Checker (mlc) uses: becheran/mlc@18a06b3aa2901ca197de59c8b0b1f54fdba6b3fa # v1.0.0 with: diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 8bbf7b0..6a88e0c 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -26,7 +26,7 @@ jobs: # You can define any steps you want, and they will run before the agent starts. # If you do not check out your code, Copilot will do this for you. steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 28313d1..adeffee 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -24,7 +24,7 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/libtemplate-update.yml b/.github/workflows/libtemplate-update.yml index f7d0b54..800279b 100644 --- a/.github/workflows/libtemplate-update.yml +++ b/.github/workflows/libtemplate-update.yml @@ -17,7 +17,7 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. From 35aa4d135f4050acec3a35cab0cf57a1512faad5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 17:50:00 +0000 Subject: [PATCH 047/174] Update actions/checkout digest --- .github/workflows/copilot-setup-steps.yml | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/docs_validate.yml | 2 +- .github/workflows/libtemplate-update.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 8bbf7b0..6a88e0c 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -26,7 +26,7 @@ jobs: # You can define any steps you want, and they will run before the agent starts. # If you do not check out your code, Copilot will do this for you. steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 28313d1..adeffee 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -24,7 +24,7 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/docs_validate.yml b/.github/workflows/docs_validate.yml index c3e76e5..ad00d50 100644 --- a/.github/workflows/docs_validate.yml +++ b/.github/workflows/docs_validate.yml @@ -13,7 +13,7 @@ jobs: name: ๐Ÿ“š Doc validation runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: ๐Ÿ”— Markup Link Checker (mlc) diff --git a/.github/workflows/libtemplate-update.yml b/.github/workflows/libtemplate-update.yml index f7d0b54..800279b 100644 --- a/.github/workflows/libtemplate-update.yml +++ b/.github/workflows/libtemplate-update.yml @@ -17,7 +17,7 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. From 498462f89919dfd07cfad1ab6f1edbdc39d2ccc2 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 2 Dec 2025 12:48:51 -0700 Subject: [PATCH 048/174] Build on VS2026 agents --- azure-pipelines/OptProf.yml | 4 ++-- azure-pipelines/archive-sourcecode.yml | 2 +- azure-pipelines/official.yml | 4 ++-- azure-pipelines/prepare-insertion-stages.yml | 2 +- azure-pipelines/release.yml | 2 +- azure-pipelines/unofficial.yml | 4 ++-- azure-pipelines/vs-insertion.yml | 4 ++-- azure-pipelines/vs-validation.yml | 6 +++--- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/azure-pipelines/OptProf.yml b/azure-pipelines/OptProf.yml index 515e72a..cc3df69 100644 --- a/azure-pipelines/OptProf.yml +++ b/azure-pipelines/OptProf.yml @@ -43,7 +43,7 @@ stages: parameters: Is1ESPT: false RealSign: false - windowsPool: VSEngSS-MicroBuild2022-1ES + windowsPool: VSEng-MicroBuildVSStable EnableMacOSBuild: false ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }} IsOptProf: true @@ -52,7 +52,7 @@ stages: - stage: QueueVSBuild jobs: - job: QueueOptProf - pool: VSEngSS-MicroBuild2022-1ES + pool: VSEng-MicroBuildVSStable variables: InsertPayloadName: LibraryName InsertTopicBranch: team/VS-IDE/LibraryName-OptProf-run-$(Build.BuildId) diff --git a/azure-pipelines/archive-sourcecode.yml b/azure-pipelines/archive-sourcecode.yml index 7f35de4..ee349e5 100644 --- a/azure-pipelines/archive-sourcecode.yml +++ b/azure-pipelines/archive-sourcecode.yml @@ -38,7 +38,7 @@ extends: settings: networkIsolationPolicy: Permissive,CFSClean sdl: - sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES + sourceAnalysisPool: VSEng-MicroBuildVSStable stages: - stage: archive diff --git a/azure-pipelines/official.yml b/azure-pipelines/official.yml index d5571b0..1171838 100644 --- a/azure-pipelines/official.yml +++ b/azure-pipelines/official.yml @@ -48,7 +48,7 @@ extends: settings: networkIsolationPolicy: Permissive,CFSClean sdl: - sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES + sourceAnalysisPool: VSEng-MicroBuildVSStable codeSignValidation: enabled: true break: true @@ -72,7 +72,7 @@ extends: RealSign: true # ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }} EnableAPIScan: ${{ parameters.EnableAPIScan }} - windowsPool: VSEngSS-MicroBuild2022-1ES + windowsPool: VSEng-MicroBuildVSStable linuxPool: name: AzurePipelines-EO demands: diff --git a/azure-pipelines/prepare-insertion-stages.yml b/azure-pipelines/prepare-insertion-stages.yml index fdce906..9f934f9 100644 --- a/azure-pipelines/prepare-insertion-stages.yml +++ b/azure-pipelines/prepare-insertion-stages.yml @@ -17,7 +17,7 @@ stages: - ${{ if parameters.ArchiveSymbols }}: - job: symbol_archive displayName: Archive symbols - pool: VSEngSS-MicroBuild2022-1ES + pool: VSEng-MicroBuildVSStable variables: ONEES_ENFORCED_CODEQL_ENABLED: false # CodeQL runs on build stages, we don't need it here steps: diff --git a/azure-pipelines/release.yml b/azure-pipelines/release.yml index aea1a2d..38e9a3b 100644 --- a/azure-pipelines/release.yml +++ b/azure-pipelines/release.yml @@ -23,7 +23,7 @@ extends: settings: networkIsolationPolicy: Permissive,CFSClean sdl: - sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES + sourceAnalysisPool: VSEng-MicroBuildVSStable stages: - stage: release diff --git a/azure-pipelines/unofficial.yml b/azure-pipelines/unofficial.yml index 5796f78..64905a8 100644 --- a/azure-pipelines/unofficial.yml +++ b/azure-pipelines/unofficial.yml @@ -58,7 +58,7 @@ extends: settings: networkIsolationPolicy: Permissive,CFSClean sdl: - sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES + sourceAnalysisPool: VSEng-MicroBuildVSStable credscan: enabled: false suppression: @@ -85,7 +85,7 @@ extends: RealSign: false # ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }} EnableAPIScan: ${{ parameters.EnableAPIScan }} - windowsPool: VSEngSS-MicroBuild2022-1ES + windowsPool: VSEng-MicroBuildVSStable linuxPool: name: AzurePipelines-EO demands: diff --git a/azure-pipelines/vs-insertion.yml b/azure-pipelines/vs-insertion.yml index bb5332e..e4a4424 100644 --- a/azure-pipelines/vs-insertion.yml +++ b/azure-pipelines/vs-insertion.yml @@ -25,14 +25,14 @@ extends: settings: networkIsolationPolicy: Permissive,CFSClean sdl: - sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES + sourceAnalysisPool: VSEng-MicroBuildVSStable stages: - stage: insertion jobs: - job: insertion displayName: VS insertion - pool: VSEngSS-MicroBuild2022-1ES + pool: VSEng-MicroBuildVSStable templateContext: outputParentDirectory: $(Pipeline.Workspace)/CI steps: diff --git a/azure-pipelines/vs-validation.yml b/azure-pipelines/vs-validation.yml index 92f84cc..a553455 100644 --- a/azure-pipelines/vs-validation.yml +++ b/azure-pipelines/vs-validation.yml @@ -29,7 +29,7 @@ extends: settings: networkIsolationPolicy: Permissive,CFSClean sdl: - sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES + sourceAnalysisPool: VSEng-MicroBuildVSStable credscan: enabled: false @@ -46,7 +46,7 @@ extends: Is1ESPT: true RealSign: false # ShouldSkipOptimize: ${{ parameters.ShouldSkipOptimize }} - windowsPool: VSEngSS-MicroBuild2022-1ES + windowsPool: VSEng-MicroBuildVSStable linuxPool: name: AzurePipelines-EO demands: @@ -70,7 +70,7 @@ extends: jobs: - job: insertion displayName: VS insertion - pool: VSEngSS-MicroBuild2022-1ES + pool: VSEng-MicroBuildVSStable steps: - checkout: self clean: true From 26355f20e7a52cbe38e81f7d98e3cf040df04275 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 2 Dec 2025 15:21:37 -0700 Subject: [PATCH 049/174] Better pinning of GitHub Actions --- .github/renovate.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/renovate.json b/.github/renovate.json index c8b723c..c97d977 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,6 +1,6 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": ["config:best-practices"], + "extends": ["config:best-practices","helpers:pinGitHubActionDigestsToSemver"], "labels": ["dependencies"], "packageRules": [ { From 5ded58b1970014c5e40a1495936d9f0f4c69f24c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 22:28:28 +0000 Subject: [PATCH 050/174] Update actions/checkout action to v6.0.1 (449) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/copilot-setup-steps.yml | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/libtemplate-update.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 11a8eb3..b3aa05b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ jobs: - windows-2025 steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites @@ -75,7 +75,7 @@ jobs: name: ๐Ÿ“ƒ Docs runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: ๐Ÿ”— Markup Link Checker (mlc) uses: becheran/mlc@18a06b3aa2901ca197de59c8b0b1f54fdba6b3fa # v1.0.0 with: diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 6a88e0c..ebd5388 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -26,7 +26,7 @@ jobs: # You can define any steps you want, and they will run before the agent starts. # If you do not check out your code, Copilot will do this for you. steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index adeffee..f7ed808 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -24,7 +24,7 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/libtemplate-update.yml b/.github/workflows/libtemplate-update.yml index 800279b..0b111a6 100644 --- a/.github/workflows/libtemplate-update.yml +++ b/.github/workflows/libtemplate-update.yml @@ -17,7 +17,7 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. From 4548135503611f9115cc961e4ec643cfafc8ba0c Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 2 Dec 2025 13:28:02 -0700 Subject: [PATCH 051/174] Exclude `vs-insertion-script.ps1` from signing requirement --- azure-pipelines/official.yml | 2 +- azure-pipelines/unofficial.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines/official.yml b/azure-pipelines/official.yml index 5404962..5c14d14 100644 --- a/azure-pipelines/official.yml +++ b/azure-pipelines/official.yml @@ -52,7 +52,7 @@ extends: codeSignValidation: enabled: true break: true - additionalTargetsGlobPattern: -|Variables-*\*.ps1;-|LocBin-*\**;-|APIScanInputs-*\**;-|test_symbols-*\**;-|MicroBuild\** + additionalTargetsGlobPattern: -|Variables-*\*.ps1;-|LocBin-*\**;-|APIScanInputs-*\**;-|test_symbols-*\**;-|MicroBuild\**;-|$(Build.ArtifactStagingDirectory)\VSInsertion-Windows\vs-insertion-script.ps1 policheck: enabled: true exclusionsFile: $(System.DefaultWorkingDirectory)\azure-pipelines\PoliCheckExclusions.xml diff --git a/azure-pipelines/unofficial.yml b/azure-pipelines/unofficial.yml index bc2e88e..6097512 100644 --- a/azure-pipelines/unofficial.yml +++ b/azure-pipelines/unofficial.yml @@ -67,7 +67,7 @@ extends: codeSignValidation: enabled: ${{ parameters.EnableProductionSDL }} break: true - additionalTargetsGlobPattern: -|Variables-*\*.ps1;-|APIScanInputs-*\**;-|test_symbols-*\**;-|MicroBuild\** + additionalTargetsGlobPattern: -|Variables-*\*.ps1;-|APIScanInputs-*\**;-|test_symbols-*\**;-|MicroBuild\**;-|$(Build.ArtifactStagingDirectory)\VSInsertion-Windows\vs-insertion-script.ps1 policyFile: $(MBSIGN_APPFOLDER)\CSVTestSignPolicy.xml policheck: enabled: ${{ parameters.EnableProductionSDL }} From 9a6d7453fe7dcf3370fff0bdb86ba5ee0bc50082 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 22:33:00 +0000 Subject: [PATCH 052/174] Update actions/deploy-pages action to v4.0.5 (450) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index f7ed808..b1ba568 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -40,4 +40,4 @@ jobs: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4 + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 From 5beff9213afc4fda78fb7189fdb2d1d46d7b9f5c Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 2 Dec 2025 18:21:32 -0700 Subject: [PATCH 053/174] Skip SBOM generation for the vs-insertion pipeline --- azure-pipelines/vs-insertion.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/azure-pipelines/vs-insertion.yml b/azure-pipelines/vs-insertion.yml index bb5332e..068580c 100644 --- a/azure-pipelines/vs-insertion.yml +++ b/azure-pipelines/vs-insertion.yml @@ -26,6 +26,8 @@ extends: networkIsolationPolicy: Permissive,CFSClean sdl: sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES + sbom: + enabled: false stages: - stage: insertion From 89853ca1fd7e0c5839eac2071952e1770d23073f Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 2 Dec 2025 18:21:56 -0700 Subject: [PATCH 054/174] Remove stray backtick from README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0c1a00..aa2dfb5 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Further customize your repo by: ### Maintaining your repo based on this template The best way to keep your repo in sync with this template's evolving features and best practices is to periodically merge the template into your repo: -` + ```ps1 git fetch git checkout origin/main From 40019588499960f7d5bc54e44bfd784f65f601bf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 19:57:52 -0700 Subject: [PATCH 055/174] Update NuGet/login action to v1.1.0 (451) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ee4159b..d2495c1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -76,7 +76,7 @@ jobs: } - name: ๐Ÿชช Authorize NuGet package push - uses: NuGet/login@d22cc5f58ff5b88bf9bd452535b4335137e24544 # v1 + uses: NuGet/login@d22cc5f58ff5b88bf9bd452535b4335137e24544 # v1.1.0 id: nuget-login with: user: ${{ secrets.NUGET_USER }} From b09c6e5524c0767461d10daa5b077d22db4033c9 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 3 Dec 2025 17:02:42 -0700 Subject: [PATCH 056/174] Remove vs-threading specific change --- src/OptProf.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OptProf.targets b/src/OptProf.targets index 0757df2..b99753b 100644 --- a/src/OptProf.targets +++ b/src/OptProf.targets @@ -2,7 +2,7 @@ IBC - Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.Threading.17.x\$(TargetFileName) + Common7\IDE\PrivateAssemblies\$(TargetFileName) /ExeConfig:"%VisualStudio.InstallationUnderTest.Path%\Common7\IDE\vsn.exe" From fe54aae7537439698e7f9ce02e5b596ad3019880 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 3 Dec 2025 17:16:47 -0700 Subject: [PATCH 057/174] Remove stale comment --- src/OptProf.targets | 1 - 1 file changed, 1 deletion(-) diff --git a/src/OptProf.targets b/src/OptProf.targets index b99753b..0b6cc92 100644 --- a/src/OptProf.targets +++ b/src/OptProf.targets @@ -6,7 +6,6 @@ /ExeConfig:"%VisualStudio.InstallationUnderTest.Path%\Common7\IDE\vsn.exe" - From 397e3e9f01c7b986b84a5aced50fc32c000f1869 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Dec 2025 03:36:38 +0000 Subject: [PATCH 058/174] Update actions/checkout action to v6.0.1 --- .github/workflows/copilot-setup-steps.yml | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/docs_validate.yml | 2 +- .github/workflows/libtemplate-update.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 6a88e0c..ebd5388 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -26,7 +26,7 @@ jobs: # You can define any steps you want, and they will run before the agent starts. # If you do not check out your code, Copilot will do this for you. steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index adeffee..f7ed808 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -24,7 +24,7 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/docs_validate.yml b/.github/workflows/docs_validate.yml index ad00d50..1b6565d 100644 --- a/.github/workflows/docs_validate.yml +++ b/.github/workflows/docs_validate.yml @@ -13,7 +13,7 @@ jobs: name: ๐Ÿ“š Doc validation runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: ๐Ÿ”— Markup Link Checker (mlc) diff --git a/.github/workflows/libtemplate-update.yml b/.github/workflows/libtemplate-update.yml index 800279b..0b111a6 100644 --- a/.github/workflows/libtemplate-update.yml +++ b/.github/workflows/libtemplate-update.yml @@ -17,7 +17,7 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. From c2ee756b471535be01944279e73e379f0900ca80 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 4 Dec 2025 06:39:26 -0700 Subject: [PATCH 059/174] Fix alignment of `sbom` parameter --- azure-pipelines/vs-insertion.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines/vs-insertion.yml b/azure-pipelines/vs-insertion.yml index 3436ce0..faeadd8 100644 --- a/azure-pipelines/vs-insertion.yml +++ b/azure-pipelines/vs-insertion.yml @@ -26,8 +26,8 @@ extends: networkIsolationPolicy: Permissive,CFSClean sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable - sbom: - enabled: false + sbom: + enabled: false stages: - stage: insertion From abb8f7471146590332cde44bec5d2ce2fae7d3e0 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Fri, 5 Dec 2025 09:54:59 -0700 Subject: [PATCH 060/174] Fix template expansion --- Expand-Template.ps1 | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Expand-Template.ps1 b/Expand-Template.ps1 index cebbcc9..aee8303 100755 --- a/Expand-Template.ps1 +++ b/Expand-Template.ps1 @@ -100,8 +100,6 @@ try { if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } git mv test/Library.Tests "test/$LibraryName.Tests" if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - git mv src/VSInsertionMetadata/Library.VSInsertionMetadata.proj "src/VSInsertionMetadata/$LibraryName.VSInsertionMetadata.proj" - if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } # Update project reference in test project. Add before removal to keep the same ItemGroup in place. dotnet add "test/$LibraryName.Tests" reference "src/$LibraryName" @@ -172,13 +170,6 @@ try { 'LibraryName' = $LibraryName; } - Replace-Placeholders -Path "azure-pipelines/OptProf.yml" -Replacements @{ - 'LibraryName' = $LibraryName; - } - Replace-Placeholders -Path "azure-pipelines/OptProf_part2.yml" -Replacements @{ - 'LibraryName' = $LibraryName; - } - # Self destruct git rm Expand-Template.* Apply-Template.ps1 if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } From fddc013fc29090578d198f457537568994647d46 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sun, 7 Dec 2025 14:14:43 -0700 Subject: [PATCH 061/174] Opt into Microsoft Testing Platform (MTP) (#452) --- Directory.Packages.props | 5 +++ azure-pipelines/Merge-CodeCoverage.ps1 | 1 + global.json | 3 ++ test/Directory.Build.props | 1 + test/Directory.Build.targets | 6 +++ tools/artifacts/coverageResults.ps1 | 27 ++++++------- tools/artifacts/testResults.ps1 | 3 +- tools/dotnet-test-cloud.ps1 | 53 +++++++++++++++++++------- 8 files changed, 72 insertions(+), 27 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index d4cbbbb..56cc7c2 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,12 +4,17 @@ true true + 1.9.1 + + + + diff --git a/azure-pipelines/Merge-CodeCoverage.ps1 b/azure-pipelines/Merge-CodeCoverage.ps1 index 308f575..169bb17 100644 --- a/azure-pipelines/Merge-CodeCoverage.ps1 +++ b/azure-pipelines/Merge-CodeCoverage.ps1 @@ -28,6 +28,7 @@ try { if ($reports) { $reports |% { $_.FullName } |% { # In addition to replacing {reporoot}, we also normalize on one kind of slash so that the report aggregates data for a file whether data was collected on Windows or not. + Write-Verbose "Processing $_" $xml = [xml](Get-Content -LiteralPath $_) $xml.coverage.packages.package.classes.class |? { $_.filename} |% { $_.filename = $_.filename.Replace('{reporoot}', $RepoRoot).Replace([IO.Path]::AltDirectorySeparatorChar, [IO.Path]::DirectorySeparatorChar) diff --git a/global.json b/global.json index 895d51b..37a3146 100644 --- a/global.json +++ b/global.json @@ -3,5 +3,8 @@ "version": "10.0.100", "rollForward": "patch", "allowPrerelease": false + }, + "test": { + "runner": "Microsoft.Testing.Platform" } } diff --git a/test/Directory.Build.props b/test/Directory.Build.props index 6c7aa71..2b5b542 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -5,6 +5,7 @@ false true + true diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index 9f32cd0..8ec617e 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -1,5 +1,11 @@ + + + + + + diff --git a/tools/artifacts/coverageResults.ps1 b/tools/artifacts/coverageResults.ps1 index 8c68216..1aadbb7 100644 --- a/tools/artifacts/coverageResults.ps1 +++ b/tools/artifacts/coverageResults.ps1 @@ -1,25 +1,26 @@ -$RepoRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..") +$RepoRoot = Resolve-Path "$PSScriptRoot\..\.." -$coverageFiles = @(Get-ChildItem "$RepoRoot/test/*.cobertura.xml" -Recurse | Where {$_.FullName -notlike "*/In/*" -and $_.FullName -notlike "*\In\*" }) +$coverageFilesUnderRoot = @(Get-ChildItem "$RepoRoot/*.cobertura.xml" -Recurse | Where-Object {$_.FullName -notlike "*/In/*" -and $_.FullName -notlike "*\In\*" }) + +# Under MTP, coverage files are written directly to the artifacts output directory, +# so we need to look there too. +$ArtifactStagingFolder = & "$PSScriptRoot/../Get-ArtifactsStagingDirectory.ps1" +$directTestLogs = Join-Path $ArtifactStagingFolder test_logs +$coverageFilesUnderArtifacts = if (Test-Path $directTestLogs) { @(Get-ChildItem "$directTestLogs/*.cobertura.xml" -Recurse) } else { @() } # Prepare code coverage reports for merging on another machine -$repoRoot = $env:SYSTEM_DEFAULTWORKINGDIRECTORY -if (!$repoRoot) { $repoRoot = $env:GITHUB_WORKSPACE } -if ($repoRoot) { - Write-Host "Substituting $repoRoot with `"{reporoot}`"" - $coverageFiles |% { - $content = Get-Content -LiteralPath $_ |% { $_ -Replace [regex]::Escape($repoRoot), "{reporoot}" } - Set-Content -LiteralPath $_ -Value $content -Encoding UTF8 - } -} else { - Write-Warning "coverageResults: Cloud build not detected. Machine-neutral token replacement skipped." +Write-Host "Substituting $repoRoot with `"{reporoot}`"" +@($coverageFilesUnderRoot + $coverageFilesUnderArtifacts) |? { $_ }|% { + $content = Get-Content -LiteralPath $_ |% { $_ -Replace [regex]::Escape($repoRoot), "{reporoot}" } + Set-Content -LiteralPath $_ -Value $content -Encoding UTF8 } if (!((Test-Path $RepoRoot\bin) -and (Test-Path $RepoRoot\obj))) { return } @{ + $directTestLogs = $coverageFilesUnderArtifacts; $RepoRoot = ( - $coverageFiles + + $coverageFilesUnderRoot + (Get-ChildItem "$RepoRoot\obj\*.cs" -Recurse) ); } diff --git a/tools/artifacts/testResults.ps1 b/tools/artifacts/testResults.ps1 index 5310fb5..a841967 100644 --- a/tools/artifacts/testResults.ps1 +++ b/tools/artifacts/testResults.ps1 @@ -4,7 +4,8 @@ Param( $result = @{} -$testRoot = Resolve-Path "$PSScriptRoot\..\..\test" +$RepoRoot = Resolve-Path "$PSScriptRoot\..\.." +$testRoot = Join-Path $RepoRoot test $result[$testRoot] = (Get-ChildItem "$testRoot\TestResults" -Recurse -Directory | Get-ChildItem -Recurse -File) $artifactStaging = & "$PSScriptRoot/../Get-ArtifactsStagingDirectory.ps1" diff --git a/tools/dotnet-test-cloud.ps1 b/tools/dotnet-test-cloud.ps1 index 02891d9..17fbe6c 100644 --- a/tools/dotnet-test-cloud.ps1 +++ b/tools/dotnet-test-cloud.ps1 @@ -25,6 +25,7 @@ Param( $RepoRoot = (Resolve-Path "$PSScriptRoot/..").Path $ArtifactStagingFolder = & "$PSScriptRoot/Get-ArtifactsStagingDirectory.ps1" +$OnCI = ($env:CI -or $env:TF_BUILD) $dotnet = 'dotnet' if ($x86) { @@ -45,23 +46,49 @@ if ($x86) { } $testBinLog = Join-Path $ArtifactStagingFolder (Join-Path build_logs test.binlog) -$testDiagLog = Join-Path $ArtifactStagingFolder (Join-Path test_logs diag.log) +$testLogs = Join-Path $ArtifactStagingFolder test_logs -& $dotnet test $RepoRoot ` - --no-build ` - -c $Configuration ` - --filter "TestCategory!=FailsInCloudTest" ` - --collect "Code Coverage;Format=cobertura" ` - --settings "$PSScriptRoot/test.runsettings" ` - --blame-hang-timeout 60s ` - --blame-crash ` - -bl:"$testBinLog" ` - --diag "$testDiagLog;TraceLevel=info" ` - --logger trx ` +$globalJson = Get-Content $PSScriptRoot/../global.json | ConvertFrom-Json +$isMTP = $globalJson.test.runner -eq 'Microsoft.Testing.Platform' +if ($isMTP) { + $extraArgs = @() + if ($OnCI) { $extraArgs += '--no-progress' } + & $dotnet test --solution $RepoRoot ` + --no-build ` + -c $Configuration ` + -bl:"$testBinLog" ` + --filter-not-trait 'TestCategory=FailsInCloudTest' ` + --coverage ` + --coverage-output-format cobertura ` + --coverage-settings "$PSScriptRoot/test.runsettings" ` + --hangdump ` + --hangdump-timeout 60s ` + --crashdump ` + --diagnostic ` + --diagnostic-output-directory $testLogs ` + --diagnostic-verbosity Information ` + --results-directory $testLogs ` + --report-trx ` + @extraArgs +} else { + $testDiagLog = Join-Path $ArtifactStagingFolder (Join-Path test_logs diag.log) + & $dotnet test $RepoRoot ` + --no-build ` + -c $Configuration ` + --filter "TestCategory!=FailsInCloudTest" ` + --collect "Code Coverage;Format=cobertura" ` + --settings "$PSScriptRoot/test.runsettings" ` + --blame-hang-timeout 60s ` + --blame-crash ` + -bl:"$testBinLog" ` + --diag "$testDiagLog;TraceLevel=info" ` + --logger trx ` +} $unknownCounter = 0 Get-ChildItem -Recurse -Path $RepoRoot\test\*.trx |% { - Copy-Item $_ -Destination $ArtifactStagingFolder/test_logs/ + New-Item $testLogs -ItemType Directory -Force | Out-Null + Copy-Item $_ -Destination $testLogs if ($PublishResults) { $x = [xml](Get-Content -LiteralPath $_) From f761f0f7e50514cdb2b0b4b3b07fa3d298ff2eaf Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sun, 7 Dec 2025 15:09:40 -0700 Subject: [PATCH 062/174] Push to nuget.org before pushing to github release This makes recovering a release from a nuget.org push failure easier. --- .github/workflows/release.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2495c1..a4e4745 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -64,6 +64,15 @@ jobs: run-id: ${{ steps.findrunid.outputs.runid }} github-token: ${{ github.token }} + - name: ๐Ÿชช Authorize NuGet package push + uses: NuGet/login@d22cc5f58ff5b88bf9bd452535b4335137e24544 # v1.1.0 + id: nuget-login + with: + user: ${{ secrets.NUGET_USER }} + + - name: ๐Ÿš€ Push NuGet packages + run: dotnet nuget push ${{ runner.temp }}/deployables/*.nupkg --source https://api.nuget.org/v3/index.json -k '${{ steps.nuget-login.outputs.NUGET_API_KEY }}' + - name: ๐Ÿ’ฝ Upload artifacts to release shell: pwsh if: ${{ github.event_name == 'release' && github.event.release.assets_url != '' }} @@ -74,12 +83,3 @@ jobs: Write-Host "Uploading $($_.Name) to release..." gh release -R ${{ github.repository }} upload "${{ github.ref_name }}" $_.FullName } - - - name: ๐Ÿชช Authorize NuGet package push - uses: NuGet/login@d22cc5f58ff5b88bf9bd452535b4335137e24544 # v1.1.0 - id: nuget-login - with: - user: ${{ secrets.NUGET_USER }} - - - name: ๐Ÿš€ Push NuGet packages - run: dotnet nuget push ${{ runner.temp }}/deployables/*.nupkg --source https://api.nuget.org/v3/index.json -k '${{ steps.nuget-login.outputs.NUGET_API_KEY }}' From e4035601946447f2cb317003ebb600cf7df2742d Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sun, 7 Dec 2025 15:59:57 -0700 Subject: [PATCH 063/174] Update to MTP v2 (#455) --- Directory.Packages.props | 6 +++--- test/Library.Tests/Library.Tests.csproj | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 56cc7c2..80d105c 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,19 +4,19 @@ true true - 1.9.1 + 2.0.2 - + - + diff --git a/test/Library.Tests/Library.Tests.csproj b/test/Library.Tests/Library.Tests.csproj index 5cbc1e1..1463357 100644 --- a/test/Library.Tests/Library.Tests.csproj +++ b/test/Library.Tests/Library.Tests.csproj @@ -14,7 +14,7 @@ - + From a28d54057fd4e9d86d4130b3977354bdf1754fbb Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sun, 7 Dec 2025 16:11:51 -0700 Subject: [PATCH 064/174] Update all MTP related packages at once (457) --- .github/renovate.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/renovate.json b/.github/renovate.json index c97d977..79dba1e 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -11,6 +11,10 @@ "matchPackageNames": ["xunit*"], "groupName": "xunit" }, + { + "matchPackageNames": ["Microsoft.Testing.Extensions.*"], + "groupName": "Microsoft Testing Platform" + }, { "matchDatasources": ["dotnet-version", "docker"], "matchDepNames": ["dotnet-sdk", "mcr.microsoft.com/dotnet/sdk"], From f355f008b2b164d1e1fa8ca120442b0bffcf06af Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sun, 7 Dec 2025 16:15:02 -0700 Subject: [PATCH 065/174] Fix test result publishing to AzDO (458) --- tools/dotnet-test-cloud.ps1 | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tools/dotnet-test-cloud.ps1 b/tools/dotnet-test-cloud.ps1 index 17fbe6c..9b48178 100644 --- a/tools/dotnet-test-cloud.ps1 +++ b/tools/dotnet-test-cloud.ps1 @@ -70,6 +70,8 @@ if ($isMTP) { --results-directory $testLogs ` --report-trx ` @extraArgs + + $trxFiles = Get-ChildItem -Recurse -Path $testLogs\*.trx } else { $testDiagLog = Join-Path $ArtifactStagingFolder (Join-Path test_logs diag.log) & $dotnet test $RepoRoot ` @@ -82,13 +84,17 @@ if ($isMTP) { --blame-crash ` -bl:"$testBinLog" ` --diag "$testDiagLog;TraceLevel=info" ` - --logger trx ` + --logger trx + + $trxFiles = Get-ChildItem -Recurse -Path $RepoRoot\test\*.trx } $unknownCounter = 0 -Get-ChildItem -Recurse -Path $RepoRoot\test\*.trx |% { +$trxFiles |% { New-Item $testLogs -ItemType Directory -Force | Out-Null - Copy-Item $_ -Destination $testLogs + if (!($_.FullName.StartsWith($testLogs))) { + Copy-Item $_ -Destination $testLogs + } if ($PublishResults) { $x = [xml](Get-Content -LiteralPath $_) From 3304d7930d87ac76dc060f80d5a89a233696e40c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 13:50:17 +0000 Subject: [PATCH 066/174] Update .NET SDK to v10.0.101 (#459) * Update mcr.microsoft.com/dotnet/sdk Docker tag to v10.0.101 * Bump .NET SDK --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Andrew Arnott --- .devcontainer/Dockerfile | 2 +- global.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 6637ad8..64f23a9 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.100@sha256:c7445f141c04f1a6b454181bd098dcfa606c61ba0bd213d0a702489e5bd4cd71 +FROM mcr.microsoft.com/dotnet/sdk:10.0.101@sha256:d1823fecac3689a2eb959e02ee3bfe1c2142392808240039097ad70644566190 # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. diff --git a/global.json b/global.json index 37a3146..a0ec2d8 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.100", + "version": "10.0.101", "rollForward": "patch", "allowPrerelease": false }, From 63de08696a81f2a8350910cd9c162e021f95a604 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 10 Dec 2025 08:48:27 -0700 Subject: [PATCH 067/174] Drop package dependencies that MTP does not require --- Directory.Packages.props | 2 -- test/Library.Tests/Library.Tests.csproj | 2 -- 2 files changed, 4 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 80d105c..098c7f0 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,12 +10,10 @@ - - diff --git a/test/Library.Tests/Library.Tests.csproj b/test/Library.Tests/Library.Tests.csproj index 1463357..e9e12e4 100644 --- a/test/Library.Tests/Library.Tests.csproj +++ b/test/Library.Tests/Library.Tests.csproj @@ -12,8 +12,6 @@ - - From 70980c340965220736976b61c0880a1f914a3171 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 10 Dec 2025 14:22:58 -0700 Subject: [PATCH 068/174] Fix MTP test failure for MTP-incompatible projects under the test folder --- test/Directory.Build.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index 8ec617e..839afb5 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -1,6 +1,6 @@ - + From 307d5e37fbf1fff5b2ce96d7154145d4aa80e676 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 11 Dec 2025 07:16:35 -0700 Subject: [PATCH 069/174] Fix testing regression from last commit --- test/Directory.Build.props | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Directory.Build.props b/test/Directory.Build.props index 2b5b542..d7f919f 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -3,6 +3,7 @@ + true false true true From 5c9d6251b1074d83db4d18416828b2ccdba07eb9 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 11 Dec 2025 07:32:43 -0700 Subject: [PATCH 070/174] Adjust how we use IsTestProject This matches how MTP uses it internally. --- test/Directory.Build.props | 1 - test/Directory.Build.targets | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/Directory.Build.props b/test/Directory.Build.props index d7f919f..2b5b542 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -3,7 +3,6 @@ - true false true true diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index 839afb5..3758bb8 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -1,6 +1,6 @@ - + From 762bd46d949ef038c90c5258be769e82b08c2e2d Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 11 Dec 2025 10:25:57 -0700 Subject: [PATCH 071/174] Expand applicability of extra args in `dotnet-test-cloud.ps1` --- tools/dotnet-test-cloud.ps1 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/dotnet-test-cloud.ps1 b/tools/dotnet-test-cloud.ps1 index 9b48178..b550480 100644 --- a/tools/dotnet-test-cloud.ps1 +++ b/tools/dotnet-test-cloud.ps1 @@ -50,8 +50,9 @@ $testLogs = Join-Path $ArtifactStagingFolder test_logs $globalJson = Get-Content $PSScriptRoot/../global.json | ConvertFrom-Json $isMTP = $globalJson.test.runner -eq 'Microsoft.Testing.Platform' +$extraArgs = @() + if ($isMTP) { - $extraArgs = @() if ($OnCI) { $extraArgs += '--no-progress' } & $dotnet test --solution $RepoRoot ` --no-build ` @@ -84,7 +85,8 @@ if ($isMTP) { --blame-crash ` -bl:"$testBinLog" ` --diag "$testDiagLog;TraceLevel=info" ` - --logger trx + --logger trx ` + @extraArgs $trxFiles = Get-ChildItem -Recurse -Path $RepoRoot\test\*.trx } From 25c8c0d68756fd07ce81881576b8ca39f4ee5eb1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Dec 2025 04:37:41 +0000 Subject: [PATCH 072/174] Update becheran/mlc action to v1.1.0 (461) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b3aa05b..f0ee2d3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,6 +77,6 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: ๐Ÿ”— Markup Link Checker (mlc) - uses: becheran/mlc@18a06b3aa2901ca197de59c8b0b1f54fdba6b3fa # v1.0.0 + uses: becheran/mlc@6fa3bddc1a921454b7840df30b343f6415bc8d35 # v1.1.0 with: args: --do-not-warn-for-redirect-to https://learn.microsoft.com*,https://dotnet.microsoft.com/*,https://dev.azure.com/*,https://app.codecov.io/* -p docfx -i https://www.npmjs.com/package/*,https://get.dot.net/ From 6dc696587963b28140ecaa5d01dcd19317ce8715 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Dec 2025 17:44:17 -0700 Subject: [PATCH 073/174] Update GitHub Artifact Actions (462) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/actions/publish-artifacts/action.yaml | 14 +++++++------- .github/workflows/release.yml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/actions/publish-artifacts/action.yaml b/.github/actions/publish-artifacts/action.yaml index 3b267f3..e024682 100644 --- a/.github/actions/publish-artifacts/action.yaml +++ b/.github/actions/publish-artifacts/action.yaml @@ -14,46 +14,46 @@ runs: - name: ๐Ÿ“ข Upload project.assets.json files if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: projectAssetsJson-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/projectAssetsJson continue-on-error: true - name: ๐Ÿ“ข Upload variables - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: variables-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/Variables continue-on-error: true - name: ๐Ÿ“ข Upload build_logs if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: build_logs-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/build_logs continue-on-error: true - name: ๐Ÿ“ข Upload testResults if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: testResults-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/testResults continue-on-error: true - name: ๐Ÿ“ข Upload coverageResults if: always() - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: coverageResults-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/coverageResults continue-on-error: true - name: ๐Ÿ“ข Upload symbols - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: symbols-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/symbols continue-on-error: true - name: ๐Ÿ“ข Upload deployables - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: deployables-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/deployables diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a4e4745..51b1138 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,7 +57,7 @@ jobs: Echo "runid=$runid" >> $env:GITHUB_OUTPUT - name: ๐Ÿ”ป Download deployables artifacts - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 with: name: deployables-Linux path: ${{ runner.temp }}/deployables From 36de3c86ac63043a3d9c6fd78c8be6c34e91cfbd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Dec 2025 19:35:04 -0700 Subject: [PATCH 074/174] Update becheran/mlc action to v1.2.0 (463) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f0ee2d3..271ba21 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,6 +77,6 @@ jobs: steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: ๐Ÿ”— Markup Link Checker (mlc) - uses: becheran/mlc@6fa3bddc1a921454b7840df30b343f6415bc8d35 # v1.1.0 + uses: becheran/mlc@7ec24825cefe0c9c8c6bac48430e1f69e3ec356e # v1.2.0 with: args: --do-not-warn-for-redirect-to https://learn.microsoft.com*,https://dotnet.microsoft.com/*,https://dev.azure.com/*,https://app.codecov.io/* -p docfx -i https://www.npmjs.com/package/*,https://get.dot.net/ From 6b1ad3c0d9f095ade0751cd7c66406f079dfd4bc Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sat, 20 Dec 2025 16:13:45 -0700 Subject: [PATCH 075/174] Preserve exit codes better and organize switches --- tools/dotnet-test-cloud.ps1 | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/tools/dotnet-test-cloud.ps1 b/tools/dotnet-test-cloud.ps1 index b550480..61e848a 100644 --- a/tools/dotnet-test-cloud.ps1 +++ b/tools/dotnet-test-cloud.ps1 @@ -51,26 +51,36 @@ $testLogs = Join-Path $ArtifactStagingFolder test_logs $globalJson = Get-Content $PSScriptRoot/../global.json | ConvertFrom-Json $isMTP = $globalJson.test.runner -eq 'Microsoft.Testing.Platform' $extraArgs = @() +$failedTests = 0 if ($isMTP) { if ($OnCI) { $extraArgs += '--no-progress' } + + $dumpSwitches = @( + ,'--hangdump' + ,'--hangdump-timeout','120s' + ,'--crashdump' + ) + $mtpArgs = @( + ,'--coverage' + ,'--coverage-output-format','cobertura' + ,'--diagnostic' + ,'--diagnostic-output-directory',$testLogs + ,'--diagnostic-verbosity','Information' + ,'--results-directory',$testLogs + ,'--report-trx' + ) + & $dotnet test --solution $RepoRoot ` --no-build ` -c $Configuration ` -bl:"$testBinLog" ` --filter-not-trait 'TestCategory=FailsInCloudTest' ` - --coverage ` - --coverage-output-format cobertura ` --coverage-settings "$PSScriptRoot/test.runsettings" ` - --hangdump ` - --hangdump-timeout 60s ` - --crashdump ` - --diagnostic ` - --diagnostic-output-directory $testLogs ` - --diagnostic-verbosity Information ` - --results-directory $testLogs ` - --report-trx ` + @mtpArgs ` + @dumpSwitches ` @extraArgs + if ($LASTEXITCODE -ne 0) { $failedTests += 1 } $trxFiles = Get-ChildItem -Recurse -Path $testLogs\*.trx } else { @@ -87,6 +97,7 @@ if ($isMTP) { --diag "$testDiagLog;TraceLevel=info" ` --logger trx ` @extraArgs + if ($LASTEXITCODE -ne 0) { $failedTests += 1 } $trxFiles = Get-ChildItem -Recurse -Path $RepoRoot\test\*.trx } @@ -119,3 +130,7 @@ $trxFiles |% { Write-Host "##vso[results.publish type=VSTest;runTitle=$runTitle;publishRunAttachments=true;resultFiles=$_;failTaskOnFailedTests=true;testRunSystem=VSTS - PTR;]" } } + +if ($failedTests -ne 0) { + exit $failedTests +} From 86545b60b33ededd96206464cf83764a2049746e Mon Sep 17 00:00:00 2001 From: Charles Gagnon Date: Sat, 27 Dec 2025 16:06:07 -0800 Subject: [PATCH 076/174] Skip native binary PDB conversion Add check to skip conversion for native binary PDBs. --- tools/Prepare-Legacy-Symbols.ps1 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/Prepare-Legacy-Symbols.ps1 b/tools/Prepare-Legacy-Symbols.ps1 index ae0bc40..e566d62 100644 --- a/tools/Prepare-Legacy-Symbols.ps1 +++ b/tools/Prepare-Legacy-Symbols.ps1 @@ -20,6 +20,20 @@ Get-ChildItem "$ArtifactStagingFolder\*.pdb" -Recurse |% { } if ($BinaryImagePath) { + # Native binaries can't have their PDBs converted to legacy (Windows) format so just skip them + try { + $assembly = [System.Reflection.AssemblyName]::GetAssemblyName($BinaryImagePath) + $isManaged = $true + } + catch { + $isManaged = $false + } + + if (-not $isManaged) { + Write-Host "Skipping native binary PDB: $_" -ForegroundColor DarkYellow + return + } + # Convert the PDB to legacy Windows PDBs Write-Host "Converting PDB for $_" -ForegroundColor DarkGray $WindowsPdbDir = "$($_.Directory.FullName)\$WindowsPdbSubDirName" From 57248c719e5b18109e646ffd2145111b6163a824 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sun, 4 Jan 2026 18:55:23 -0700 Subject: [PATCH 077/174] Fix case sensitivity in dotnet-test-cloud --- tools/dotnet-test-cloud.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dotnet-test-cloud.ps1 b/tools/dotnet-test-cloud.ps1 index 61e848a..5d20481 100644 --- a/tools/dotnet-test-cloud.ps1 +++ b/tools/dotnet-test-cloud.ps1 @@ -105,7 +105,7 @@ if ($isMTP) { $unknownCounter = 0 $trxFiles |% { New-Item $testLogs -ItemType Directory -Force | Out-Null - if (!($_.FullName.StartsWith($testLogs))) { + if (!($_.FullName.StartsWith($testLogs, [StringComparison]::OrdinalIgnoreCase))) { Copy-Item $_ -Destination $testLogs } From a385e050ade017e3cbbdebc6cc5f390c9efbe7b8 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 5 Jan 2026 07:10:03 -0700 Subject: [PATCH 078/174] Bump code coverage package/tool --- .config/dotnet-tools.json | 4 ++-- Directory.Packages.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 9f9de05..6979242 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -10,7 +10,7 @@ "rollForward": false }, "dotnet-coverage": { - "version": "18.1.0", + "version": "18.3.1", "commands": [ "dotnet-coverage" ], @@ -38,4 +38,4 @@ "rollForward": false } } -} \ No newline at end of file +} diff --git a/Directory.Packages.props b/Directory.Packages.props index 098c7f0..d050432 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,7 +10,7 @@ - + From 961b025b79a2e0cf39e6976ec74d73aa6ef35388 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 5 Jan 2026 07:46:58 -0700 Subject: [PATCH 079/174] Update becheran/mlc action to v1.2.0 --- .github/workflows/docs_validate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs_validate.yml b/.github/workflows/docs_validate.yml index 1b6565d..139a27f 100644 --- a/.github/workflows/docs_validate.yml +++ b/.github/workflows/docs_validate.yml @@ -17,7 +17,7 @@ jobs: with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: ๐Ÿ”— Markup Link Checker (mlc) - uses: becheran/mlc@18a06b3aa2901ca197de59c8b0b1f54fdba6b3fa # v1.0.0 + uses: becheran/mlc@7ec24825cefe0c9c8c6bac48430e1f69e3ec356e # v1.2.0 with: args: --do-not-warn-for-redirect-to https://learn.microsoft.com*,https://dotnet.microsoft.com/*,https://dev.azure.com/*,https://app.codecov.io/* -p docfx -i https://aka.ms/onboardsupport,https://aka.ms/spot,https://msrc.microsoft.com/*,https://www.microsoft.com/msrc*,https://microsoft.com/msrc*,https://www.npmjs.com/package/*,https://get.dot.net/ - name: โš™ Install prerequisites From c7b72fb02f540fa930e66e57f642b3c511610ca7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Jan 2026 13:45:29 +0000 Subject: [PATCH 080/174] Update dependency Microsoft.Testing.Extensions.CodeCoverage to 18.3.2 --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index d050432..152a207 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,7 +10,7 @@ - + From 9870d10a151a2c6747d7c43178a36d81509fda3b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Jan 2026 17:20:11 -0700 Subject: [PATCH 081/174] Update dependency dotnet-coverage to v18.3.2 (465) --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 6979242..31856cb 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -10,7 +10,7 @@ "rollForward": false }, "dotnet-coverage": { - "version": "18.3.1", + "version": "18.3.2", "commands": [ "dotnet-coverage" ], From c35e57fd2576d8e51b6745f4bd713161e5599751 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 12 Jan 2026 05:59:21 -0700 Subject: [PATCH 082/174] Merge pull request 469 from AArnott/copilot/port-change-to-library-template Add MTP v2/xunit v3 test commands to copilot instructions --- .github/copilot-instructions.md | 63 +++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 0859350..bb31332 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -12,9 +12,68 @@ ## Testing +**IMPORTANT**: This repository uses Microsoft.Testing.Platform (MTP v2) with xunit v3. Traditional `--filter` syntax does NOT work. Use the options below instead. + * There should generally be one test project (under the `test` directory) per shipping project (under the `src` directory). Test projects are named after the project being tested with a `.Test` suffix. -* Tests should use the Xunit testing framework. -* Some tests are known to be unstable. When running tests, you should skip the unstable ones by running `dotnet test --filter "TestCategory!=FailsInCloudTest"`. +* Tests use xunit v3 with Microsoft.Testing.Platform (MTP v2). Traditional VSTest `--filter` syntax does NOT work. +* Some tests are known to be unstable. When running tests, you should skip the unstable ones by using `-- --filter-not-trait "FailsInCloudTest=true"`. + +### Running Tests + +**Run all tests**: +```bash +dotnet test --no-build -c Release +``` + +**Run tests for a specific test project**: +```bash +dotnet test --project test/Library.Tests/Library.Tests.csproj --no-build -c Release +``` + +**Run a single test method**: +```bash +dotnet test --project test/Library.Tests/Library.Tests.csproj --no-build -c Release -- --filter-method ClassName.MethodName +``` + +**Run all tests in a test class**: +```bash +dotnet test --project test/Library.Tests/Library.Tests.csproj --no-build -c Release -- --filter-class ClassName +``` + +**Run tests with wildcard matching** (supports wildcards at beginning and/or end): +```bash +dotnet test --project test/Library.Tests/Library.Tests.csproj --no-build -c Release -- --filter-method "*Pattern*" +``` + +**Run tests with a specific trait** (equivalent to category filtering): +```bash +dotnet test --project test/Library.Tests/Library.Tests.csproj --no-build -c Release -- --filter-trait "TraitName=value" +``` + +**Exclude tests with a specific trait** (skip unstable tests): +```bash +dotnet test --project test/Library.Tests/Library.Tests.csproj --no-build -c Release -- --filter-not-trait "FailsInCloudTest=true" +``` + +**Run tests for a specific framework only**: +```bash +dotnet test --project test/Library.Tests/Library.Tests.csproj --no-build -c Release --framework net9.0 +``` + +**List all available tests without running them**: +```bash +cd test/Library.Tests +dotnet run --no-build -c Release --framework net9.0 -- --list-tests +``` + +**Key points about test filtering with MTP v2 / xunit v3**: +- Options after `--` are passed to the test runner, not to `dotnet test` +- Use `--filter-method`, `--filter-class`, `--filter-namespace` for simple filtering +- Use `--filter-trait` and `--filter-not-trait` for trait-based filtering (replaces `--filter "TestCategory=..."`) +- Traditional VSTest `--filter` expressions do NOT work +- Wildcards `*` are supported at the beginning and/or end of filter values +- Multiple simple filters of the same type use OR logic, different types combine with AND +- See `--help` for query filter language for advanced scenarios ## Coding style From 169c608ea1b989523b8907b1abef29746e3c1423 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 12 Jan 2026 06:19:24 -0700 Subject: [PATCH 083/174] Fix copilot instructions regarding test project suffix --- .github/copilot-instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index bb31332..2aeca2a 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -14,7 +14,7 @@ **IMPORTANT**: This repository uses Microsoft.Testing.Platform (MTP v2) with xunit v3. Traditional `--filter` syntax does NOT work. Use the options below instead. -* There should generally be one test project (under the `test` directory) per shipping project (under the `src` directory). Test projects are named after the project being tested with a `.Test` suffix. +* There should generally be one test project (under the `test` directory) per shipping project (under the `src` directory). Test projects are named after the project being tested with a `.Tests` suffix. * Tests use xunit v3 with Microsoft.Testing.Platform (MTP v2). Traditional VSTest `--filter` syntax does NOT work. * Some tests are known to be unstable. When running tests, you should skip the unstable ones by using `-- --filter-not-trait "FailsInCloudTest=true"`. From e989a4c3670c71a2b1213bdd92583b6a062ad531 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 15:44:13 +0000 Subject: [PATCH 084/174] Update .NET SDK to v10.0.102 (471) * Update mcr.microsoft.com/dotnet/sdk Docker tag to v10.0.102 * Bump .NET SDK to 10.0.102 --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Andrew Arnott --- .devcontainer/Dockerfile | 2 +- global.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 64f23a9..10fb395 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.101@sha256:d1823fecac3689a2eb959e02ee3bfe1c2142392808240039097ad70644566190 +FROM mcr.microsoft.com/dotnet/sdk:10.0.102@sha256:25d14b400b75fa4e89d5bd4487a92a604a4e409ab65becb91821e7dc4ac7f81f # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. diff --git a/global.json b/global.json index a0ec2d8..d8d718a 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.101", + "version": "10.0.102", "rollForward": "patch", "allowPrerelease": false }, From 901b22d472d6b424fd00409cba2675d42056beaf Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Fri, 16 Jan 2026 15:59:45 -0700 Subject: [PATCH 085/174] Fix FailsInCloudTest filter after MTPv2 migration --- tools/dotnet-test-cloud.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dotnet-test-cloud.ps1 b/tools/dotnet-test-cloud.ps1 index 5d20481..608214c 100644 --- a/tools/dotnet-test-cloud.ps1 +++ b/tools/dotnet-test-cloud.ps1 @@ -75,7 +75,7 @@ if ($isMTP) { --no-build ` -c $Configuration ` -bl:"$testBinLog" ` - --filter-not-trait 'TestCategory=FailsInCloudTest' ` + --filter-not-trait 'FailsInCloudTest=true' ` --coverage-settings "$PSScriptRoot/test.runsettings" ` @mtpArgs ` @dumpSwitches ` From 918803f7be2cc07bc5e22b0882772e6ca98162b3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 11:30:03 -0700 Subject: [PATCH 086/174] Update dependency xunit.v3.mtp-v2 to 3.2.2 (472) --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 152a207..d245de1 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -14,7 +14,7 @@ - + From 689415e156abff6d39d5b9b93c8eed9cf2113b26 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 24 Jan 2026 18:32:42 +0000 Subject: [PATCH 087/174] Update actions/checkout action to v6.0.2 (#473) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 ++-- .github/workflows/copilot-setup-steps.yml | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/libtemplate-update.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 271ba21..26bc9eb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ jobs: - windows-2025 steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites @@ -75,7 +75,7 @@ jobs: name: ๐Ÿ“ƒ Docs runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: ๐Ÿ”— Markup Link Checker (mlc) uses: becheran/mlc@7ec24825cefe0c9c8c6bac48430e1f69e3ec356e # v1.2.0 with: diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index ebd5388..3c032fa 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -26,7 +26,7 @@ jobs: # You can define any steps you want, and they will run before the agent starts. # If you do not check out your code, Copilot will do this for you. steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b1ba568..53af0a0 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -24,7 +24,7 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: โš™ Install prerequisites diff --git a/.github/workflows/libtemplate-update.yml b/.github/workflows/libtemplate-update.yml index 0b111a6..62a6417 100644 --- a/.github/workflows/libtemplate-update.yml +++ b/.github/workflows/libtemplate-update.yml @@ -17,7 +17,7 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. From 8b62459f6fd69fd56f8fac849d111fd30e539d04 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 13:13:47 -0700 Subject: [PATCH 088/174] Update Microsoft Testing Platform (475) --- Directory.Packages.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index d245de1..73d0d36 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,13 +4,13 @@ true true - 2.0.2 + 2.1.0 - + From 11e9554fe3fc76785f8b1ca8f6e5c54cb64b631f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 13:14:45 -0700 Subject: [PATCH 089/174] Update dependency dotnet-coverage to v18.4.1 (474) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 31856cb..1418b91 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -10,7 +10,7 @@ "rollForward": false }, "dotnet-coverage": { - "version": "18.3.2", + "version": "18.4.1", "commands": [ "dotnet-coverage" ], From d10df4bfb0c47a50100348849044b7899d3c70f8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 22:05:06 -0700 Subject: [PATCH 090/174] Update mcr.microsoft.com/dotnet/sdk:10.0.102 Docker digest to 6ba533c (476) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 10fb395..50883c3 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.102@sha256:25d14b400b75fa4e89d5bd4487a92a604a4e409ab65becb91821e7dc4ac7f81f +FROM mcr.microsoft.com/dotnet/sdk:10.0.102@sha256:6ba533cc61a5d8c5e7d4b3a3e33e2ddc2efef200b112e4d658303516bfd24255 # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. From c8b42f289002cf02b2bd1e3bb3ce312410afceef Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sun, 8 Feb 2026 21:48:29 -0700 Subject: [PATCH 091/174] Add Copilot prompt to automate Library.Template updates This prompt file is intended for use in repos that use this template -- not for this template to use within its own repo directly. --- .github/prompts/template-release-notes.md | 4 ++ .../prompts/update-library-template.prompt.md | 58 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 .github/prompts/template-release-notes.md create mode 100644 .github/prompts/update-library-template.prompt.md diff --git a/.github/prompts/template-release-notes.md b/.github/prompts/template-release-notes.md new file mode 100644 index 0000000..eb26881 --- /dev/null +++ b/.github/prompts/template-release-notes.md @@ -0,0 +1,4 @@ +# Template release notes + +This file will describe significant changes in Library.Template as they are introduced, especially if they require special consideration when merging updates into existing repos. +This file is referenced by update-library-template.prompt.md and should remain in place to facilitate future merges, whether done manually or by AI. diff --git a/.github/prompts/update-library-template.prompt.md b/.github/prompts/update-library-template.prompt.md new file mode 100644 index 0000000..a044007 --- /dev/null +++ b/.github/prompts/update-library-template.prompt.md @@ -0,0 +1,58 @@ +--- +description: Merges the latest Library.Template into this repo (at position of HEAD) and resolves conflicts. +--- + +# Instructions + +1. Run `tools\MergeFrom-Template.ps1` +2. Resolve merge conflicts, taking into account conflict resolution policy below. +3. Validate the changes, as described in the validation section below. +4. Commiting your changes (if applicable). + +## Conflict resolution policy + +There may be special notes in `.github/prompts/template-release-notes.md` that describe special considerations for certain files or scenarios to help you resolve conflicts appropriately. +Always refer to that file before proceeding. +In particular, focus on the *incoming* part of the file, since it represents the changes from the Library.Template that you are merging into your repo. + +Also consider that some repos choose to reject certain Library.Template patterns. +For example the template uses MTPv2 for test projects, but a repo might have chosen not to adopt that. +When resolving merge conflicts, consider whether it looks like the relevant code file is older than it should be given the changes the template is bringing in. +Ask the user when in doubt as to whether the conflict should be resolved in favor of 'catching up' with the template or keeping the current changes. + +### Keep Current files + +Conflicts in the following files should always be resolved by keeping the current version (i.e. discard incoming changes): + +* README.md + +### Deleted files + +Very typically, when the incoming change is to a file that was deleted locally, the correct resolution is to re-delete the file. + +In some cases however, the deleted file may have incoming changes that should be applied to other files. +The `test\Library.Tests\Library.Tests.csproj` file is very typical of this. +Changes to this file should very typically be applied to any and all test projects in the repo. +You are responsible for doing this in addition to re-deleting this template file. + +## Validation + +Validate the merge result (after resolving any conflicts, if applicable). +Use #runSubagent for each step. + +1. Verify that `dotnet restore` succeeds. Fix any issues that come up. +2. Verify that `dotnet build` succeeds. +3. Verify that tests succeed by running `tools\dotnet-test-cloud.ps1`. + +While these validations are described using `dotnet` CLI commands, some repos require using full msbuild.exe. +You can detect this by checking the `azure-pipelines/dotnet.yml` or `.github/workflows/build.yml` files for use of one or the other tool. + +## Committing your changes + +If you have to make any changes for validations to pass, consider whether they qualify as a bad merge conflict resolution or more of a novel change that you're making to work with the Library.Template update. +Merge conflict resolution fixes ideally get amended into the merge commit, while novel changes would go into a novel commit after the merge commit. + +Always author your commits using `git commit --author "๐Ÿค– Copilot "` (and possibly other parameters). +Describe the nature of the merge conflicts you encountered and how you resolved them in your commit message. + +Later, if asked to review pull request validation breaks, always author a fresh commit with each fix that you push, unless the user directs you to do otherwise. From 98ba7d5b41df191ad03f0afd52e0a75a9cac11c8 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 9 Feb 2026 13:36:11 -0700 Subject: [PATCH 092/174] Fix test filter --- .github/copilot-instructions.md | 2 +- tools/dotnet-test-cloud.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 2aeca2a..deb2953 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -52,7 +52,7 @@ dotnet test --project test/Library.Tests/Library.Tests.csproj --no-build -c Rele **Exclude tests with a specific trait** (skip unstable tests): ```bash -dotnet test --project test/Library.Tests/Library.Tests.csproj --no-build -c Release -- --filter-not-trait "FailsInCloudTest=true" +dotnet test --project test/Library.Tests/Library.Tests.csproj --no-build -c Release -- --filter-not-trait "TestCategory=FailsInCloudTest" ``` **Run tests for a specific framework only**: diff --git a/tools/dotnet-test-cloud.ps1 b/tools/dotnet-test-cloud.ps1 index 608214c..5d20481 100644 --- a/tools/dotnet-test-cloud.ps1 +++ b/tools/dotnet-test-cloud.ps1 @@ -75,7 +75,7 @@ if ($isMTP) { --no-build ` -c $Configuration ` -bl:"$testBinLog" ` - --filter-not-trait 'FailsInCloudTest=true' ` + --filter-not-trait 'TestCategory=FailsInCloudTest' ` --coverage-settings "$PSScriptRoot/test.runsettings" ` @mtpArgs ` @dumpSwitches ` From 1632266376df028c8e44fdbc7e65fb49c184edfe Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 9 Feb 2026 14:12:38 -0700 Subject: [PATCH 093/174] Update actions/checkout action to v6.0.2 --- .github/workflows/docs_validate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs_validate.yml b/.github/workflows/docs_validate.yml index 139a27f..fa08fdb 100644 --- a/.github/workflows/docs_validate.yml +++ b/.github/workflows/docs_validate.yml @@ -13,7 +13,7 @@ jobs: name: ๐Ÿ“š Doc validation runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: ๐Ÿ”— Markup Link Checker (mlc) From 8f317e65a1f3180d4efa4ebbd5aed7f53206394c Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 10 Feb 2026 16:01:19 -0700 Subject: [PATCH 094/174] Improve library.template merge AI prompt --- .github/prompts/template-release-notes.md | 8 ++++++++ .github/prompts/update-library-template.prompt.md | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/.github/prompts/template-release-notes.md b/.github/prompts/template-release-notes.md index eb26881..0e5e2d8 100644 --- a/.github/prompts/template-release-notes.md +++ b/.github/prompts/template-release-notes.md @@ -2,3 +2,11 @@ This file will describe significant changes in Library.Template as they are introduced, especially if they require special consideration when merging updates into existing repos. This file is referenced by update-library-template.prompt.md and should remain in place to facilitate future merges, whether done manually or by AI. + +## Solution rename + +Never leave a Library.slnx file in the repository. +You might even see one there even though this particular merge didn't bring it in. +This can be an artifact of having renamed Library.sln to Library.slnx in the template repo, but ultimately the receiving repo should have only one .sln or .slnx file, with a better name than `Library`. +If you can confidently do so, go ahead and migrate their `.sln` to an `.slnx` with their original name. +If you can't, just delete `Library.slnx` anyway. diff --git a/.github/prompts/update-library-template.prompt.md b/.github/prompts/update-library-template.prompt.md index a044007..cfabcb3 100644 --- a/.github/prompts/update-library-template.prompt.md +++ b/.github/prompts/update-library-template.prompt.md @@ -20,6 +20,8 @@ For example the template uses MTPv2 for test projects, but a repo might have cho When resolving merge conflicts, consider whether it looks like the relevant code file is older than it should be given the changes the template is bringing in. Ask the user when in doubt as to whether the conflict should be resolved in favor of 'catching up' with the template or keeping the current changes. +Use #runSubagent to analyze and resolve merge conflicts across files in parallel. + ### Keep Current files Conflicts in the following files should always be resolved by keeping the current version (i.e. discard incoming changes): @@ -47,6 +49,11 @@ Use #runSubagent for each step. While these validations are described using `dotnet` CLI commands, some repos require using full msbuild.exe. You can detect this by checking the `azure-pipelines/dotnet.yml` or `.github/workflows/build.yml` files for use of one or the other tool. +You are *not* responsible for fixing issues that the merge did not cause. +If validation fails for reasons that seem unrelated to the changes brought in by the merge, advise the user and ask how they'd like you to proceed. +That said, sometimes merges will bring in SDK or dependency updates that can cause breaks in seemingly unrelated areas. +In such cases, you should investigate and solve the issues as needed. + ## Committing your changes If you have to make any changes for validations to pass, consider whether they qualify as a bad merge conflict resolution or more of a novel change that you're making to work with the Library.Template update. From ca9f8e977e1a9cafc986fb14974953e6f9a0ee57 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Feb 2026 00:16:24 +0000 Subject: [PATCH 095/174] Update Dockerfile and global.json updates to v10.0.103 (477) * Update mcr.microsoft.com/dotnet/sdk Docker tag to v10.0.103 * Bump global.json as well --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Andrew Arnott --- .devcontainer/Dockerfile | 2 +- global.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 50883c3..95ac1b5 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.102@sha256:6ba533cc61a5d8c5e7d4b3a3e33e2ddc2efef200b112e4d658303516bfd24255 +FROM mcr.microsoft.com/dotnet/sdk:10.0.103@sha256:89e985253248c1211e8440b82db775fd3d3c73c915ceb96766495bce050d385f # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. diff --git a/global.json b/global.json index d8d718a..bdc382f 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.102", + "version": "10.0.103", "rollForward": "patch", "allowPrerelease": false }, From 467ef6db1e8babe19b4f5e044574479bd2404af2 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 11 Feb 2026 08:20:40 -0700 Subject: [PATCH 096/174] Explain how to migrate sln to slnx --- .github/prompts/template-release-notes.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/prompts/template-release-notes.md b/.github/prompts/template-release-notes.md index 0e5e2d8..975da31 100644 --- a/.github/prompts/template-release-notes.md +++ b/.github/prompts/template-release-notes.md @@ -8,5 +8,13 @@ This file is referenced by update-library-template.prompt.md and should remain i Never leave a Library.slnx file in the repository. You might even see one there even though this particular merge didn't bring it in. This can be an artifact of having renamed Library.sln to Library.slnx in the template repo, but ultimately the receiving repo should have only one .sln or .slnx file, with a better name than `Library`. -If you can confidently do so, go ahead and migrate their `.sln` to an `.slnx` with their original name. -If you can't, just delete `Library.slnx` anyway. +Delete any `Library.slnx` that you see. +Migrate an `.sln` in the repo root to `.slnx` using this command: + +```ps1 +dotnet solution EXISTING.sln migrate +``` + +This will create an EXISTING.slnx file. `git add` that file, then `git rm` the old `.sln` file. +Sometimes a repo will reference the sln filename in a script or doc somewhere. +Search the repo for such references and update them to the slnx file. From 04993f61ce55d17ee7c7f1b1ef9c9391fb4b9f7d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Feb 2026 10:30:11 -0700 Subject: [PATCH 097/174] Update mcr.microsoft.com/dotnet/sdk:10.0.103 Docker digest to 0a506ab (478) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 95ac1b5..3df45f8 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.103@sha256:89e985253248c1211e8440b82db775fd3d3c73c915ceb96766495bce050d385f +FROM mcr.microsoft.com/dotnet/sdk:10.0.103@sha256:0a506ab0c8aa077361af42f82569d364ab1b8741e967955d883e3f23683d473a # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. From 54a80db48a9062c4f81676ffbc7c807f6bae8417 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 12:49:50 -0700 Subject: [PATCH 098/174] Update dependency nerdbank.dotnetrepotools to v1.1.1 (479) --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 1418b91..c22a2eb 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -31,7 +31,7 @@ "rollForward": false }, "nerdbank.dotnetrepotools": { - "version": "1.0.92", + "version": "1.1.1", "commands": [ "repo" ], From 41493c6aba7c6b1e9018cbf0f22f0a8cb32d47d0 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 17 Feb 2026 11:08:54 -0700 Subject: [PATCH 099/174] Use forward slash in md files --- .github/prompts/update-library-template.prompt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/prompts/update-library-template.prompt.md b/.github/prompts/update-library-template.prompt.md index cfabcb3..fae1a1e 100644 --- a/.github/prompts/update-library-template.prompt.md +++ b/.github/prompts/update-library-template.prompt.md @@ -44,7 +44,7 @@ Use #runSubagent for each step. 1. Verify that `dotnet restore` succeeds. Fix any issues that come up. 2. Verify that `dotnet build` succeeds. -3. Verify that tests succeed by running `tools\dotnet-test-cloud.ps1`. +3. Verify that tests succeed by running `tools/dotnet-test-cloud.ps1`. While these validations are described using `dotnet` CLI commands, some repos require using full msbuild.exe. You can detect this by checking the `azure-pipelines/dotnet.yml` or `.github/workflows/build.yml` files for use of one or the other tool. From 6dfee58e27e2c3aa037d9893dba85377b58d8ac2 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 17 Feb 2026 13:02:39 -0700 Subject: [PATCH 100/174] Touch-up custom prompt --- .github/prompts/update-library-template.prompt.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/prompts/update-library-template.prompt.md b/.github/prompts/update-library-template.prompt.md index fae1a1e..f9fe672 100644 --- a/.github/prompts/update-library-template.prompt.md +++ b/.github/prompts/update-library-template.prompt.md @@ -4,10 +4,10 @@ description: Merges the latest Library.Template into this repo (at position of H # Instructions -1. Run `tools\MergeFrom-Template.ps1` +1. Run `tools/MergeFrom-Template.ps1` 2. Resolve merge conflicts, taking into account conflict resolution policy below. 3. Validate the changes, as described in the validation section below. -4. Commiting your changes (if applicable). +4. Committing your changes (if applicable). ## Conflict resolution policy @@ -33,7 +33,7 @@ Conflicts in the following files should always be resolved by keeping the curren Very typically, when the incoming change is to a file that was deleted locally, the correct resolution is to re-delete the file. In some cases however, the deleted file may have incoming changes that should be applied to other files. -The `test\Library.Tests\Library.Tests.csproj` file is very typical of this. +The `test/Library.Tests/Library.Tests.csproj` file is very typical of this. Changes to this file should very typically be applied to any and all test projects in the repo. You are responsible for doing this in addition to re-deleting this template file. From 4d1026d5b7304a392707163f257c5f9af981ef0e Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 18 Feb 2026 16:02:56 -0700 Subject: [PATCH 101/174] Update network isolation policy --- azure-pipelines/archive-sourcecode.yml | 2 +- azure-pipelines/libtemplate-update.yml | 2 +- azure-pipelines/official.yml | 2 +- azure-pipelines/release.yml | 2 +- azure-pipelines/unofficial.yml | 2 +- azure-pipelines/vs-insertion.yml | 2 +- azure-pipelines/vs-validation.yml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/azure-pipelines/archive-sourcecode.yml b/azure-pipelines/archive-sourcecode.yml index ee349e5..84b70ec 100644 --- a/azure-pipelines/archive-sourcecode.yml +++ b/azure-pipelines/archive-sourcecode.yml @@ -36,7 +36,7 @@ extends: template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate parameters: settings: - networkIsolationPolicy: Permissive,CFSClean + networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable diff --git a/azure-pipelines/libtemplate-update.yml b/azure-pipelines/libtemplate-update.yml index a0421bd..6d0051a 100644 --- a/azure-pipelines/libtemplate-update.yml +++ b/azure-pipelines/libtemplate-update.yml @@ -31,7 +31,7 @@ extends: template: azure-pipelines/MicroBuild.1ES.Unofficial.yml@MicroBuildTemplate parameters: settings: - networkIsolationPolicy: Permissive,CFSClean + networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: name: AzurePipelines-EO diff --git a/azure-pipelines/official.yml b/azure-pipelines/official.yml index 0956e88..9f0a89d 100644 --- a/azure-pipelines/official.yml +++ b/azure-pipelines/official.yml @@ -46,7 +46,7 @@ extends: template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate parameters: settings: - networkIsolationPolicy: Permissive,CFSClean + networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable codeSignValidation: diff --git a/azure-pipelines/release.yml b/azure-pipelines/release.yml index 38e9a3b..5824b0a 100644 --- a/azure-pipelines/release.yml +++ b/azure-pipelines/release.yml @@ -21,7 +21,7 @@ extends: template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate parameters: settings: - networkIsolationPolicy: Permissive,CFSClean + networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable diff --git a/azure-pipelines/unofficial.yml b/azure-pipelines/unofficial.yml index 7daa9e6..47a2a2e 100644 --- a/azure-pipelines/unofficial.yml +++ b/azure-pipelines/unofficial.yml @@ -56,7 +56,7 @@ extends: template: azure-pipelines/MicroBuild.1ES.Unofficial.yml@MicroBuildTemplate parameters: settings: - networkIsolationPolicy: Permissive,CFSClean + networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable credscan: diff --git a/azure-pipelines/vs-insertion.yml b/azure-pipelines/vs-insertion.yml index faeadd8..22481c9 100644 --- a/azure-pipelines/vs-insertion.yml +++ b/azure-pipelines/vs-insertion.yml @@ -23,7 +23,7 @@ extends: template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate parameters: settings: - networkIsolationPolicy: Permissive,CFSClean + networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable sbom: diff --git a/azure-pipelines/vs-validation.yml b/azure-pipelines/vs-validation.yml index d150fee..f623731 100644 --- a/azure-pipelines/vs-validation.yml +++ b/azure-pipelines/vs-validation.yml @@ -27,7 +27,7 @@ extends: template: azure-pipelines/MicroBuild.1ES.Unofficial.yml@MicroBuildTemplate parameters: settings: - networkIsolationPolicy: Permissive,CFSClean + networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable credscan: From 6103b65b8fa48cb06b355f4f3419cdee3620de45 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 23 Feb 2026 12:55:23 -0700 Subject: [PATCH 102/174] Only disable NBGV_GitEngine when necessary --- .github/Prime-ForCopilot.ps1 | 5 +++++ .github/copilot-instructions.md | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .github/Prime-ForCopilot.ps1 diff --git a/.github/Prime-ForCopilot.ps1 b/.github/Prime-ForCopilot.ps1 new file mode 100644 index 0000000..4de91ab --- /dev/null +++ b/.github/Prime-ForCopilot.ps1 @@ -0,0 +1,5 @@ +if ((git rev-parse --is-shallow-repository) -eq 'true') +{ + Write-Host "Shallow clone detected, disabling NBGV Git engine so the build can succeed." + $env:NBGV_GitEngine='Disabled' +} diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index deb2953..654fbfe 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -3,7 +3,8 @@ ## High level guidance * Review the `CONTRIBUTING.md` file for instructions to build and test the software. -* Set the `NBGV_GitEngine` environment variable to `Disabled` before running any `dotnet` or `msbuild` commands. +* Run the `.github\Prime-ForCopilot.ps1` script (once) before running any `dotnet` or `msbuild` commands. + If you see any build errors about not finding git objects or a shallow clone, it may be time to run this script again. ## Software Design From c04c3a806f192422e315d5645941ba62df9a8b7a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 07:51:54 -0700 Subject: [PATCH 103/174] Merge pull request 481 from AArnott/renovate/docfx-2.x Update dependency docfx to v2.78.5 --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index c22a2eb..20472ac 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -24,7 +24,7 @@ "rollForward": false }, "docfx": { - "version": "2.78.4", + "version": "2.78.5", "commands": [ "docfx" ], From f4c9c8108cc71be37ff4fe2d661fd2c2c8469b51 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 24 Feb 2026 07:52:14 -0700 Subject: [PATCH 104/174] Update mcr.microsoft.com/dotnet/sdk:10.0.103 Docker digest to e362a8d (480) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 3df45f8..8fc20d6 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.103@sha256:0a506ab0c8aa077361af42f82569d364ab1b8741e967955d883e3f23683d473a +FROM mcr.microsoft.com/dotnet/sdk:10.0.103@sha256:e362a8dbcd691522456da26a5198b8f3ca1d7641c95624fadc5e3e82678bd08a # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. From a9b48e169f97cfa22a2b18c3d031807f73583545 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Feb 2026 06:35:36 -0700 Subject: [PATCH 105/174] Update dependency dotnet-coverage to v18.5.1 (483) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 20472ac..b1bd90b 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -10,7 +10,7 @@ "rollForward": false }, "dotnet-coverage": { - "version": "18.4.1", + "version": "18.5.1", "commands": [ "dotnet-coverage" ], From 824209761c8a0614a8e921cd642c05c2064d3d5b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Feb 2026 06:36:11 -0700 Subject: [PATCH 106/174] Update dependency Microsoft.Testing.Extensions.CodeCoverage to 18.5.1 (484) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 73d0d36..37275ba 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,7 +10,7 @@ - + From 2960fc588ac92372e603de9b1f5ab84c054668b4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Feb 2026 06:36:42 -0700 Subject: [PATCH 107/174] Update GitHub Artifact Actions (482) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/actions/publish-artifacts/action.yaml | 14 +++++++------- .github/workflows/release.yml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/actions/publish-artifacts/action.yaml b/.github/actions/publish-artifacts/action.yaml index e024682..9982cf1 100644 --- a/.github/actions/publish-artifacts/action.yaml +++ b/.github/actions/publish-artifacts/action.yaml @@ -14,46 +14,46 @@ runs: - name: ๐Ÿ“ข Upload project.assets.json files if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: projectAssetsJson-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/projectAssetsJson continue-on-error: true - name: ๐Ÿ“ข Upload variables - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: variables-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/Variables continue-on-error: true - name: ๐Ÿ“ข Upload build_logs if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: build_logs-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/build_logs continue-on-error: true - name: ๐Ÿ“ข Upload testResults if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: testResults-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/testResults continue-on-error: true - name: ๐Ÿ“ข Upload coverageResults if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: coverageResults-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/coverageResults continue-on-error: true - name: ๐Ÿ“ข Upload symbols - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: symbols-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/symbols continue-on-error: true - name: ๐Ÿ“ข Upload deployables - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: deployables-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/deployables diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 51b1138..4c2f0a5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,7 +57,7 @@ jobs: Echo "runid=$runid" >> $env:GITHUB_OUTPUT - name: ๐Ÿ”ป Download deployables artifacts - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: name: deployables-Linux path: ${{ runner.temp }}/deployables From 582d263d8bd5c187aa9e6e0047f152809fe8ed77 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Fri, 27 Feb 2026 23:17:43 -0700 Subject: [PATCH 108/174] Bump DotNetRepoTools to 1.2.1 --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index b1bd90b..9e18782 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -31,7 +31,7 @@ "rollForward": false }, "nerdbank.dotnetrepotools": { - "version": "1.1.1", + "version": "1.2.1", "commands": [ "repo" ], From 85514fab35853970d769db0f762941b6ddb88c48 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 09:51:43 -0700 Subject: [PATCH 109/174] Update dependency Microsoft.Testing.Extensions.CodeCoverage to 18.5.2 (486) --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 37275ba..0657db8 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,7 +10,7 @@ - + From ebc35701512d7c7b7b3bce3fedd46d7f0c7243bb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 09:51:54 -0700 Subject: [PATCH 110/174] Update dependency dotnet-coverage to v18.5.2 (485) --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 9e18782..16f077b 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -10,7 +10,7 @@ "rollForward": false }, "dotnet-coverage": { - "version": "18.5.1", + "version": "18.5.2", "commands": [ "dotnet-coverage" ], From e4a2493e50089f6c2872da08bb46da972499cad8 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Fri, 6 Mar 2026 09:33:43 -0700 Subject: [PATCH 111/174] Fix warning message --- tools/variables/ProfilingInputsPropsName.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/variables/ProfilingInputsPropsName.ps1 b/tools/variables/ProfilingInputsPropsName.ps1 index e66cce0..9e6bc4a 100644 --- a/tools/variables/ProfilingInputsPropsName.ps1 +++ b/tools/variables/ProfilingInputsPropsName.ps1 @@ -2,5 +2,5 @@ if ($env:SYSTEM_TEAMPROJECT) { $repoName = $env:BUILD_REPOSITORY_NAME.Replace('/', '.') "$env:SYSTEM_TEAMPROJECT.$repoName.props" } else { - Write-Warning "No Azure Pipelines build detected. No Azure Pipelines drop name will be computed." + Write-Warning "No Azure Pipelines build detected. No profiling inputs filename will be computed." } From 41b6a219f210a07213e2c3d354c0c304378bbbc6 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Fri, 6 Mar 2026 10:14:42 -0700 Subject: [PATCH 112/174] Fix Prime-ForCopilot.ps1 when invoked from outside the repo --- .github/Prime-ForCopilot.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/Prime-ForCopilot.ps1 b/.github/Prime-ForCopilot.ps1 index 4de91ab..e0b1fb7 100644 --- a/.github/Prime-ForCopilot.ps1 +++ b/.github/Prime-ForCopilot.ps1 @@ -1,4 +1,4 @@ -if ((git rev-parse --is-shallow-repository) -eq 'true') +if ((git -C $PSScriptRoot rev-parse --is-shallow-repository) -eq 'true') { Write-Host "Shallow clone detected, disabling NBGV Git engine so the build can succeed." $env:NBGV_GitEngine='Disabled' From 2e49a12aa3315019b7fe89d0d88cf41bc9215d90 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Fri, 6 Mar 2026 10:14:52 -0700 Subject: [PATCH 113/174] Use forward slashes consistently in docs --- .github/copilot-instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 654fbfe..0187843 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -3,7 +3,7 @@ ## High level guidance * Review the `CONTRIBUTING.md` file for instructions to build and test the software. -* Run the `.github\Prime-ForCopilot.ps1` script (once) before running any `dotnet` or `msbuild` commands. +* Run the `.github/Prime-ForCopilot.ps1` script (once) before running any `dotnet` or `msbuild` commands. If you see any build errors about not finding git objects or a shallow clone, it may be time to run this script again. ## Software Design From 62a1ccc2379f534f60922690bc4eecc373c2b625 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Fri, 6 Mar 2026 10:17:11 -0700 Subject: [PATCH 114/174] Avoid assigning to an unused variable --- tools/Prepare-Legacy-Symbols.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Prepare-Legacy-Symbols.ps1 b/tools/Prepare-Legacy-Symbols.ps1 index e566d62..0ab7e4f 100644 --- a/tools/Prepare-Legacy-Symbols.ps1 +++ b/tools/Prepare-Legacy-Symbols.ps1 @@ -22,7 +22,7 @@ Get-ChildItem "$ArtifactStagingFolder\*.pdb" -Recurse |% { if ($BinaryImagePath) { # Native binaries can't have their PDBs converted to legacy (Windows) format so just skip them try { - $assembly = [System.Reflection.AssemblyName]::GetAssemblyName($BinaryImagePath) + [System.Reflection.AssemblyName]::GetAssemblyName($BinaryImagePath) | Out-Null $isManaged = $true } catch { From 0a7200aa069f5583d11ef44d15f50ef603ece7af Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Fri, 6 Mar 2026 12:58:19 -0700 Subject: [PATCH 115/174] Avoid returning early while preparing legacy symbols --- tools/Prepare-Legacy-Symbols.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Prepare-Legacy-Symbols.ps1 b/tools/Prepare-Legacy-Symbols.ps1 index 0ab7e4f..8a007c2 100644 --- a/tools/Prepare-Legacy-Symbols.ps1 +++ b/tools/Prepare-Legacy-Symbols.ps1 @@ -31,7 +31,7 @@ Get-ChildItem "$ArtifactStagingFolder\*.pdb" -Recurse |% { if (-not $isManaged) { Write-Host "Skipping native binary PDB: $_" -ForegroundColor DarkYellow - return + continue } # Convert the PDB to legacy Windows PDBs From 7d4a9ecbc8274a7f659273542c27b2addf4b1b49 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 07:12:27 -0600 Subject: [PATCH 116/174] Update Dockerfile and global.json updates to v10.0.200 (487) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- global.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 8fc20d6..5a23e80 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.103@sha256:e362a8dbcd691522456da26a5198b8f3ca1d7641c95624fadc5e3e82678bd08a +FROM mcr.microsoft.com/dotnet/sdk:10.0.200@sha256:ea13841f10c6c410a6df63c6c97ab549dfd2b5fcfff1c00186531ba30208117d # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. diff --git a/global.json b/global.json index bdc382f..c98253b 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.103", + "version": "10.0.200", "rollForward": "patch", "allowPrerelease": false }, From c20fa1afa282a1cb410d1bab4d5cf61a50fed82b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 15:19:29 -0600 Subject: [PATCH 117/174] Update dependency powershell to v7.5.5 (#489) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 16f077b..d4570a6 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "powershell": { - "version": "7.5.4", + "version": "7.5.5", "commands": [ "pwsh" ], From 56dfa063913051dee37780664e70d16025f50850 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 15:20:08 -0600 Subject: [PATCH 118/174] Update actions/download-artifact action to v8.0.1 (488) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4c2f0a5..11bebbe 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,7 +57,7 @@ jobs: Echo "runid=$runid" >> $env:GITHUB_OUTPUT - name: ๐Ÿ”ป Download deployables artifacts - uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: deployables-Linux path: ${{ runner.temp }}/deployables From b58cafc7bf3a81eee5db7408b01b9405058626e8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 20:05:11 -0600 Subject: [PATCH 119/174] Update Dockerfile and global.json updates to v10.0.201 (490) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- global.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 5a23e80..ab98561 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.200@sha256:ea13841f10c6c410a6df63c6c97ab549dfd2b5fcfff1c00186531ba30208117d +FROM mcr.microsoft.com/dotnet/sdk:10.0.201@sha256:478b9038d187e5b5c29bfa8173ded5d29e864b5ad06102a12106380ee01e2e49 # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. diff --git a/global.json b/global.json index c98253b..c331692 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.200", + "version": "10.0.201", "rollForward": "patch", "allowPrerelease": false }, From 326764f52487bcb3bc3d09c6bace30c5fdd2ebfc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2026 14:45:44 +1300 Subject: [PATCH 120/174] Update dependency powershell to v7.6.0 (#491) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index d4570a6..7c912c3 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "powershell": { - "version": "7.5.5", + "version": "7.6.0", "commands": [ "pwsh" ], From 330fbbed2b433d111128ebce59152a12047f7488 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:06:43 -0600 Subject: [PATCH 121/174] Update actions/deploy-pages action to v5 (492) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 53af0a0..e19cf64 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -40,4 +40,4 @@ jobs: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 + uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 From c7e63e775696a62eed687d0bd01394576b8d9f77 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 30 Mar 2026 12:16:41 -0600 Subject: [PATCH 122/174] Harden path joining in VSInsertion.ps1 --- tools/artifacts/VSInsertion.ps1 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/artifacts/VSInsertion.ps1 b/tools/artifacts/VSInsertion.ps1 index 700b24f..2858f7f 100644 --- a/tools/artifacts/VSInsertion.ps1 +++ b/tools/artifacts/VSInsertion.ps1 @@ -21,7 +21,7 @@ $NuGetPackages = "$PackagesRoot/NuGet" $VsixPackages = "$PackagesRoot/Vsix" $AzurePipelinesPath = "$RepoRoot/azure-pipelines" if ($env:BUILD_ARTIFACTSTAGINGDIRECTORY) { - $InsertionOutputs = "$env:BUILD_ARTIFACTSTAGINGDIRECTORY/InsertionOutputs" + $InsertionOutputs = Join-Path $env:BUILD_ARTIFACTSTAGINGDIRECTORY 'InsertionOutputs' } if (!(Test-Path $NuGetPackages) -and !(Test-Path $VsixPackages)) { @@ -38,8 +38,11 @@ if (Test-Path $VsixPackages) { $result["$PackagesRoot"] += Get-ChildItem $VsixPackages -Recurse } -if ($InsertionOutputs -and $env:PROFILINGINPUTSPROPSNAME -and (Test-Path "$InsertionOutputs/$env:PROFILINGINPUTSPROPSNAME")) { - $result[$InsertionOutputs] = (Get-ChildItem "$InsertionOutputs/$env:PROFILINGINPUTSPROPSNAME"); # OptProf ProfilingInputs +if ($InsertionOutputs -and $env:PROFILINGINPUTSPROPSNAME) { + $InsertOutputsProfilingInputs = Join-Path $InsertionOutputs $env:PROFILINGINPUTSPROPSNAME + if (Test-Path -LiteralPath $InsertOutputsProfilingInputs) { + $result[$InsertionOutputs] = Get-ChildItem -LiteralPath $InsertOutputsProfilingInputs # OptProf ProfilingInputs + } } $result From 2106ee95755f1d396f026a8b3ddd3a56cfb35d0d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 4 Apr 2026 06:24:10 -0600 Subject: [PATCH 123/174] Update mcr.microsoft.com/dotnet/sdk:10.0.201 Docker digest to f061e5a (493) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ab98561..14b064d 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.201@sha256:478b9038d187e5b5c29bfa8173ded5d29e864b5ad06102a12106380ee01e2e49 +FROM mcr.microsoft.com/dotnet/sdk:10.0.201@sha256:f061e5a7532b36fa1d1b684857fe1f504ba92115b9934f154643266613c44c62 # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. From 3c72508949517b488ea7adff2f44d3f13d00abe3 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 6 Apr 2026 12:20:23 -0600 Subject: [PATCH 124/174] Harden release workflow to use better runs --- .github/workflows/release.yml | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 11bebbe..a14587a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,16 +40,30 @@ jobs: Write-Host "Resolved ${{ github.ref_name }} to $commitSha" - $releases = gh run list -R ${{ github.repository }} -c $commitSha -w .github/workflows/build.yml -s success --json databaseId,startedAt ` + $releases = gh run list -R ${{ github.repository }} -c $commitSha -w .github/workflows/build.yml -s success --json databaseId,startedAt,event,headBranch ` | ConvertFrom-Json | Sort-Object startedAt -Descending + $preferredReleases = $releases | Where-Object { + $_.event -eq 'push' -and ($_.headBranch -eq 'main' -or $_.headBranch -match '^v\d+(?:\.\d+)?$') + } + if ($releases.length -eq 0) { Write-Error "No successful builds found for ${{ github.ref }}." - } elseif ($releases.length -gt 1) { - Write-Warning "More than one successful run found for ${{ github.ref }}. Artifacts from the most recent successful run will ship." - } + } else { + if ($preferredReleases.length -gt 0) { + $selectedReleases = $preferredReleases + $multipleRunsWarning = "More than one successful run found for ${{ github.ref }}. Preferring the most recent push build from a public-release branch." + } else { + $selectedReleases = $releases + $multipleRunsWarning = "More than one successful run found for ${{ github.ref }} and none were from a public-release branch. Artifacts from the most recent successful run will ship." + } - $runid = $releases[0].databaseId + if ($releases.length -gt 1) { + Write-Warning $multipleRunsWarning + } + + $runid = $selectedReleases[0].databaseId + } } Write-Host "Using artifacts from run-id: $runid" From f398becc80f946a9c52ba2f2ed1146da4716aded Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 6 Apr 2026 12:29:37 -0600 Subject: [PATCH 125/174] Fix the build status badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa2dfb5..3f8c976 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ![NuGet package](https://img.shields.io/badge/nuget-your--package--here-yellow.svg) [![Azure Pipelines status](https://dev.azure.com/andrewarnott/OSS/_apis/build/status/AArnott.Library.Template?branchName=main)](https://dev.azure.com/andrewarnott/OSS/_build/latest?definitionId=29&branchName=main) -![GitHub Actions status](https://github.com/aarnott/Library.Template/workflows/CI/badge.svg) +[![๐Ÿญ Build](https://github.com/AArnott/Library.Template/actions/workflows/build.yml/badge.svg)](https://github.com/AArnott/Library.Template/actions/workflows/build.yml) [![codecov](https://codecov.io/gh/aarnott/library.template/branch/main/graph/badge.svg)](https://codecov.io/gh/aarnott/library.template) ## Features From 903963452da5c47500f9620688b6fbd7e723a2c2 Mon Sep 17 00:00:00 2001 From: Andrii Tretiak Date: Mon, 6 Apr 2026 11:33:12 -0700 Subject: [PATCH 126/174] Switch from using nuget.exe to dotnet cli commands (#494) * Switch from using nuget.exe to dotnet cli commands * Fix Download-NuGetPackage failure and version selection --------- Co-authored-by: Andrew Arnott --- tools/Download-NuGetPackage.ps1 | 77 +++++++++++++++++++++++++++++++ tools/Get-3rdPartySymbolFiles.ps1 | 50 +++++++++++--------- tools/Get-NuGetTool.ps1 | 22 --------- tools/Get-ProcDump.ps1 | 6 +-- tools/Install-NuGetPackage.ps1 | 63 ------------------------- 5 files changed, 108 insertions(+), 110 deletions(-) create mode 100644 tools/Download-NuGetPackage.ps1 delete mode 100644 tools/Get-NuGetTool.ps1 delete mode 100644 tools/Install-NuGetPackage.ps1 diff --git a/tools/Download-NuGetPackage.ps1 b/tools/Download-NuGetPackage.ps1 new file mode 100644 index 0000000..924b9ed --- /dev/null +++ b/tools/Download-NuGetPackage.ps1 @@ -0,0 +1,77 @@ +<# +.SYNOPSIS + Downloads a NuGet package to a local folder using dotnet package download. +.PARAMETER PackageId + The Package ID to download. +.PARAMETER Version + The version of the package to download. If unspecified, the latest version is downloaded. +.PARAMETER Source + An additional package source to search. Used as a fallback alongside the configured feeds. +.PARAMETER OutputDirectory + The directory to download the package to. By default, it uses the obj\tools folder at the root of the repo. +.PARAMETER ConfigFile + The nuget.config file to use. By default, it uses the repo root nuget.config. +.PARAMETER Verbosity + The verbosity level for the download. Defaults to quiet. +.OUTPUTS + System.String. The path to the downloaded package directory. +#> +[CmdletBinding()] +Param( + [Parameter(Position=1,Mandatory=$true)] + [string]$PackageId, + [Parameter()] + [string]$Version, + [Parameter()] + [string]$Source, + [Parameter()] + [string]$OutputDirectory="$PSScriptRoot\..\obj\tools", + [Parameter()] + [string]$ConfigFile="$PSScriptRoot\..\nuget.config", + [Parameter()] + [ValidateSet('quiet','minimal','normal','detailed','diagnostic')] + [string]$Verbosity='quiet' +) + +if (!(Test-Path $OutputDirectory)) { New-Item -ItemType Directory -Path $OutputDirectory -Force | Out-Null } +$OutputDirectory = (Resolve-Path $OutputDirectory).Path +$ConfigFile = (Resolve-Path $ConfigFile).Path + +$packageArg = $PackageId +if ($Version) { $packageArg = "$PackageId@$Version" } + +$extraArgs = @() +if ($Source) { $extraArgs += '--source', $Source } + +$prevErrorActionPreference = $ErrorActionPreference +$ErrorActionPreference = 'Continue' +& dotnet package download $packageArg --configfile $ConfigFile --output $OutputDirectory --verbosity $Verbosity @extraArgs 2>&1 | Out-Null +$downloadExitCode = $LASTEXITCODE +$ErrorActionPreference = $prevErrorActionPreference + +if ($downloadExitCode -ne 0) { + throw "Failed to download package $packageArg (exit code $downloadExitCode)." +} + +# Return the path to the downloaded package directory (dotnet package download uses lowercase id) +$packageIdLower = $PackageId.ToLower() +if ($Version) { + $packageRoot = Join-Path $OutputDirectory $packageIdLower + $packageDir = Get-ChildItem -Path $packageRoot -Directory -ErrorAction SilentlyContinue | + Where-Object { $_.Name -ieq $Version } | + Select-Object -First 1 + if ($packageDir) { $packageDir = $packageDir.FullName } +} else { + # When no version is specified, pick the most recently written version directory. + $packageRoot = Join-Path $OutputDirectory $packageIdLower + $packageDir = Get-ChildItem -Path $packageRoot -Directory -ErrorAction SilentlyContinue | + Sort-Object -Property LastWriteTimeUtc -Descending | + Select-Object -First 1 + if ($packageDir) { $packageDir = $packageDir.FullName } +} + +if ($packageDir -and (Test-Path $packageDir)) { + Write-Output $packageDir +} else { + Write-Error "Package directory not found after download." +} diff --git a/tools/Get-3rdPartySymbolFiles.ps1 b/tools/Get-3rdPartySymbolFiles.ps1 index ef6bbef..7e15f91 100644 --- a/tools/Get-3rdPartySymbolFiles.ps1 +++ b/tools/Get-3rdPartySymbolFiles.ps1 @@ -1,16 +1,8 @@ -Function Get-FileFromWeb([Uri]$Uri, $OutFile) { - $OutDir = Split-Path $OutFile - if (!(Test-Path $OutFile)) { - Write-Verbose "Downloading $Uri..." - if (!(Test-Path $OutDir)) { New-Item -ItemType Directory -Path $OutDir | Out-Null } - try { - (New-Object System.Net.WebClient).DownloadFile($Uri, $OutFile) - } - finally { - # This try/finally causes the script to abort - } - } -} +# Symbol servers to search for PDBs, in order of priority. +$SymbolServers = @( + 'https://msdl.microsoft.com/download/symbols' + 'https://symbols.nuget.org/download/symbols' +) Function Unzip($Path, $OutDir) { $OutDir = (New-Item -ItemType Directory -Path $OutDir -Force).FullName @@ -33,17 +25,31 @@ Function Unzip($Path, $OutDir) { Function Get-SymbolsFromPackage($id, $version) { $symbolPackagesPath = "$PSScriptRoot/../obj/SymbolsPackages" New-Item -ItemType Directory -Path $symbolPackagesPath -Force | Out-Null - $nupkgPath = Join-Path $symbolPackagesPath "$id.$version.nupkg" - $snupkgPath = Join-Path $symbolPackagesPath "$id.$version.snupkg" $unzippedPkgPath = Join-Path $symbolPackagesPath "$id.$version" - Get-FileFromWeb -Uri "https://www.nuget.org/api/v2/package/$id/$version" -OutFile $nupkgPath - Get-FileFromWeb -Uri "https://www.nuget.org/api/v2/symbolpackage/$id/$version" -OutFile $snupkgPath - Unzip -Path $nupkgPath -OutDir $unzippedPkgPath - Unzip -Path $snupkgPath -OutDir $unzippedPkgPath + # Download the package from configured feeds (failures are non-fatal for symbol collection) + & "$PSScriptRoot\Download-NuGetPackage.ps1" -PackageId $id -Version $version -OutputDirectory $symbolPackagesPath -ErrorAction SilentlyContinue | Out-Null + $global:LASTEXITCODE = 0 + $nupkgFile = Get-ChildItem -Recurse -Path $symbolPackagesPath -Filter "$id.$version.nupkg" -ErrorAction SilentlyContinue | Select-Object -First 1 + if (!$nupkgFile) { + Write-Warning "Package $id $version not found in configured feeds. Skipping." + return + } + + Unzip -Path $nupkgFile.FullName -OutDir $unzippedPkgPath + + # Download symbols for each binary using dotnet-symbol + $serverArgs = $SymbolServers | ForEach-Object { '--server-path'; $_ } + $binaries = Get-ChildItem -Recurse -LiteralPath $unzippedPkgPath -Include *.dll, *.exe + foreach ($binary in $binaries) { + $prevErrorActionPreference = $ErrorActionPreference + $ErrorActionPreference = 'Continue' + & dotnet symbol --symbols @serverArgs --output $binary.DirectoryName $binary.FullName 2>&1 | Out-Null + $ErrorActionPreference = $prevErrorActionPreference + } + # Output pairs of binary + PDB paths for archival Get-ChildItem -Recurse -LiteralPath $unzippedPkgPath -Filter *.pdb | % { - # Collect the DLLs/EXEs as well. $rootName = Join-Path $_.Directory $_.BaseName if ($rootName.EndsWith('.ni')) { $rootName = $rootName.Substring(0, $rootName.Length - 3) @@ -80,7 +86,9 @@ Function Get-PackageVersion($id) { } # All 3rd party packages for which symbols packages are expected should be listed here. -# These must all be sourced from nuget.org, as it is the only feed that supports symbol packages. +# Packages are downloaded from configured feeds in nuget.config. +# We should NOT add 3rd party packages to this list because PDBs may be unsafe for our debuggers to load, +# so we should only archive 1st party symbols. $3rdPartyPackageIds = @() $3rdPartyPackageIds | % { diff --git a/tools/Get-NuGetTool.ps1 b/tools/Get-NuGetTool.ps1 deleted file mode 100644 index bed0cba..0000000 --- a/tools/Get-NuGetTool.ps1 +++ /dev/null @@ -1,22 +0,0 @@ -<# -.SYNOPSIS - Downloads the NuGet.exe tool and returns the path to it. -.PARAMETER NuGetVersion - The version of the NuGet tool to acquire. -#> -Param( - [Parameter()] - [string]$NuGetVersion='6.14.0' -) - -$toolsPath = & "$PSScriptRoot\Get-TempToolsPath.ps1" -$binaryToolsPath = Join-Path $toolsPath $NuGetVersion -if (!(Test-Path $binaryToolsPath)) { $null = mkdir $binaryToolsPath } -$nugetPath = Join-Path $binaryToolsPath nuget.exe - -if (!(Test-Path $nugetPath)) { - Write-Host "Downloading nuget.exe $NuGetVersion..." -ForegroundColor Yellow - (New-Object System.Net.WebClient).DownloadFile("https://dist.nuget.org/win-x86-commandline/v$NuGetVersion/NuGet.exe", $nugetPath) -} - -return (Resolve-Path $nugetPath).Path diff --git a/tools/Get-ProcDump.ps1 b/tools/Get-ProcDump.ps1 index 1493fe4..8b1f7d1 100644 --- a/tools/Get-ProcDump.ps1 +++ b/tools/Get-ProcDump.ps1 @@ -4,11 +4,9 @@ Downloads 32-bit and 64-bit procdump executables and returns the path to where t #> $version = '0.0.1' $baseDir = "$PSScriptRoot\..\obj\tools" -$procDumpToolPath = "$baseDir\procdump.$version\bin" +$procDumpToolPath = "$baseDir\procdump\$version\bin" if (-not (Test-Path $procDumpToolPath)) { - if (-not (Test-Path $baseDir)) { New-Item -Type Directory -Path $baseDir | Out-Null } - $baseDir = (Resolve-Path $baseDir).Path # Normalize it - & (& $PSScriptRoot\Get-NuGetTool.ps1) install procdump -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir -Source https://api.nuget.org/v3/index.json | Out-Null + & "$PSScriptRoot\Download-NuGetPackage.ps1" -PackageId procdump -Version $version -OutputDirectory $baseDir | Out-Null } (Resolve-Path $procDumpToolPath).Path diff --git a/tools/Install-NuGetPackage.ps1 b/tools/Install-NuGetPackage.ps1 deleted file mode 100644 index 3c11b0f..0000000 --- a/tools/Install-NuGetPackage.ps1 +++ /dev/null @@ -1,63 +0,0 @@ -<# -.SYNOPSIS - Installs a NuGet package. -.PARAMETER PackageID - The Package ID to install. -.PARAMETER Version - The version of the package to install. If unspecified, the latest stable release is installed. -.PARAMETER Source - The package source feed to find the package to install from. -.PARAMETER Prerelease - Include prerelease packages when searching for the latest version. -.PARAMETER ExcludeVersion - Installs the package without adding the version to the folder name. -.PARAMETER DirectDownload - Bypass the local cache when downloading packages. -.PARAMETER PackagesDir - The directory to install the package to. By default, it uses the Packages folder at the root of the repo. -.PARAMETER ConfigFile - The nuget.config file to use. By default, it uses :/nuget.config. -.OUTPUTS - System.String. The path to the installed package. -#> -[CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Low')] -Param( - [Parameter(Position=1,Mandatory=$true)] - [string]$PackageId, - [Parameter()] - [string]$Version, - [Parameter()] - [string]$Source, - [Parameter()] - [switch]$Prerelease, - [Parameter()] - [switch]$ExcludeVersion, - [Parameter()] - [switch]$DirectDownload, - [Parameter()] - [string]$PackagesDir="$PSScriptRoot\..\packages", - [Parameter()] - [string]$ConfigFile="$PSScriptRoot\..\nuget.config", - [Parameter()] - [ValidateSet('Quiet','Normal','Detailed')] - [string]$Verbosity='normal' -) - -$nugetPath = & "$PSScriptRoot\Get-NuGetTool.ps1" - -Write-Verbose "Installing $PackageId..." -$nugetArgs = "Install",$PackageId,"-OutputDirectory",$PackagesDir,'-ConfigFile',$ConfigFile -if ($Version) { $nugetArgs += "-Version",$Version } -if ($Source) { $nugetArgs += "-FallbackSource",$Source } -if ($Prerelease) { $nugetArgs += "-Prerelease" } -if ($ExcludeVersion) { $nugetArgs += '-ExcludeVersion' } -if ($DirectDownload) { $nugetArgs += '-DirectDownload' } -$nugetArgs += '-Verbosity',$Verbosity - -if ($PSCmdlet.ShouldProcess($PackageId, 'nuget install')) { - $p = Start-Process $nugetPath $nugetArgs -NoNewWindow -Wait -PassThru - if ($null -ne $p.ExitCode -and $p.ExitCode -ne 0) { throw } -} - -# Provide the path to the installed package directory to our caller. -Write-Output (Get-ChildItem "$PackagesDir\$PackageId.*")[0].FullName From 3ae7b3f2b706e1d497b9f9df6e819a73f08c71bf Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 6 Apr 2026 21:14:37 -0600 Subject: [PATCH 127/174] Fix Expand-Template --- Expand-Template.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Expand-Template.ps1 b/Expand-Template.ps1 index 568ee79..eb52532 100755 --- a/Expand-Template.ps1 +++ b/Expand-Template.ps1 @@ -158,7 +158,7 @@ try { Replace-Placeholders -Path "README.md" -Replacements @{ "(?m)^.*\[NuGet package\][^`r`n]*"="[![NuGet package](https://img.shields.io/nuget/v/$LibraryName.svg)](https://nuget.org/packages/$LibraryName)" "(?m)^.*\[Azure Pipelines status\].*`r?`n"="" - "(?m)^.*\[GitHub Actions status\].*`r?`n"="" + "(?m)^.*\ Build\].*`r?`n"="" "(?m)^.*\[codecov\].*`r?`n"="" } Replace-Placeholders -Path "docfx/docfx.json" -Replacements @{ From 8f9002cc5c14f1040d8998b242b2b495479c994a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2026 07:24:55 -0600 Subject: [PATCH 128/174] Update Microsoft Testing Platform to 2.2.1 (497) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 0657db8..546c6bc 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,7 +4,7 @@ true true - 2.1.0 + 2.2.1 From eca7d5692364420c7f248b98261fab811e58cf8e Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 7 Apr 2026 07:26:12 -0600 Subject: [PATCH 129/174] Update dependency dotnet-coverage to v18.6.2 --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 7c912c3..b380024 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -10,7 +10,7 @@ "rollForward": false }, "dotnet-coverage": { - "version": "18.5.2", + "version": "18.6.2", "commands": [ "dotnet-coverage" ], From 4266d52bb2512a350a1114e8e58ad917d1982945 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 7 Apr 2026 07:27:19 -0600 Subject: [PATCH 130/174] Update dependency Microsoft.Testing.Extensions.CodeCoverage to v18.6.2 --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 546c6bc..c20bfdc 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,7 +10,7 @@ - + From 58c98c495b2c771f56d5587b9945ca6e1a66eecf Mon Sep 17 00:00:00 2001 From: Andrii Tretiak Date: Tue, 7 Apr 2026 10:57:12 -0700 Subject: [PATCH 131/174] Remove usage of old NuGet tools (#496) * Remove usage of old NuGet tools * Add source for procdump package * Add feed for getting Microsoft.DiaSymReader.Pdb2Pdb * try Copilot suggested fixes * Add pre-release support --- init.ps1 | 14 +++++++------- tools/Convert-PDB.ps1 | 22 ++++++++++++---------- tools/Download-NuGetPackage.ps1 | 4 +++- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/init.ps1 b/init.ps1 index 8bb78ad..9c62b5e 100755 --- a/init.ps1 +++ b/init.ps1 @@ -126,40 +126,40 @@ try { } } - $InstallNuGetPkgScriptPath = "$PSScriptRoot\tools\Install-NuGetPackage.ps1" + $DownloadNuGetPkgScriptPath = "$PSScriptRoot\tools\Download-NuGetPackage.ps1" $nugetVerbosity = 'quiet' if ($Verbose) { $nugetVerbosity = 'normal' } $MicroBuildPackageSource = 'https://pkgs.dev.azure.com/devdiv/_packaging/MicroBuildToolset%40Local/nuget/v3/index.json' if ($Signing) { Write-Host "Installing MicroBuild signing plugin" -ForegroundColor $HeaderColor - & $InstallNuGetPkgScriptPath MicroBuild.Plugins.Signing -source $MicroBuildPackageSource -Verbosity $nugetVerbosity + & $DownloadNuGetPkgScriptPath -PackageId MicroBuild.Plugins.Signing -Source $MicroBuildPackageSource -Verbosity $nugetVerbosity $EnvVars['SignType'] = "Test" } if ($Setup) { Write-Host "Installing MicroBuild SwixBuild plugin..." -ForegroundColor $HeaderColor - & $InstallNuGetPkgScriptPath Microsoft.VisualStudioEng.MicroBuild.Plugins.SwixBuild -source $MicroBuildPackageSource -Verbosity $nugetVerbosity + & $DownloadNuGetPkgScriptPath -PackageId Microsoft.VisualStudioEng.MicroBuild.Plugins.SwixBuild -Source $MicroBuildPackageSource -Verbosity $nugetVerbosity } if ($OptProf) { Write-Host "Installing MicroBuild OptProf plugin" -ForegroundColor $HeaderColor - & $InstallNuGetPkgScriptPath MicroBuild.Plugins.OptProf -source $MicroBuildPackageSource -Verbosity $nugetVerbosity + & $DownloadNuGetPkgScriptPath -PackageId MicroBuild.Plugins.OptProf -Source $MicroBuildPackageSource -Verbosity $nugetVerbosity $EnvVars['OptProfEnabled'] = '1' } if ($Localization) { Write-Host "Installing MicroBuild localization plugin" -ForegroundColor $HeaderColor - & $InstallNuGetPkgScriptPath MicroBuild.Plugins.Localization -source $MicroBuildPackageSource -Verbosity $nugetVerbosity + & $DownloadNuGetPkgScriptPath -PackageId MicroBuild.Plugins.Localization -Source $MicroBuildPackageSource -Verbosity $nugetVerbosity $EnvVars['LocType'] = "Pseudo" $EnvVars['LocLanguages'] = "JPN" } if ($SBOM) { Write-Host "Installing MicroBuild SBOM plugin" -ForegroundColor $HeaderColor - & $InstallNuGetPkgScriptPath MicroBuild.Plugins.Sbom -source $MicroBuildPackageSource -Verbosity $nugetVerbosity + & $DownloadNuGetPkgScriptPath -PackageId MicroBuild.Plugins.Sbom -Source $MicroBuildPackageSource -Verbosity $nugetVerbosity # The feed with the latest versions of the tool is at 'https://1essharedassets.pkgs.visualstudio.com/1esPkgs/_packaging/SBOMTool/nuget/v3/index.json', # but we'll use the feed that the SBOM task itself uses to install the tool for consistency. - $PkgMicrosoft_ManifestTool_CrossPlatform = & $InstallNuGetPkgScriptPath Microsoft.ManifestTool.CrossPlatform -source $MicroBuildPackageSource -Verbosity $nugetVerbosity + $PkgMicrosoft_ManifestTool_CrossPlatform = & $DownloadNuGetPkgScriptPath -PackageId Microsoft.ManifestTool.CrossPlatform -Source $MicroBuildPackageSource -Verbosity $nugetVerbosity $EnvVars['GenerateSBOM'] = "true" $EnvVars['PkgMicrosoft_ManifestTool_CrossPlatform'] = $PkgMicrosoft_ManifestTool_CrossPlatform } diff --git a/tools/Convert-PDB.ps1 b/tools/Convert-PDB.ps1 index 7e1303a..ad00799 100644 --- a/tools/Convert-PDB.ps1 +++ b/tools/Convert-PDB.ps1 @@ -10,11 +10,11 @@ #> [CmdletBinding()] Param( - [Parameter(Mandatory=$true,Position=0)] + [Parameter(Mandatory = $true, Position = 0)] [string]$DllPath, [Parameter()] [string]$PdbPath, - [Parameter(Mandatory=$true,Position=1)] + [Parameter(Mandatory = $true, Position = 1)] [string]$OutputPath ) @@ -25,24 +25,26 @@ if ($IsMacOS -or $IsLinux) { $version = '1.1.0-beta2-21101-01' $baseDir = "$PSScriptRoot/../obj/tools" -$pdb2pdbpath = "$baseDir/Microsoft.DiaSymReader.Pdb2Pdb.$version/tools/Pdb2Pdb.exe" +$pdb2pdbpath = "$baseDir/microsoft.diasymreader.pdb2pdb/$version/tools/Pdb2Pdb.exe" if (-not (Test-Path $pdb2pdbpath)) { if (-not (Test-Path $baseDir)) { New-Item -Type Directory -Path $baseDir | Out-Null } $baseDir = (Resolve-Path $baseDir).Path # Normalize it - Write-Verbose "& (& $PSScriptRoot/Get-NuGetTool.ps1) install Microsoft.DiaSymReader.Pdb2Pdb -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir -Source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json | Out-Null" # This package originally comes from the https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json feed. # Add this feed as an upstream to whatever feed is in nuget.config if this step fails. - & (& $PSScriptRoot/Get-NuGetTool.ps1) install Microsoft.DiaSymReader.Pdb2Pdb -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir | Out-Null - if ($LASTEXITCODE -ne 0) { + try { + & "$PSScriptRoot/Download-NuGetPackage.ps1" -PackageId Microsoft.DiaSymReader.Pdb2Pdb -Version $version -Source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json -OutputDirectory $baseDir | Out-Null + } + catch { Write-Error "Failed to install Microsoft.DiaSymReader.Pdb2Pdb. Consider adding https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json as an upstream to your nuget.config feed." return } + $pdb2pdbpath = "$baseDir/microsoft.diasymreader.pdb2pdb/$version/tools/Pdb2Pdb.exe" } -$args = $DllPath,'/out',$OutputPath,'/nowarn','0021' +$arguments = $DllPath, '/out', $OutputPath, '/nowarn', '0021' if ($PdbPath) { - $args += '/pdb',$PdbPath + $arguments += '/pdb', $PdbPath } -Write-Verbose "$pdb2pdbpath $args" -& $pdb2pdbpath $args +Write-Verbose "$pdb2pdbpath $arguments" +& $pdb2pdbpath $arguments diff --git a/tools/Download-NuGetPackage.ps1 b/tools/Download-NuGetPackage.ps1 index 924b9ed..ce31167 100644 --- a/tools/Download-NuGetPackage.ps1 +++ b/tools/Download-NuGetPackage.ps1 @@ -42,14 +42,16 @@ if ($Version) { $packageArg = "$PackageId@$Version" } $extraArgs = @() if ($Source) { $extraArgs += '--source', $Source } +if ($Version -and $Version -match '-') { $extraArgs += '--prerelease' } $prevErrorActionPreference = $ErrorActionPreference $ErrorActionPreference = 'Continue' -& dotnet package download $packageArg --configfile $ConfigFile --output $OutputDirectory --verbosity $Verbosity @extraArgs 2>&1 | Out-Null +$downloadOutput = & dotnet package download $packageArg --configfile $ConfigFile --output $OutputDirectory --verbosity $Verbosity @extraArgs 2>&1 $downloadExitCode = $LASTEXITCODE $ErrorActionPreference = $prevErrorActionPreference if ($downloadExitCode -ne 0) { + $downloadOutput | Write-Host throw "Failed to download package $packageArg (exit code $downloadExitCode)." } From 8075c3f022308d59a585976a8864837f833e4cf5 Mon Sep 17 00:00:00 2001 From: Andrey Tretyak Date: Tue, 7 Apr 2026 11:08:33 -0700 Subject: [PATCH 132/174] Use default configuration for Network Isolation --- azure-pipelines/archive-sourcecode.yml | 2 -- azure-pipelines/libtemplate-update.yml | 2 -- azure-pipelines/official.yml | 2 -- azure-pipelines/release.yml | 2 -- azure-pipelines/unofficial.yml | 2 -- azure-pipelines/vs-insertion.yml | 2 -- azure-pipelines/vs-validation.yml | 2 -- 7 files changed, 14 deletions(-) diff --git a/azure-pipelines/archive-sourcecode.yml b/azure-pipelines/archive-sourcecode.yml index 84b70ec..211881f 100644 --- a/azure-pipelines/archive-sourcecode.yml +++ b/azure-pipelines/archive-sourcecode.yml @@ -35,8 +35,6 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate parameters: - settings: - networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable diff --git a/azure-pipelines/libtemplate-update.yml b/azure-pipelines/libtemplate-update.yml index 6d0051a..384be7c 100644 --- a/azure-pipelines/libtemplate-update.yml +++ b/azure-pipelines/libtemplate-update.yml @@ -30,8 +30,6 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Unofficial.yml@MicroBuildTemplate parameters: - settings: - networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: name: AzurePipelines-EO diff --git a/azure-pipelines/official.yml b/azure-pipelines/official.yml index 9f0a89d..22a5d6a 100644 --- a/azure-pipelines/official.yml +++ b/azure-pipelines/official.yml @@ -45,8 +45,6 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate parameters: - settings: - networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable codeSignValidation: diff --git a/azure-pipelines/release.yml b/azure-pipelines/release.yml index 5824b0a..edc5652 100644 --- a/azure-pipelines/release.yml +++ b/azure-pipelines/release.yml @@ -20,8 +20,6 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate parameters: - settings: - networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable diff --git a/azure-pipelines/unofficial.yml b/azure-pipelines/unofficial.yml index 47a2a2e..36aaf6e 100644 --- a/azure-pipelines/unofficial.yml +++ b/azure-pipelines/unofficial.yml @@ -55,8 +55,6 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Unofficial.yml@MicroBuildTemplate parameters: - settings: - networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable credscan: diff --git a/azure-pipelines/vs-insertion.yml b/azure-pipelines/vs-insertion.yml index 22481c9..f1a2576 100644 --- a/azure-pipelines/vs-insertion.yml +++ b/azure-pipelines/vs-insertion.yml @@ -22,8 +22,6 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate parameters: - settings: - networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable sbom: diff --git a/azure-pipelines/vs-validation.yml b/azure-pipelines/vs-validation.yml index f623731..5e54386 100644 --- a/azure-pipelines/vs-validation.yml +++ b/azure-pipelines/vs-validation.yml @@ -26,8 +26,6 @@ variables: extends: template: azure-pipelines/MicroBuild.1ES.Unofficial.yml@MicroBuildTemplate parameters: - settings: - networkIsolationPolicy: Permissive,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable credscan: From dee711b126050a090c72ea2c70dbbe9b0dfe2ea0 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Fri, 10 Apr 2026 06:58:17 -0600 Subject: [PATCH 133/174] Bump MicroBuildVersion to 2.0.226 --- .github/prompts/update-library-template.prompt.md | 6 ++++++ Directory.Packages.props | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/prompts/update-library-template.prompt.md b/.github/prompts/update-library-template.prompt.md index f9fe672..13eb2bd 100644 --- a/.github/prompts/update-library-template.prompt.md +++ b/.github/prompts/update-library-template.prompt.md @@ -37,6 +37,12 @@ The `test/Library.Tests/Library.Tests.csproj` file is very typical of this. Changes to this file should very typically be applied to any and all test projects in the repo. You are responsible for doing this in addition to re-deleting this template file. +## Updating package and SDK versions + +After the merge, always check global.json for MSBuild Sdks with names starting with `Microsoft.VisualStudio.Internal.MicroBuild`. +These SDK versions should match the value of the `MicroBuildVersion` property found in `Directory.Packages.props`. +Always take the latest of the versions you see among these SDKs and the `MicroBuildVersion` property. + ## Validation Validate the merge result (after resolving any conflicts, if applicable). diff --git a/Directory.Packages.props b/Directory.Packages.props index e8e0644..67ad6cd 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,7 +6,7 @@ true 2.2.1 - 2.0.208 + 2.0.226 From 29fe9fa1b192031e937f30983c0516a97eb7830b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 10:02:50 -0600 Subject: [PATCH 134/174] Update dependency nerdbank.dotnetrepotools to v1.3.1 (#501) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index b380024..881a580 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -31,7 +31,7 @@ "rollForward": false }, "nerdbank.dotnetrepotools": { - "version": "1.2.1", + "version": "1.3.1", "commands": [ "repo" ], From 5732a7ff7e49d2703433c16902f7c3414dc36a39 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 15:18:33 -0600 Subject: [PATCH 135/174] Update mcr.microsoft.com/dotnet/sdk:10.0.201 Docker digest to 127d7d4 (502) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 14b064d..063dac8 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.201@sha256:f061e5a7532b36fa1d1b684857fe1f504ba92115b9934f154643266613c44c62 +FROM mcr.microsoft.com/dotnet/sdk:10.0.201@sha256:127d7d4d601ae26b8e04c54efb37e9ce8766931bded0ee59fcd799afd21d6850 # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. From 1d433b85cc2e40b2f4d25d33c471b1defbae5a99 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 21:22:18 +0000 Subject: [PATCH 136/174] Update actions/upload-artifact action to v7.0.1 (503) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/actions/publish-artifacts/action.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/actions/publish-artifacts/action.yaml b/.github/actions/publish-artifacts/action.yaml index 9982cf1..87b2f9c 100644 --- a/.github/actions/publish-artifacts/action.yaml +++ b/.github/actions/publish-artifacts/action.yaml @@ -14,46 +14,46 @@ runs: - name: ๐Ÿ“ข Upload project.assets.json files if: always() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: projectAssetsJson-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/projectAssetsJson continue-on-error: true - name: ๐Ÿ“ข Upload variables - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: variables-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/Variables continue-on-error: true - name: ๐Ÿ“ข Upload build_logs if: always() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: build_logs-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/build_logs continue-on-error: true - name: ๐Ÿ“ข Upload testResults if: always() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: testResults-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/testResults continue-on-error: true - name: ๐Ÿ“ข Upload coverageResults if: always() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: coverageResults-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/coverageResults continue-on-error: true - name: ๐Ÿ“ข Upload symbols - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: symbols-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/symbols continue-on-error: true - name: ๐Ÿ“ข Upload deployables - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: deployables-${{ runner.os }} path: ${{ runner.temp }}/_artifacts/deployables From ab3f99d1213957a7477df43bfa7b636b669827d2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 21:25:09 +0000 Subject: [PATCH 137/174] Update actions/upload-pages-artifact action to v5 (504) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index e19cf64..fbfcd14 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -34,7 +34,7 @@ jobs: name: ๐Ÿ“š Generate documentation - name: Upload artifact - uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4 + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: docfx/_site From 7163e58259613ed4cca79f1598393cb27211ae2d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 11 Apr 2026 07:09:31 -0600 Subject: [PATCH 138/174] Update dependency nerdbank.dotnetrepotools to v1.3.13 (505) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 881a580..130ff5e 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -31,7 +31,7 @@ "rollForward": false }, "nerdbank.dotnetrepotools": { - "version": "1.3.1", + "version": "1.3.13", "commands": [ "repo" ], From 41a316f44b16c38ff23b1bb00b14b211fd631fe7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 06:56:08 -0600 Subject: [PATCH 139/174] Update Dockerfile and global.json updates to v10.0.202 (506) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/Dockerfile | 2 +- global.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 063dac8..6e0c045 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.201@sha256:127d7d4d601ae26b8e04c54efb37e9ce8766931bded0ee59fcd799afd21d6850 +FROM mcr.microsoft.com/dotnet/sdk:10.0.202@sha256:adc02be8b87957d07208a4a3e51775935b33bad3317de8c45b1e67357b4c073b # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. diff --git a/global.json b/global.json index c331692..8f46959 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.201", + "version": "10.0.202", "rollForward": "patch", "allowPrerelease": false }, From 863f9e1844b4067746bc2a337115d6b07cf59f41 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 07:45:12 -0600 Subject: [PATCH 140/174] Throw on Download-NuGetPackage errors Instead of writing an error and returning `$null` to the caller, we should do something that's harder to ignore. --- tools/Download-NuGetPackage.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Download-NuGetPackage.ps1 b/tools/Download-NuGetPackage.ps1 index 924b9ed..760ac90 100644 --- a/tools/Download-NuGetPackage.ps1 +++ b/tools/Download-NuGetPackage.ps1 @@ -73,5 +73,5 @@ if ($Version) { if ($packageDir -and (Test-Path $packageDir)) { Write-Output $packageDir } else { - Write-Error "Package directory not found after download." + throw "Package directory not found after download. PackageId='$PackageId'; Version='$Version'; OutputDirectory='$OutputDirectory'; PackageRoot='$packageRoot'." } From a8db2fc2f8a72d68a9b1df8255180fa32e0d35f9 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 08:04:29 -0600 Subject: [PATCH 141/174] Rename variable for better consistency --- tools/artifacts/VSInsertion.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/artifacts/VSInsertion.ps1 b/tools/artifacts/VSInsertion.ps1 index 2858f7f..32d35df 100644 --- a/tools/artifacts/VSInsertion.ps1 +++ b/tools/artifacts/VSInsertion.ps1 @@ -39,9 +39,9 @@ if (Test-Path $VsixPackages) { } if ($InsertionOutputs -and $env:PROFILINGINPUTSPROPSNAME) { - $InsertOutputsProfilingInputs = Join-Path $InsertionOutputs $env:PROFILINGINPUTSPROPSNAME - if (Test-Path -LiteralPath $InsertOutputsProfilingInputs) { - $result[$InsertionOutputs] = Get-ChildItem -LiteralPath $InsertOutputsProfilingInputs # OptProf ProfilingInputs + $InsertionOutputsProfilingInputs = Join-Path $InsertionOutputs $env:PROFILINGINPUTSPROPSNAME + if (Test-Path -LiteralPath $InsertionOutputsProfilingInputs) { + $result[$InsertionOutputs] = Get-ChildItem -LiteralPath $InsertionOutputsProfilingInputs # OptProf ProfilingInputs } } From b83fca49232d18bcecd7c1ce472f93f2fb422c85 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 08:04:45 -0600 Subject: [PATCH 142/174] Defend against exceptions thrown from `Download-NugetPackage.ps1` --- tools/Get-ExternalSymbolFiles.ps1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/Get-ExternalSymbolFiles.ps1 b/tools/Get-ExternalSymbolFiles.ps1 index 481e7a1..9cd78a2 100644 --- a/tools/Get-ExternalSymbolFiles.ps1 +++ b/tools/Get-ExternalSymbolFiles.ps1 @@ -28,7 +28,12 @@ Function Get-SymbolsFromPackage($id, $version) { $unzippedPkgPath = Join-Path $symbolPackagesPath "$id.$version" # Download the package from configured feeds (failures are non-fatal for symbol collection) - & "$PSScriptRoot\Download-NuGetPackage.ps1" -PackageId $id -Version $version -OutputDirectory $symbolPackagesPath -ErrorAction SilentlyContinue | Out-Null + try { + & "$PSScriptRoot\Download-NuGetPackage.ps1" -PackageId $id -Version $version -OutputDirectory $symbolPackagesPath -ErrorAction SilentlyContinue | Out-Null + } + catch { + Write-Warning "Failed to download package $id $version from configured feeds. Skipping if not found locally. $($_.Exception.Message)" + } $global:LASTEXITCODE = 0 $nupkgFile = Get-ChildItem -Recurse -Path $symbolPackagesPath -Filter "$id.$version.nupkg" -ErrorAction SilentlyContinue | Select-Object -First 1 if (!$nupkgFile) { From a871231f024b5a7ed3995de8ffac53725574b6e3 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 08:13:56 -0600 Subject: [PATCH 143/174] Add missing `dotnet symbol` command to manifest --- .config/dotnet-tools.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 130ff5e..9019f11 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -36,6 +36,13 @@ "repo" ], "rollForward": false + }, + "dotnet-symbol": { + "version": "10.0.721401", + "commands": [ + "dotnet-symbol" + ], + "rollForward": false } } -} +} \ No newline at end of file From a9956c45aee43ac62ffa29e909e957dbb22dfb62 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 08:29:20 -0600 Subject: [PATCH 144/174] Improve resilience of fetching PackageVersion items --- tools/Get-ExternalSymbolFiles.ps1 | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/tools/Get-ExternalSymbolFiles.ps1 b/tools/Get-ExternalSymbolFiles.ps1 index 9cd78a2..12ea2b0 100644 --- a/tools/Get-ExternalSymbolFiles.ps1 +++ b/tools/Get-ExternalSymbolFiles.ps1 @@ -80,9 +80,36 @@ Function Get-SymbolsFromPackage($id, $version) { } } +Function Get-PackageVersions() { + if ($script:PackageVersions) { + return $script:PackageVersions + } + + $propsPath = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot '..\Directory.Packages.props')).Path + $output = & dotnet build $propsPath -nologo -verbosity:quiet -getItem:PackageVersion 2>&1 + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to evaluate package versions from Directory.Packages.props.`n$($output | Out-String)" + return @{} + } + + $jsonText = ($output | Out-String).Trim() + $jsonStart = $jsonText.IndexOf('{') + if ($jsonStart -lt 0) { + Write-Error 'Failed to locate JSON output from `dotnet build -getItem:PackageVersion`.' + return @{} + } + + $packageVersions = @{} + foreach ($item in @((ConvertFrom-Json $jsonText.Substring($jsonStart)).Items.PackageVersion)) { + $packageVersions[$item.Identity] = $item.Version + } + + $script:PackageVersions = $packageVersions + $packageVersions +} + Function Get-PackageVersion($id) { - $versionProps = [xml](Get-Content -LiteralPath $PSScriptRoot\..\Directory.Packages.props) - $version = $versionProps.Project.ItemGroup.PackageVersion | ? { $_.Include -eq $id } | % { $_.Version } + $version = Get-PackageVersions | Select-Object -ExpandProperty $id -ErrorAction SilentlyContinue if (!$version) { Write-Error "No package version found in Directory.Packages.props for the package '$id'" } From b9fdfc7adfe5082a17362011c2e637b5e49e746f Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 08:37:29 -0600 Subject: [PATCH 145/174] Avoid re-unzipping downloaded symbol packages Get-ExternalSymbolFiles.ps1 was downloading Nerdbank.Streams into obj/SymbolsPackages/nerdbank.streams/2.13.16 via Download-NuGetPackage.ps1, which uses dotnet package download. After that, the script searched for the .nupkg inside that directory and extracted it again into obj/SymbolsPackages/Nerdbank.Streams.2.13.16. That second extraction was redundant and only existed so dotnet symbol and the PDB archival logic had a package root to inspect. The downloaded package directory already contains the package contents in NuGet's normal lowercase layout, so the script can operate on that directory directly. Use the package path returned by Download-NuGetPackage.ps1 for symbol download and PDB discovery, and remove the extra unzip step. This leaves only one materialized package tree under obj/SymbolsPackages. --- tools/Get-ExternalSymbolFiles.ps1 | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/tools/Get-ExternalSymbolFiles.ps1 b/tools/Get-ExternalSymbolFiles.ps1 index 12ea2b0..87e020f 100644 --- a/tools/Get-ExternalSymbolFiles.ps1 +++ b/tools/Get-ExternalSymbolFiles.ps1 @@ -4,48 +4,27 @@ $SymbolServers = @( 'https://symbols.nuget.org/download/symbols' ) -Function Unzip($Path, $OutDir) { - $OutDir = (New-Item -ItemType Directory -Path $OutDir -Force).FullName - Add-Type -AssemblyName System.IO.Compression.FileSystem - - # Start by extracting to a temporary directory so that there are no file conflicts. - [System.IO.Compression.ZipFile]::ExtractToDirectory($Path, "$OutDir.out") - - # Now move all files from the temp directory to $OutDir, overwriting any files. - Get-ChildItem -Path "$OutDir.out" -Recurse -File | ForEach-Object { - $destinationPath = Join-Path -Path $OutDir -ChildPath $_.FullName.Substring("$OutDir.out".Length).TrimStart([io.path]::DirectorySeparatorChar, [io.path]::AltDirectorySeparatorChar) - if (!(Test-Path -Path (Split-Path -Path $destinationPath -Parent))) { - New-Item -ItemType Directory -Path (Split-Path -Path $destinationPath -Parent) | Out-Null - } - Move-Item -Path $_.FullName -Destination $destinationPath -Force - } - Remove-Item -Path "$OutDir.out" -Recurse -Force -} - Function Get-SymbolsFromPackage($id, $version) { $symbolPackagesPath = "$PSScriptRoot/../obj/SymbolsPackages" New-Item -ItemType Directory -Path $symbolPackagesPath -Force | Out-Null - $unzippedPkgPath = Join-Path $symbolPackagesPath "$id.$version" + $packagePath = $null # Download the package from configured feeds (failures are non-fatal for symbol collection) try { - & "$PSScriptRoot\Download-NuGetPackage.ps1" -PackageId $id -Version $version -OutputDirectory $symbolPackagesPath -ErrorAction SilentlyContinue | Out-Null + $packagePath = & "$PSScriptRoot\Download-NuGetPackage.ps1" -PackageId $id -Version $version -OutputDirectory $symbolPackagesPath -ErrorAction SilentlyContinue } catch { Write-Warning "Failed to download package $id $version from configured feeds. Skipping if not found locally. $($_.Exception.Message)" } $global:LASTEXITCODE = 0 - $nupkgFile = Get-ChildItem -Recurse -Path $symbolPackagesPath -Filter "$id.$version.nupkg" -ErrorAction SilentlyContinue | Select-Object -First 1 - if (!$nupkgFile) { + if (!$packagePath -or !(Test-Path -LiteralPath $packagePath)) { Write-Warning "Package $id $version not found in configured feeds. Skipping." return } - Unzip -Path $nupkgFile.FullName -OutDir $unzippedPkgPath - # Download symbols for each binary using dotnet-symbol $serverArgs = $SymbolServers | ForEach-Object { '--server-path'; $_ } - $binaries = Get-ChildItem -Recurse -LiteralPath $unzippedPkgPath -Include *.dll, *.exe + $binaries = Get-ChildItem -Recurse -LiteralPath $packagePath -Include *.dll, *.exe foreach ($binary in $binaries) { $prevErrorActionPreference = $ErrorActionPreference $ErrorActionPreference = 'Continue' @@ -54,7 +33,7 @@ Function Get-SymbolsFromPackage($id, $version) { } # Output pairs of binary + PDB paths for archival - Get-ChildItem -Recurse -LiteralPath $unzippedPkgPath -Filter *.pdb | % { + Get-ChildItem -Recurse -LiteralPath $packagePath -Filter *.pdb | % { $rootName = Join-Path $_.Directory $_.BaseName if ($rootName.EndsWith('.ni')) { $rootName = $rootName.Substring(0, $rootName.Length - 3) From fd7d87ee2edf99a2500eb0884c5a73f3d671cd1a Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 08:43:36 -0600 Subject: [PATCH 146/174] Avoid stomping on LASTEXITCODE while simply trying to reset it --- tools/Get-ExternalSymbolFiles.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/Get-ExternalSymbolFiles.ps1 b/tools/Get-ExternalSymbolFiles.ps1 index 87e020f..7bd2c2b 100644 --- a/tools/Get-ExternalSymbolFiles.ps1 +++ b/tools/Get-ExternalSymbolFiles.ps1 @@ -10,13 +10,14 @@ Function Get-SymbolsFromPackage($id, $version) { $packagePath = $null # Download the package from configured feeds (failures are non-fatal for symbol collection) + $previousLastExitCode = $global:LASTEXITCODE try { $packagePath = & "$PSScriptRoot\Download-NuGetPackage.ps1" -PackageId $id -Version $version -OutputDirectory $symbolPackagesPath -ErrorAction SilentlyContinue } catch { Write-Warning "Failed to download package $id $version from configured feeds. Skipping if not found locally. $($_.Exception.Message)" } - $global:LASTEXITCODE = 0 + $global:LASTEXITCODE = $previousLastExitCode if (!$packagePath -or !(Test-Path -LiteralPath $packagePath)) { Write-Warning "Package $id $version not found in configured feeds. Skipping." return From 86ad5cd7a10dd6f20400a9126db34496f15ff94b Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 09:05:54 -0600 Subject: [PATCH 147/174] Fix init.ps1 installation of local microbuild plugins We need the packages *with their dependencies* to be installed, and only I filed https://github.com/dotnet/sdk/issues/53890 to track this missing feature that requires us to go back to using nuget.exe. --- init.ps1 | 14 +++--- tools/Get-NuGetTool.ps1 | 49 ++++++++++++++++++++ tools/Install-NuGetPackage.ps1 | 85 ++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 7 deletions(-) create mode 100644 tools/Get-NuGetTool.ps1 create mode 100644 tools/Install-NuGetPackage.ps1 diff --git a/init.ps1 b/init.ps1 index 9c62b5e..8bb78ad 100755 --- a/init.ps1 +++ b/init.ps1 @@ -126,40 +126,40 @@ try { } } - $DownloadNuGetPkgScriptPath = "$PSScriptRoot\tools\Download-NuGetPackage.ps1" + $InstallNuGetPkgScriptPath = "$PSScriptRoot\tools\Install-NuGetPackage.ps1" $nugetVerbosity = 'quiet' if ($Verbose) { $nugetVerbosity = 'normal' } $MicroBuildPackageSource = 'https://pkgs.dev.azure.com/devdiv/_packaging/MicroBuildToolset%40Local/nuget/v3/index.json' if ($Signing) { Write-Host "Installing MicroBuild signing plugin" -ForegroundColor $HeaderColor - & $DownloadNuGetPkgScriptPath -PackageId MicroBuild.Plugins.Signing -Source $MicroBuildPackageSource -Verbosity $nugetVerbosity + & $InstallNuGetPkgScriptPath MicroBuild.Plugins.Signing -source $MicroBuildPackageSource -Verbosity $nugetVerbosity $EnvVars['SignType'] = "Test" } if ($Setup) { Write-Host "Installing MicroBuild SwixBuild plugin..." -ForegroundColor $HeaderColor - & $DownloadNuGetPkgScriptPath -PackageId Microsoft.VisualStudioEng.MicroBuild.Plugins.SwixBuild -Source $MicroBuildPackageSource -Verbosity $nugetVerbosity + & $InstallNuGetPkgScriptPath Microsoft.VisualStudioEng.MicroBuild.Plugins.SwixBuild -source $MicroBuildPackageSource -Verbosity $nugetVerbosity } if ($OptProf) { Write-Host "Installing MicroBuild OptProf plugin" -ForegroundColor $HeaderColor - & $DownloadNuGetPkgScriptPath -PackageId MicroBuild.Plugins.OptProf -Source $MicroBuildPackageSource -Verbosity $nugetVerbosity + & $InstallNuGetPkgScriptPath MicroBuild.Plugins.OptProf -source $MicroBuildPackageSource -Verbosity $nugetVerbosity $EnvVars['OptProfEnabled'] = '1' } if ($Localization) { Write-Host "Installing MicroBuild localization plugin" -ForegroundColor $HeaderColor - & $DownloadNuGetPkgScriptPath -PackageId MicroBuild.Plugins.Localization -Source $MicroBuildPackageSource -Verbosity $nugetVerbosity + & $InstallNuGetPkgScriptPath MicroBuild.Plugins.Localization -source $MicroBuildPackageSource -Verbosity $nugetVerbosity $EnvVars['LocType'] = "Pseudo" $EnvVars['LocLanguages'] = "JPN" } if ($SBOM) { Write-Host "Installing MicroBuild SBOM plugin" -ForegroundColor $HeaderColor - & $DownloadNuGetPkgScriptPath -PackageId MicroBuild.Plugins.Sbom -Source $MicroBuildPackageSource -Verbosity $nugetVerbosity + & $InstallNuGetPkgScriptPath MicroBuild.Plugins.Sbom -source $MicroBuildPackageSource -Verbosity $nugetVerbosity # The feed with the latest versions of the tool is at 'https://1essharedassets.pkgs.visualstudio.com/1esPkgs/_packaging/SBOMTool/nuget/v3/index.json', # but we'll use the feed that the SBOM task itself uses to install the tool for consistency. - $PkgMicrosoft_ManifestTool_CrossPlatform = & $DownloadNuGetPkgScriptPath -PackageId Microsoft.ManifestTool.CrossPlatform -Source $MicroBuildPackageSource -Verbosity $nugetVerbosity + $PkgMicrosoft_ManifestTool_CrossPlatform = & $InstallNuGetPkgScriptPath Microsoft.ManifestTool.CrossPlatform -source $MicroBuildPackageSource -Verbosity $nugetVerbosity $EnvVars['GenerateSBOM'] = "true" $EnvVars['PkgMicrosoft_ManifestTool_CrossPlatform'] = $PkgMicrosoft_ManifestTool_CrossPlatform } diff --git a/tools/Get-NuGetTool.ps1 b/tools/Get-NuGetTool.ps1 new file mode 100644 index 0000000..e507596 --- /dev/null +++ b/tools/Get-NuGetTool.ps1 @@ -0,0 +1,49 @@ +<# +.SYNOPSIS + Downloads the NuGet.exe tool and returns the path to it. +.PARAMETER NuGetVersion + The version of the NuGet tool to acquire. +#> +Param( + [Parameter()] + [string]$NuGetVersion='7.3.1' +) + +function Test-NuGetExecutableSignature { + Param( + [Parameter(Mandatory=$true)] + [string]$Path + ) + + if (!(Test-Path $Path)) { + return $false + } + + $signature = Get-AuthenticodeSignature -FilePath $Path + if ($signature.Status -eq [System.Management.Automation.SignatureStatus]::Valid -and + $null -ne $signature.SignerCertificate -and + $signature.SignerCertificate.Subject -like '*CN=Microsoft Corporation*') { + Write-Verbose "NuGet executable signature is valid." + return $true + } + + Write-Verbose "NuGet executable signature is invalid." + return $false +} + +$toolsPath = & "$PSScriptRoot\Get-TempToolsPath.ps1" +$binaryToolsPath = Join-Path $toolsPath $NuGetVersion +if (!(Test-Path $binaryToolsPath)) { $null = mkdir $binaryToolsPath } +$nugetPath = Join-Path $binaryToolsPath nuget.exe + +if (!(Test-Path $nugetPath) -or -not (Test-NuGetExecutableSignature -Path $nugetPath)) { + Write-Host "Downloading nuget.exe $NuGetVersion..." -ForegroundColor Yellow + (New-Object System.Net.WebClient).DownloadFile("https://dist.nuget.org/win-x86-commandline/v$NuGetVersion/NuGet.exe", $nugetPath) + + if (!(Test-NuGetExecutableSignature -Path $nugetPath)) { + Remove-Item $nugetPath -Force -ErrorAction SilentlyContinue + throw "Downloaded nuget.exe $NuGetVersion failed Authenticode signature validation." + } +} + +return (Resolve-Path $nugetPath).Path diff --git a/tools/Install-NuGetPackage.ps1 b/tools/Install-NuGetPackage.ps1 new file mode 100644 index 0000000..42ad123 --- /dev/null +++ b/tools/Install-NuGetPackage.ps1 @@ -0,0 +1,85 @@ +<# +.SYNOPSIS + Installs a NuGet package. +.PARAMETER PackageID + The Package ID to install. +.PARAMETER Version + The version of the package to install. If unspecified, the latest stable release is installed. +.PARAMETER Source + The package source feed to find the package to install from. +.PARAMETER Prerelease + Include prerelease packages when searching for the latest version. +.PARAMETER ExcludeVersion + Installs the package without adding the version to the folder name. +.PARAMETER DirectDownload + Bypass the local cache when downloading packages. +.PARAMETER PackagesDir + The directory to install the package to. By default, it uses the Packages folder at the root of the repo. +.PARAMETER ConfigFile + The nuget.config file to use. By default, it uses :/nuget.config. +.OUTPUTS + System.String. The path to the installed package. +#> +[CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Low')] +Param( + [Parameter(Position=1,Mandatory=$true)] + [string]$PackageId, + [Parameter()] + [string]$Version, + [Parameter()] + [string]$Source, + [Parameter()] + [switch]$Prerelease, + [Parameter()] + [switch]$ExcludeVersion, + [Parameter()] + [switch]$DirectDownload, + [Parameter()] + [string]$PackagesDir="$PSScriptRoot\..\packages", + [Parameter()] + [string]$ConfigFile="$PSScriptRoot\..\nuget.config", + [Parameter()] + [ValidateSet('Quiet','Normal','Detailed')] + [string]$Verbosity='normal' +) + +$nugetPath = & "$PSScriptRoot\Get-NuGetTool.ps1" + +Write-Verbose "Installing $PackageId..." +$nugetArgs = "Install",$PackageId,"-OutputDirectory",$PackagesDir,'-ConfigFile',$ConfigFile +if ($Version) { $nugetArgs += "-Version",$Version } +if ($Source) { $nugetArgs += "-FallbackSource",$Source } +if ($Prerelease) { $nugetArgs += "-Prerelease" } +if ($ExcludeVersion) { $nugetArgs += '-ExcludeVersion' } +if ($DirectDownload) { $nugetArgs += '-DirectDownload' } +$nugetArgs += '-Verbosity',$Verbosity + +if ($PSCmdlet.ShouldProcess($PackageId, 'nuget install')) { + $p = Start-Process $nugetPath $nugetArgs -NoNewWindow -Wait -PassThru + if ($null -ne $p.ExitCode -and $p.ExitCode -ne 0) { + throw "NuGet install failed for package '$PackageId' (version '$requestedVersion') with exit code $exitCode." + } +} + +# Provide the path to the installed package directory to our caller. +if ($ExcludeVersion) { + $packageDir = Get-ChildItem -Path $PackagesDir -Directory -ErrorAction SilentlyContinue | + Where-Object { $_.Name -ieq $PackageId } | + Select-Object -First 1 +} elseif ($Version) { + $expectedDirectoryName = "$PackageId.$Version" + $packageDir = Get-ChildItem -Path $PackagesDir -Directory -ErrorAction SilentlyContinue | + Where-Object { $_.Name -ieq $expectedDirectoryName } | + Select-Object -First 1 +} else { + $packageDir = Get-ChildItem -Path $PackagesDir -Directory -ErrorAction SilentlyContinue | + Where-Object { $_.Name -like "$PackageId.*" } | + Sort-Object -Property LastWriteTimeUtc -Descending | + Select-Object -First 1 +} + +if ($packageDir -and (Test-Path -Path $packageDir.FullName -PathType Container)) { + Write-Output $packageDir.FullName +} else { + throw "Installed package directory not found. PackageId='$PackageId'; Version='$Version'; ExcludeVersion='$ExcludeVersion'; PackagesDir='$PackagesDir'." +} From 1f9ec2408cc6330ba466441fbb181dc5845c4899 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 09:25:31 -0600 Subject: [PATCH 148/174] Don't download a nuget package twice --- tools/Download-NuGetPackage.ps1 | 14 +++++++++++--- tools/Get-ProcDump.ps1 | 9 +-------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/tools/Download-NuGetPackage.ps1 b/tools/Download-NuGetPackage.ps1 index 8104b92..6eef937 100644 --- a/tools/Download-NuGetPackage.ps1 +++ b/tools/Download-NuGetPackage.ps1 @@ -37,6 +37,17 @@ if (!(Test-Path $OutputDirectory)) { New-Item -ItemType Directory -Path $OutputD $OutputDirectory = (Resolve-Path $OutputDirectory).Path $ConfigFile = (Resolve-Path $ConfigFile).Path +$packageIdLower = $PackageId.ToLower() +$packageRoot = Join-Path $OutputDirectory $packageIdLower + +if ($Version) { + $predictedPackageDir = Join-Path $packageRoot $Version + if (Test-Path -Path $predictedPackageDir -PathType Container) { + Write-Output (Resolve-Path $predictedPackageDir).Path + return + } +} + $packageArg = $PackageId if ($Version) { $packageArg = "$PackageId@$Version" } @@ -56,16 +67,13 @@ if ($downloadExitCode -ne 0) { } # Return the path to the downloaded package directory (dotnet package download uses lowercase id) -$packageIdLower = $PackageId.ToLower() if ($Version) { - $packageRoot = Join-Path $OutputDirectory $packageIdLower $packageDir = Get-ChildItem -Path $packageRoot -Directory -ErrorAction SilentlyContinue | Where-Object { $_.Name -ieq $Version } | Select-Object -First 1 if ($packageDir) { $packageDir = $packageDir.FullName } } else { # When no version is specified, pick the most recently written version directory. - $packageRoot = Join-Path $OutputDirectory $packageIdLower $packageDir = Get-ChildItem -Path $packageRoot -Directory -ErrorAction SilentlyContinue | Sort-Object -Property LastWriteTimeUtc -Descending | Select-Object -First 1 diff --git a/tools/Get-ProcDump.ps1 b/tools/Get-ProcDump.ps1 index 8b1f7d1..9d9bcd8 100644 --- a/tools/Get-ProcDump.ps1 +++ b/tools/Get-ProcDump.ps1 @@ -2,11 +2,4 @@ .SYNOPSIS Downloads 32-bit and 64-bit procdump executables and returns the path to where they were installed. #> -$version = '0.0.1' -$baseDir = "$PSScriptRoot\..\obj\tools" -$procDumpToolPath = "$baseDir\procdump\$version\bin" -if (-not (Test-Path $procDumpToolPath)) { - & "$PSScriptRoot\Download-NuGetPackage.ps1" -PackageId procdump -Version $version -OutputDirectory $baseDir | Out-Null -} - -(Resolve-Path $procDumpToolPath).Path +Join-Path (& "$PSScriptRoot\Download-NuGetPackage.ps1" -PackageId procdump -Version 0.0.1) 'bin' From f1de0ce66c2ffacb6ed6eaf2e324053d513cd110 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 09:31:24 -0600 Subject: [PATCH 149/174] Don't assume unpacked structure in Convert-PDB.ps1 --- tools/Convert-PDB.ps1 | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/tools/Convert-PDB.ps1 b/tools/Convert-PDB.ps1 index ad00799..d1d0e88 100644 --- a/tools/Convert-PDB.ps1 +++ b/tools/Convert-PDB.ps1 @@ -23,28 +23,25 @@ if ($IsMacOS -or $IsLinux) { return } -$version = '1.1.0-beta2-21101-01' -$baseDir = "$PSScriptRoot/../obj/tools" -$pdb2pdbpath = "$baseDir/microsoft.diasymreader.pdb2pdb/$version/tools/Pdb2Pdb.exe" -if (-not (Test-Path $pdb2pdbpath)) { - if (-not (Test-Path $baseDir)) { New-Item -Type Directory -Path $baseDir | Out-Null } - $baseDir = (Resolve-Path $baseDir).Path # Normalize it - # This package originally comes from the https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json feed. - # Add this feed as an upstream to whatever feed is in nuget.config if this step fails. - try { - & "$PSScriptRoot/Download-NuGetPackage.ps1" -PackageId Microsoft.DiaSymReader.Pdb2Pdb -Version $version -Source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json -OutputDirectory $baseDir | Out-Null - } - catch { - Write-Error "Failed to install Microsoft.DiaSymReader.Pdb2Pdb. Consider adding https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json as an upstream to your nuget.config feed." - return - } - $pdb2pdbpath = "$baseDir/microsoft.diasymreader.pdb2pdb/$version/tools/Pdb2Pdb.exe" +# This package originally comes from the https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json feed. +# Add this feed as an upstream to whatever feed is in nuget.config if this step fails. +$packageID = 'Microsoft.DiaSymReader.Pdb2Pdb' +$packageVersion = '1.1.0-beta2-21101-01' +try { + $pdb2pdbpath = & "$PSScriptRoot/Download-NuGetPackage.ps1" -PackageId $packageID -Version $packageVersion -Source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json } +catch { + Write-Error "Failed to install $packageID. Consider adding https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json as an upstream to your nuget.config feed." + return +} + +New-Item -ItemType Directory -Force -Path (Split-Path $OutputPath -Parent) | Out-Null +$toolpath = "$pdb2pdbpath/tools/Pdb2Pdb.exe" $arguments = $DllPath, '/out', $OutputPath, '/nowarn', '0021' if ($PdbPath) { $arguments += '/pdb', $PdbPath } -Write-Verbose "$pdb2pdbpath $arguments" -& $pdb2pdbpath $arguments +Write-Verbose "$toolpath $arguments" +& $toolpath $arguments From cb09f6d198e462eb190d2d8dbfeaf94155ca0484 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 09:41:47 -0600 Subject: [PATCH 150/174] Improve `dotnet symbol` performance We can invoke it just once with all the binaries we want symbols for. --- tools/Get-ExternalSymbolFiles.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/Get-ExternalSymbolFiles.ps1 b/tools/Get-ExternalSymbolFiles.ps1 index 7bd2c2b..257f2f4 100644 --- a/tools/Get-ExternalSymbolFiles.ps1 +++ b/tools/Get-ExternalSymbolFiles.ps1 @@ -25,11 +25,11 @@ Function Get-SymbolsFromPackage($id, $version) { # Download symbols for each binary using dotnet-symbol $serverArgs = $SymbolServers | ForEach-Object { '--server-path'; $_ } - $binaries = Get-ChildItem -Recurse -LiteralPath $packagePath -Include *.dll, *.exe - foreach ($binary in $binaries) { + $binaries = @(Get-ChildItem -Recurse -LiteralPath $packagePath -Include *.dll, *.exe) + if ($binaries) { $prevErrorActionPreference = $ErrorActionPreference $ErrorActionPreference = 'Continue' - & dotnet symbol --symbols @serverArgs --output $binary.DirectoryName $binary.FullName 2>&1 | Out-Null + & dotnet symbol --symbols @serverArgs @($binaries.FullName) 2>&1 | Out-Null $ErrorActionPreference = $prevErrorActionPreference } From fdd1b12dcbc401f987a99636bde411f6651c4ae9 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 10:15:12 -0600 Subject: [PATCH 151/174] Call out when package versions are missing --- tools/Get-ExternalSymbolFiles.ps1 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/Get-ExternalSymbolFiles.ps1 b/tools/Get-ExternalSymbolFiles.ps1 index 257f2f4..8e6d42d 100644 --- a/tools/Get-ExternalSymbolFiles.ps1 +++ b/tools/Get-ExternalSymbolFiles.ps1 @@ -1,3 +1,7 @@ +[CmdletBinding(SupportsShouldProcess = $true)] +Param ( +) + # Symbol servers to search for PDBs, in order of priority. $SymbolServers = @( 'https://msdl.microsoft.com/download/symbols' @@ -106,6 +110,9 @@ $1stPartyPackageIds = @() $1stPartyPackageIds | % { $version = Get-PackageVersion $_ if ($version) { + Write-Verbose "Downloading symbols for package '$_' version '$version'." Get-SymbolsFromPackage -id $_ -version $version + } else { + Write-Warning "No version found for package '$_'. Skipping symbol download." } } From 3453297682586e443862305a0ff68bfb5a5327ba Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 10:34:43 -0600 Subject: [PATCH 152/174] Use `dotnet-symbols` 9.0.661903 (the latest public version) --- .config/dotnet-tools.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 9019f11..5ebc2dc 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -38,11 +38,11 @@ "rollForward": false }, "dotnet-symbol": { - "version": "10.0.721401", + "version": "9.0.661903", "commands": [ "dotnet-symbol" ], "rollForward": false } } -} \ No newline at end of file +} From 6fd4c225f77977cc1194497078540ccb33351e7b Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 10:48:15 -0600 Subject: [PATCH 153/174] Fix references to undefined variables --- tools/Install-NuGetPackage.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Install-NuGetPackage.ps1 b/tools/Install-NuGetPackage.ps1 index 42ad123..30e9c4f 100644 --- a/tools/Install-NuGetPackage.ps1 +++ b/tools/Install-NuGetPackage.ps1 @@ -57,7 +57,7 @@ $nugetArgs += '-Verbosity',$Verbosity if ($PSCmdlet.ShouldProcess($PackageId, 'nuget install')) { $p = Start-Process $nugetPath $nugetArgs -NoNewWindow -Wait -PassThru if ($null -ne $p.ExitCode -and $p.ExitCode -ne 0) { - throw "NuGet install failed for package '$PackageId' (version '$requestedVersion') with exit code $exitCode." + throw "NuGet install failed for package '$PackageId' (version '$Version') with exit code $($p.ExitCode)." } } From 710ab015903ef1e1a2dc334cb616652c388c07c7 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 10:50:46 -0600 Subject: [PATCH 154/174] Simplify ps1 syntax The old way worked, but copilot reviews kept flagging it as wrong anyway. So we're just appeasing it. --- tools/Get-ExternalSymbolFiles.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Get-ExternalSymbolFiles.ps1 b/tools/Get-ExternalSymbolFiles.ps1 index 8e6d42d..7b498af 100644 --- a/tools/Get-ExternalSymbolFiles.ps1 +++ b/tools/Get-ExternalSymbolFiles.ps1 @@ -93,7 +93,7 @@ Function Get-PackageVersions() { } Function Get-PackageVersion($id) { - $version = Get-PackageVersions | Select-Object -ExpandProperty $id -ErrorAction SilentlyContinue + $version = (Get-PackageVersions)[$id] if (!$version) { Write-Error "No package version found in Directory.Packages.props for the package '$id'" } From 5c12a14ff4648586cdd85b0c309f63958d97a75d Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 10:57:01 -0600 Subject: [PATCH 155/174] Defend against filename-only output paths --- tools/Convert-PDB.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/Convert-PDB.ps1 b/tools/Convert-PDB.ps1 index d1d0e88..d4e548a 100644 --- a/tools/Convert-PDB.ps1 +++ b/tools/Convert-PDB.ps1 @@ -35,7 +35,10 @@ catch { return } -New-Item -ItemType Directory -Force -Path (Split-Path $OutputPath -Parent) | Out-Null +$outputDirectory = Split-Path $OutputPath -Parent +if ($outputDirectory) { + New-Item -ItemType Directory -Force -Path $outputDirectory | Out-Null +} $toolpath = "$pdb2pdbpath/tools/Pdb2Pdb.exe" $arguments = $DllPath, '/out', $OutputPath, '/nowarn', '0021' From 4738c2bc518d06f21320c5cf24a151eba680e8d0 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 11:14:04 -0600 Subject: [PATCH 156/174] Drop `SupportsShouldProcess` from `Get-ExternalSymbolFiles.ps1` --- tools/Get-ExternalSymbolFiles.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Get-ExternalSymbolFiles.ps1 b/tools/Get-ExternalSymbolFiles.ps1 index 7b498af..e9f8320 100644 --- a/tools/Get-ExternalSymbolFiles.ps1 +++ b/tools/Get-ExternalSymbolFiles.ps1 @@ -1,4 +1,4 @@ -[CmdletBinding(SupportsShouldProcess = $true)] +[CmdletBinding()] Param ( ) From 44ed582605a7de4c2a9b6d783a4b01402c1542b6 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 11:15:25 -0600 Subject: [PATCH 157/174] Use `dotnet msbuild` for `-getItem` parameters --- tools/Get-ExternalSymbolFiles.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/Get-ExternalSymbolFiles.ps1 b/tools/Get-ExternalSymbolFiles.ps1 index e9f8320..c5dbfd3 100644 --- a/tools/Get-ExternalSymbolFiles.ps1 +++ b/tools/Get-ExternalSymbolFiles.ps1 @@ -70,7 +70,7 @@ Function Get-PackageVersions() { } $propsPath = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot '..\Directory.Packages.props')).Path - $output = & dotnet build $propsPath -nologo -verbosity:quiet -getItem:PackageVersion 2>&1 + $output = & dotnet msbuild $propsPath -nologo -verbosity:quiet -getItem:PackageVersion 2>&1 if ($LASTEXITCODE -ne 0) { Write-Error "Failed to evaluate package versions from Directory.Packages.props.`n$($output | Out-String)" return @{} @@ -79,7 +79,7 @@ Function Get-PackageVersions() { $jsonText = ($output | Out-String).Trim() $jsonStart = $jsonText.IndexOf('{') if ($jsonStart -lt 0) { - Write-Error 'Failed to locate JSON output from `dotnet build -getItem:PackageVersion`.' + Write-Error 'Failed to locate JSON output from `dotnet msbuild -getItem:PackageVersion`.' return @{} } From e62e0e7015c618884b509507fb13dd78d1f2aa0f Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 11:16:14 -0600 Subject: [PATCH 158/174] Use -LiteralPath where appropriate --- tools/Get-NuGetTool.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Get-NuGetTool.ps1 b/tools/Get-NuGetTool.ps1 index e507596..088c5f3 100644 --- a/tools/Get-NuGetTool.ps1 +++ b/tools/Get-NuGetTool.ps1 @@ -15,7 +15,7 @@ function Test-NuGetExecutableSignature { [string]$Path ) - if (!(Test-Path $Path)) { + if (!(Test-Path -LiteralPath $Path)) { return $false } From 9ee0ec1b9da2691d9945868a0d1abadc97d43fde Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 11:17:55 -0600 Subject: [PATCH 159/174] Use Join-Path --- tools/Convert-PDB.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Convert-PDB.ps1 b/tools/Convert-PDB.ps1 index d4e548a..27346d6 100644 --- a/tools/Convert-PDB.ps1 +++ b/tools/Convert-PDB.ps1 @@ -40,7 +40,7 @@ if ($outputDirectory) { New-Item -ItemType Directory -Force -Path $outputDirectory | Out-Null } -$toolpath = "$pdb2pdbpath/tools/Pdb2Pdb.exe" +$toolpath = Join-Path $pdb2pdbpath 'tools\Pdb2Pdb.exe' $arguments = $DllPath, '/out', $OutputPath, '/nowarn', '0021' if ($PdbPath) { $arguments += '/pdb', $PdbPath From ea91d46bea5b11cebdf56f6dd1311d6d4eb86f13 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 08:13:56 -0600 Subject: [PATCH 160/174] Add missing `dotnet symbol` command to manifest --- .config/dotnet-tools.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 130ff5e..5ebc2dc 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -36,6 +36,13 @@ "repo" ], "rollForward": false + }, + "dotnet-symbol": { + "version": "9.0.661903", + "commands": [ + "dotnet-symbol" + ], + "rollForward": false } } } From b547bed407e06ea7b0890793df32e3748add1a64 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 15 Apr 2026 12:48:20 -0600 Subject: [PATCH 161/174] Backport fixes from microbuild branch --- tools/Get-3rdPartySymbolFiles.ps1 | 81 +++++++++++++++++++------------ 1 file changed, 50 insertions(+), 31 deletions(-) diff --git a/tools/Get-3rdPartySymbolFiles.ps1 b/tools/Get-3rdPartySymbolFiles.ps1 index 7e15f91..1808438 100644 --- a/tools/Get-3rdPartySymbolFiles.ps1 +++ b/tools/Get-3rdPartySymbolFiles.ps1 @@ -1,55 +1,44 @@ +[CmdletBinding()] +Param ( +) + # Symbol servers to search for PDBs, in order of priority. $SymbolServers = @( 'https://msdl.microsoft.com/download/symbols' 'https://symbols.nuget.org/download/symbols' ) -Function Unzip($Path, $OutDir) { - $OutDir = (New-Item -ItemType Directory -Path $OutDir -Force).FullName - Add-Type -AssemblyName System.IO.Compression.FileSystem - - # Start by extracting to a temporary directory so that there are no file conflicts. - [System.IO.Compression.ZipFile]::ExtractToDirectory($Path, "$OutDir.out") - - # Now move all files from the temp directory to $OutDir, overwriting any files. - Get-ChildItem -Path "$OutDir.out" -Recurse -File | ForEach-Object { - $destinationPath = Join-Path -Path $OutDir -ChildPath $_.FullName.Substring("$OutDir.out".Length).TrimStart([io.path]::DirectorySeparatorChar, [io.path]::AltDirectorySeparatorChar) - if (!(Test-Path -Path (Split-Path -Path $destinationPath -Parent))) { - New-Item -ItemType Directory -Path (Split-Path -Path $destinationPath -Parent) | Out-Null - } - Move-Item -Path $_.FullName -Destination $destinationPath -Force - } - Remove-Item -Path "$OutDir.out" -Recurse -Force -} - Function Get-SymbolsFromPackage($id, $version) { $symbolPackagesPath = "$PSScriptRoot/../obj/SymbolsPackages" New-Item -ItemType Directory -Path $symbolPackagesPath -Force | Out-Null - $unzippedPkgPath = Join-Path $symbolPackagesPath "$id.$version" + $packagePath = $null # Download the package from configured feeds (failures are non-fatal for symbol collection) - & "$PSScriptRoot\Download-NuGetPackage.ps1" -PackageId $id -Version $version -OutputDirectory $symbolPackagesPath -ErrorAction SilentlyContinue | Out-Null - $global:LASTEXITCODE = 0 - $nupkgFile = Get-ChildItem -Recurse -Path $symbolPackagesPath -Filter "$id.$version.nupkg" -ErrorAction SilentlyContinue | Select-Object -First 1 - if (!$nupkgFile) { + $previousLastExitCode = $global:LASTEXITCODE + try { + $packagePath = & "$PSScriptRoot\Download-NuGetPackage.ps1" -PackageId $id -Version $version -OutputDirectory $symbolPackagesPath -ErrorAction SilentlyContinue + } + catch { + Write-Warning "Failed to download package $id $version from configured feeds. Skipping if not found locally. $($_.Exception.Message)" + } + $global:LASTEXITCODE = $previousLastExitCode + if (!$packagePath -or !(Test-Path -LiteralPath $packagePath)) { Write-Warning "Package $id $version not found in configured feeds. Skipping." return } - Unzip -Path $nupkgFile.FullName -OutDir $unzippedPkgPath - # Download symbols for each binary using dotnet-symbol $serverArgs = $SymbolServers | ForEach-Object { '--server-path'; $_ } - $binaries = Get-ChildItem -Recurse -LiteralPath $unzippedPkgPath -Include *.dll, *.exe - foreach ($binary in $binaries) { + $binaries = @(Get-ChildItem -Recurse -LiteralPath $packagePath -Include *.dll, *.exe) + if ($binaries) { $prevErrorActionPreference = $ErrorActionPreference $ErrorActionPreference = 'Continue' - & dotnet symbol --symbols @serverArgs --output $binary.DirectoryName $binary.FullName 2>&1 | Out-Null + & dotnet symbol --symbols @serverArgs @($binaries.FullName) 2>&1 | Out-Null $ErrorActionPreference = $prevErrorActionPreference } # Output pairs of binary + PDB paths for archival - Get-ChildItem -Recurse -LiteralPath $unzippedPkgPath -Filter *.pdb | % { + Get-ChildItem -Recurse -LiteralPath $packagePath -Filter *.pdb | % { $rootName = Join-Path $_.Directory $_.BaseName if ($rootName.EndsWith('.ni')) { $rootName = $rootName.Substring(0, $rootName.Length - 3) @@ -75,9 +64,36 @@ Function Get-SymbolsFromPackage($id, $version) { } } +Function Get-PackageVersions() { + if ($script:PackageVersions) { + return $script:PackageVersions + } + + $propsPath = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot '..\Directory.Packages.props')).Path + $output = & dotnet msbuild $propsPath -nologo -verbosity:quiet -getItem:PackageVersion 2>&1 + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to evaluate package versions from Directory.Packages.props.`n$($output | Out-String)" + return @{} + } + + $jsonText = ($output | Out-String).Trim() + $jsonStart = $jsonText.IndexOf('{') + if ($jsonStart -lt 0) { + Write-Error 'Failed to locate JSON output from `dotnet msbuild -getItem:PackageVersion`.' + return @{} + } + + $packageVersions = @{} + foreach ($item in @((ConvertFrom-Json $jsonText.Substring($jsonStart)).Items.PackageVersion)) { + $packageVersions[$item.Identity] = $item.Version + } + + $script:PackageVersions = $packageVersions + $packageVersions +} + Function Get-PackageVersion($id) { - $versionProps = [xml](Get-Content -LiteralPath $PSScriptRoot\..\Directory.Packages.props) - $version = $versionProps.Project.ItemGroup.PackageVersion | ? { $_.Include -eq $id } | % { $_.Version } + $version = (Get-PackageVersions)[$id] if (!$version) { Write-Error "No package version found in Directory.Packages.props for the package '$id'" } @@ -94,6 +110,9 @@ $3rdPartyPackageIds = @() $3rdPartyPackageIds | % { $version = Get-PackageVersion $_ if ($version) { + Write-Verbose "Downloading symbols for package '$_' version '$version'." Get-SymbolsFromPackage -id $_ -version $version + } else { + Write-Warning "No version found for package '$_'. Skipping symbol download." } } From 0a9483f1a451fc483985a81f072ee632dac55d65 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2026 09:22:19 -0600 Subject: [PATCH 162/174] Update dependency nerdbank.dotnetrepotools to v1.3.22 (509) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 5ebc2dc..89c1b1b 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -31,7 +31,7 @@ "rollForward": false }, "nerdbank.dotnetrepotools": { - "version": "1.3.13", + "version": "1.3.22", "commands": [ "repo" ], From 9ad206a16f966df7cd79cad7b57e4cc42c4387c1 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 22 Apr 2026 14:00:07 -0600 Subject: [PATCH 163/174] Switch AI-assisted merging from a prompt to a skill This makes it available in Copilot CLI. Co-authored-by: Copilot --- .../update-library-template/SKILL.md} | 6 ++++-- .../update-library-template}/template-release-notes.md | 0 2 files changed, 4 insertions(+), 2 deletions(-) rename .github/{prompts/update-library-template.prompt.md => skills/update-library-template/SKILL.md} (92%) rename .github/{prompts => skills/update-library-template}/template-release-notes.md (100%) diff --git a/.github/prompts/update-library-template.prompt.md b/.github/skills/update-library-template/SKILL.md similarity index 92% rename from .github/prompts/update-library-template.prompt.md rename to .github/skills/update-library-template/SKILL.md index f9fe672..a05a2c1 100644 --- a/.github/prompts/update-library-template.prompt.md +++ b/.github/skills/update-library-template/SKILL.md @@ -1,17 +1,19 @@ --- +name: update-library-template description: Merges the latest Library.Template into this repo (at position of HEAD) and resolves conflicts. +disable-model-invocation: true --- # Instructions -1. Run `tools/MergeFrom-Template.ps1` +1. Run `./tools/MergeFrom-Template.ps1` from the repo root. 2. Resolve merge conflicts, taking into account conflict resolution policy below. 3. Validate the changes, as described in the validation section below. 4. Committing your changes (if applicable). ## Conflict resolution policy -There may be special notes in `.github/prompts/template-release-notes.md` that describe special considerations for certain files or scenarios to help you resolve conflicts appropriately. +There may be [special notes](template-release-notes.md) that describe special considerations for certain files or scenarios to help you resolve conflicts appropriately. Always refer to that file before proceeding. In particular, focus on the *incoming* part of the file, since it represents the changes from the Library.Template that you are merging into your repo. diff --git a/.github/prompts/template-release-notes.md b/.github/skills/update-library-template/template-release-notes.md similarity index 100% rename from .github/prompts/template-release-notes.md rename to .github/skills/update-library-template/template-release-notes.md From f3742aa3058f24767c7ba8317f947d4e5c0e6be0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 14:01:11 -0600 Subject: [PATCH 164/174] Update dependency powershell to v7.6.1 (510) --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 89c1b1b..781fe3c 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "powershell": { - "version": "7.6.0", + "version": "7.6.1", "commands": [ "pwsh" ], From 17e9184bfd1327f4724d5ff96221cbe082480f82 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 14:01:46 -0600 Subject: [PATCH 165/174] Update Dockerfile and global.json updates to v10.0.203 (511) --- .devcontainer/Dockerfile | 2 +- global.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 6e0c045..5344ba5 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.202@sha256:adc02be8b87957d07208a4a3e51775935b33bad3317de8c45b1e67357b4c073b +FROM mcr.microsoft.com/dotnet/sdk:10.0.203@sha256:8a90a473da5205a16979de99d2fc20975e922c68304f5c79d564e666dc3982fc # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. diff --git a/global.json b/global.json index 8f46959..441e15a 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.202", + "version": "10.0.203", "rollForward": "patch", "allowPrerelease": false }, From 203696c05271a4daa713f8ee40e6399d58f8f180 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 22 Apr 2026 15:34:21 -0600 Subject: [PATCH 166/174] Use safer `ToLower` variant for package IDs --- tools/Download-NuGetPackage.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Download-NuGetPackage.ps1 b/tools/Download-NuGetPackage.ps1 index 760ac90..5eaa207 100644 --- a/tools/Download-NuGetPackage.ps1 +++ b/tools/Download-NuGetPackage.ps1 @@ -54,7 +54,7 @@ if ($downloadExitCode -ne 0) { } # Return the path to the downloaded package directory (dotnet package download uses lowercase id) -$packageIdLower = $PackageId.ToLower() +$packageIdLower = $PackageId.ToLowerInvariant() if ($Version) { $packageRoot = Join-Path $OutputDirectory $packageIdLower $packageDir = Get-ChildItem -Path $packageRoot -Directory -ErrorAction SilentlyContinue | From cbf54de73f617abe1eb3bfd56eadddd273a6f379 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 16:40:34 -0600 Subject: [PATCH 167/174] Update NuGet/login action to v1.2.0 (512) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a14587a..7b13322 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -79,7 +79,7 @@ jobs: github-token: ${{ github.token }} - name: ๐Ÿชช Authorize NuGet package push - uses: NuGet/login@d22cc5f58ff5b88bf9bd452535b4335137e24544 # v1.1.0 + uses: NuGet/login@8d196754b4036150537f80ac539e15c2f1028841 # v1.2.0 id: nuget-login with: user: ${{ secrets.NUGET_USER }} From 81a01d8d5da7280da2fc7197528dfb3fc58af9ca Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 29 Apr 2026 09:07:44 -0600 Subject: [PATCH 168/174] Ignore C# Dev Kit generated cache files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index cc2b124..31ec354 100644 --- a/.gitignore +++ b/.gitignore @@ -358,3 +358,6 @@ MigrationBackup/ # Analysis results *.sarif + +# C# Dev Kit cache files +*.lscache From 16dd4d1df95076263c1eaaddb06c25f647d28864 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Apr 2026 10:01:58 -0600 Subject: [PATCH 169/174] Update Microsoft Testing Platform to 2.2.2 (514) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index c20bfdc..398de48 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,7 +4,7 @@ true true - 2.2.1 + 2.2.2 From 5c5dd483e5d061aabab9ffd71db01e8180eec82b Mon Sep 17 00:00:00 2001 From: Tevin Stanley Date: Thu, 7 May 2026 10:43:27 -0700 Subject: [PATCH 170/174] remove reliance on mtp testing since it is not needed here --- Directory.Packages.props | 1 - global.json | 3 --- test/Directory.Build.props | 1 - test/Directory.Build.targets | 6 ------ 4 files changed, 11 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index ddec1b5..5473626 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,7 +10,6 @@ - diff --git a/global.json b/global.json index 7499228..689d5fe 100644 --- a/global.json +++ b/global.json @@ -4,9 +4,6 @@ "rollForward": "patch", "allowPrerelease": false }, - "test": { - "runner": "Microsoft.Testing.Platform" - }, "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.56" } diff --git a/test/Directory.Build.props b/test/Directory.Build.props index 466be54..395359d 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -5,7 +5,6 @@ false true - true diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index 3758bb8..9f32cd0 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -1,11 +1,5 @@ - - - - - - From b2297369a7d31fa877edc34d526721317c23c9f9 Mon Sep 17 00:00:00 2001 From: ttstanley <62913657+ttstanley@users.noreply.github.com> Date: Tue, 12 May 2026 10:01:38 -0700 Subject: [PATCH 171/174] fix up some of the issues with build action --- .github/workflows/build.yml | 118 ------------------------------------ Library.slnx | 26 -------- tools/dotnet-test-cloud.ps1 | 2 +- 3 files changed, 1 insertion(+), 145 deletions(-) delete mode 100644 .github/workflows/build.yml delete mode 100644 Library.slnx diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index f4f832e..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,118 +0,0 @@ -name: CI - -on: - push: - branches: - - main - - microbuild - - validate/* - pull_request: - -env: - DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - BUILDCONFIGURATION: Release - # codecov_token: 4dc9e7e2-6b01-4932-a180-847b52b43d35 # Get a new one from https://codecov.io/ - NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages/ - -jobs: - build: - - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: - - windows-2022 - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - - name: โš™ Install prerequisites - run: | - ./init.ps1 -UpgradePrerequisites - dotnet --info - - # Print mono version if it is present. - if (Get-Command mono -ErrorAction SilentlyContinue) { - mono --version - } - shell: pwsh - - name: โš™๏ธ Set pipeline variables based on source - run: tools/variables/_define.ps1 - shell: pwsh - - name: ๐Ÿ›  build - run: dotnet build src -t:build,pack --no-restore -c ${{ env.BUILDCONFIGURATION }} /bl:"${{ runner.temp }}/_artifacts/build_logs/build.binlog" - - name: ๐Ÿงช test - run: tools/dotnet-test-cloud.ps1 -Configuration ${{ env.BUILDCONFIGURATION }} -Agent ${{ runner.os }} - shell: pwsh - - name: ๐Ÿ’…๐Ÿป Verify formatted code - run: dotnet format --verify-no-changes --no-restore - shell: pwsh - if: runner.os == 'Linux' - - name: โš™ Update pipeline variables based on build outputs - run: tools/variables/_define.ps1 - shell: pwsh - - name: ๐Ÿ“ฅ Collect artifacts - run: tools/artifacts/_stage_all.ps1 - shell: pwsh - if: always() - - name: ๐Ÿ“ข Upload project.assets.json files - if: always() - uses: actions/upload-artifact@v4 - with: - name: projectAssetsJson-${{ runner.os }} - path: ${{ runner.temp }}/_artifacts/projectAssetsJson - continue-on-error: true - - name: ๐Ÿ“ข Upload variables - uses: actions/upload-artifact@v4 - with: - name: variables-${{ runner.os }} - path: ${{ runner.temp }}/_artifacts/Variables - continue-on-error: true - - name: ๐Ÿ“ข Upload build_logs - if: always() - uses: actions/upload-artifact@v4 - with: - name: build_logs-${{ runner.os }} - path: ${{ runner.temp }}/_artifacts/build_logs - continue-on-error: true - - name: ๐Ÿ“ข Upload test_logs - if: always() - uses: actions/upload-artifact@v4 - with: - name: test_logs-${{ runner.os }} - path: ${{ runner.temp }}/_artifacts/test_logs - continue-on-error: true - - name: ๐Ÿ“ข Upload testResults - if: always() - uses: actions/upload-artifact@v4 - with: - name: testResults-${{ runner.os }} - path: ${{ runner.temp }}/_artifacts/testResults - continue-on-error: true - - name: ๐Ÿ“ข Upload coverageResults - if: always() - uses: actions/upload-artifact@v4 - with: - name: coverageResults-${{ runner.os }} - path: ${{ runner.temp }}/_artifacts/coverageResults - continue-on-error: true - - name: ๐Ÿ“ข Upload symbols - uses: actions/upload-artifact@v4 - with: - name: symbols-${{ runner.os }} - path: ${{ runner.temp }}/_artifacts/symbols - continue-on-error: true - - name: ๐Ÿ“ข Upload deployables - uses: actions/upload-artifact@v4 - with: - name: deployables-${{ runner.os }} - path: ${{ runner.temp }}/_artifacts/deployables - if: always() - - name: ๐Ÿ“ข Publish code coverage results to codecov.io - run: ./azure-pipelines/publish-CodeCov.ps1 -CodeCovToken "${{ env.codecov_token }}" -PathToCodeCoverage "${{ runner.temp }}/_artifacts/coverageResults" -Name "${{ runner.os }} Coverage Results" -Flags "${{ runner.os }}" - shell: pwsh - timeout-minutes: 3 - continue-on-error: true - if: env.codecov_token != '' diff --git a/Library.slnx b/Library.slnx deleted file mode 100644 index dc016d9..0000000 --- a/Library.slnx +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tools/dotnet-test-cloud.ps1 b/tools/dotnet-test-cloud.ps1 index f239183..85e371d 100644 --- a/tools/dotnet-test-cloud.ps1 +++ b/tools/dotnet-test-cloud.ps1 @@ -87,7 +87,7 @@ if ($isMTP) { $trxFiles = Get-ChildItem -Recurse -Path $testLogs\*.trx } else { $testDiagLog = Join-Path $ArtifactStagingFolder (Join-Path test_logs diag.log) - & $dotnet test $RepoRoot ` + & $dotnet test "$RepoRoot\test\Microsoft.VisualStudio.Jdt.Tests"` --no-build ` -c $Configuration ` --filter "TestCategory!=FailsInCloudTest" ` From 7487573f15464ee2b9c23371b239166c97e06fef Mon Sep 17 00:00:00 2001 From: ttstanley <62913657+ttstanley@users.noreply.github.com> Date: Wed, 13 May 2026 13:50:33 -0700 Subject: [PATCH 172/174] add a scheduled monthly build to ensure we know when things break --- azure-pipelines/official.yml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/azure-pipelines/official.yml b/azure-pipelines/official.yml index 1b3627d..cad5707 100644 --- a/azure-pipelines/official.yml +++ b/azure-pipelines/official.yml @@ -3,12 +3,17 @@ trigger: include: - main pr: none -#schedules: -#- cron: "0 3 * * *" # Daily @ 8 PM PST -# displayName: Daily vs-insertion -# branches: -# include: -# - microbuild + +schedules: +# Monthly compliance sweep: runs at 03:00 UTC (8 PM PST previous day) on the 1st of every month. +# `always: true` ensures it runs even if there have been no code changes since the last successful build, +# so we can detect regressions in compliance tooling (APIScan, PoliCheck, CodeSignValidation, etc.). +- cron: "0 3 1 * *" + displayName: Monthly compliance sweep + branches: + include: + - main + always: true parameters: # As an entrypoint pipeline yml file, all parameters here show up in the Queue Run dialog. From f3201c791d1526c77939b9870de82dcd0a527f3a Mon Sep 17 00:00:00 2001 From: ttstanley <62913657+ttstanley@users.noreply.github.com> Date: Thu, 14 May 2026 09:58:54 -0700 Subject: [PATCH 173/174] fix issue with tests trying to grab the same file --- src/Microsoft.VisualStudio.Jdt/JsonTransformation.cs | 4 ++-- .../Microsoft.VisualStudio.Jdt.Tests.csproj | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.VisualStudio.Jdt/JsonTransformation.cs b/src/Microsoft.VisualStudio.Jdt/JsonTransformation.cs index 3339a34..2928e72 100644 --- a/src/Microsoft.VisualStudio.Jdt/JsonTransformation.cs +++ b/src/Microsoft.VisualStudio.Jdt/JsonTransformation.cs @@ -41,7 +41,7 @@ public JsonTransformation(string transformFile, IJsonTransformationLogger logger this.logger = new JsonTransformationContextLogger(transformFile, logger); - using (FileStream transformStream = File.Open(transformFile, FileMode.Open, FileAccess.Read)) + using (FileStream transformStream = File.Open(transformFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { this.SetTransform(transformStream); } @@ -86,7 +86,7 @@ public Stream Apply(string sourceFile) } // Open the file as streams and apply the transforms - using (Stream sourceStream = File.Open(sourceFile, FileMode.Open, FileAccess.Read)) + using (Stream sourceStream = File.Open(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { return this.ApplyWithSourceName(sourceStream, sourceFile); } diff --git a/test/Microsoft.VisualStudio.Jdt.Tests/Microsoft.VisualStudio.Jdt.Tests.csproj b/test/Microsoft.VisualStudio.Jdt.Tests/Microsoft.VisualStudio.Jdt.Tests.csproj index b511263..1a0431e 100644 --- a/test/Microsoft.VisualStudio.Jdt.Tests/Microsoft.VisualStudio.Jdt.Tests.csproj +++ b/test/Microsoft.VisualStudio.Jdt.Tests/Microsoft.VisualStudio.Jdt.Tests.csproj @@ -1,7 +1,7 @@ ๏ปฟ - net472;net5.0 + net472;net8.0 false $(NoWarn);CS1591 From 027b6868a9c3542e313dbaab2e7ff009f5b3ed8e Mon Sep 17 00:00:00 2001 From: ttstanley <62913657+ttstanley@users.noreply.github.com> Date: Thu, 14 May 2026 10:16:13 -0700 Subject: [PATCH 174/174] update dotnet sdk version in global json --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 689d5fe..00e706b 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.203", + "version": "10.0.204", "rollForward": "patch", "allowPrerelease": false },