From 6a4e43cebdecb716b377a17152569e1ccc79b832 Mon Sep 17 00:00:00 2001 From: "Pierson Lee (PIE)" Date: Mon, 13 Oct 2025 15:32:53 -0700 Subject: [PATCH 01/17] Split the VS PR stage separately from the upload steps There is sometimes an issue with the clone/create PR step. When that happens, the stage isn't requeuable because the VSTS upload step fails when its run again because the payload is already there. This update allows the step to clone the VS repo and create the PR to be rerun due to issues independent of the Upload step. --- azure-pipelines/vs-insertion.yml | 24 +++++++++++++++++++++--- azure-pipelines/vs-validation.yml | 29 +++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/azure-pipelines/vs-insertion.yml b/azure-pipelines/vs-insertion.yml index c19331d42..23e8a058a 100644 --- a/azure-pipelines/vs-insertion.yml +++ b/azure-pipelines/vs-insertion.yml @@ -27,10 +27,10 @@ extends: sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES stages: - - stage: insertion + - stage: upload_payload jobs: - - job: insertion - displayName: VS insertion + - job: upload_payload + displayName: Upload VS payload pool: VSEngSS-MicroBuild2022-1ES templateContext: outputParentDirectory: $(Pipeline.Workspace)/CI @@ -56,6 +56,24 @@ extends: packageParentPath: $(Pipeline.Workspace)/CI/VSInsertion-Windows allowPackageConflicts: true publishVstsFeed: VS + + - stage: insertion + dependsOn: upload_payload + condition: succeeded('upload_payload') + jobs: + - job: insertion + displayName: VS insertion + pool: VSEngSS-MicroBuild2022-1ES + templateContext: + outputParentDirectory: $(Pipeline.Workspace)/CI + steps: + - checkout: none + - powershell: Write-Host "##vso[build.updatebuildnumber]$(resources.pipeline.CI.runName)" + displayName: โš™๏ธ Set pipeline name + - template: azure-pipelines/release-deployment-prep.yml@self + - download: CI + artifact: VSInsertion-Windows + displayName: ๐Ÿ”ป Download VSInsertion-Windows artifact - task: MicroBuildInsertVsPayload@5 displayName: ๐Ÿญ Insert VS Payload inputs: diff --git a/azure-pipelines/vs-validation.yml b/azure-pipelines/vs-validation.yml index b9d46b7c7..42d1dab7c 100644 --- a/azure-pipelines/vs-validation.yml +++ b/azure-pipelines/vs-validation.yml @@ -63,11 +63,11 @@ extends: ArchiveSymbols: false RealSign: false - - stage: insertion - displayName: VS insertion + - stage: upload_payload + displayName: Upload VS payload jobs: - - job: insertion - displayName: VS insertion + - job: upload_payload + displayName: Upload VS payload pool: VSEngSS-MicroBuild2022-1ES steps: - checkout: self @@ -95,6 +95,27 @@ extends: packageParentPath: $(Pipeline.Workspace)/VSInsertion-Windows allowPackageConflicts: true publishVstsFeed: VS + + - stage: insertion + displayName: VS insertion + dependsOn: upload_payload + condition: succeeded('upload_payload') + jobs: + - job: insertion + displayName: VS insertion + pool: VSEngSS-MicroBuild2022-1ES + steps: + - checkout: self + clean: true + fetchDepth: 1 + - download: current + artifact: Variables-Windows + displayName: ๐Ÿ”ป Download Variables-Windows artifact + - powershell: $(Pipeline.Workspace)/Variables-Windows/_define.ps1 + displayName: โš™๏ธ Set pipeline variables based on artifacts + - download: current + artifact: VSInsertion-Windows + displayName: ๐Ÿ”ป Download VSInsertion-Windows artifact - task: MicroBuildInsertVsPayload@5 displayName: ๐Ÿญ Insert VS Payload inputs: From 9ca01b2dcd7574b32b5e7b1572916e544450e247 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 16 Oct 2025 17:07:41 -0600 Subject: [PATCH 02/17] Split into jobs instead of stages Also remove a task that was duplicated (I think) unnecessarily. --- azure-pipelines/vs-insertion.yml | 16 ++++------------ azure-pipelines/vs-validation.yml | 15 ++++----------- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/azure-pipelines/vs-insertion.yml b/azure-pipelines/vs-insertion.yml index 23e8a058a..ba9b521f5 100644 --- a/azure-pipelines/vs-insertion.yml +++ b/azure-pipelines/vs-insertion.yml @@ -27,9 +27,9 @@ extends: sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES stages: - - stage: upload_payload + - stage: insertion jobs: - - job: upload_payload + - job: upload displayName: Upload VS payload pool: VSEngSS-MicroBuild2022-1ES templateContext: @@ -57,23 +57,15 @@ extends: allowPackageConflicts: true publishVstsFeed: VS - - stage: insertion - dependsOn: upload_payload - condition: succeeded('upload_payload') - jobs: - - job: insertion + - job: insert + dependsOn: upload displayName: VS insertion pool: VSEngSS-MicroBuild2022-1ES templateContext: outputParentDirectory: $(Pipeline.Workspace)/CI steps: - checkout: none - - powershell: Write-Host "##vso[build.updatebuildnumber]$(resources.pipeline.CI.runName)" - displayName: โš™๏ธ Set pipeline name - template: azure-pipelines/release-deployment-prep.yml@self - - download: CI - artifact: VSInsertion-Windows - displayName: ๐Ÿ”ป Download VSInsertion-Windows artifact - task: MicroBuildInsertVsPayload@5 displayName: ๐Ÿญ Insert VS Payload inputs: diff --git a/azure-pipelines/vs-validation.yml b/azure-pipelines/vs-validation.yml index 42d1dab7c..4319884e1 100644 --- a/azure-pipelines/vs-validation.yml +++ b/azure-pipelines/vs-validation.yml @@ -63,10 +63,10 @@ extends: ArchiveSymbols: false RealSign: false - - stage: upload_payload - displayName: Upload VS payload + - stage: insertion + displayName: VS insertion jobs: - - job: upload_payload + - job: upload displayName: Upload VS payload pool: VSEngSS-MicroBuild2022-1ES steps: @@ -96,13 +96,9 @@ extends: allowPackageConflicts: true publishVstsFeed: VS - - stage: insertion - displayName: VS insertion - dependsOn: upload_payload - condition: succeeded('upload_payload') - jobs: - job: insertion displayName: VS insertion + dependsOn: upload pool: VSEngSS-MicroBuild2022-1ES steps: - checkout: self @@ -113,9 +109,6 @@ extends: displayName: ๐Ÿ”ป Download Variables-Windows artifact - powershell: $(Pipeline.Workspace)/Variables-Windows/_define.ps1 displayName: โš™๏ธ Set pipeline variables based on artifacts - - download: current - artifact: VSInsertion-Windows - displayName: ๐Ÿ”ป Download VSInsertion-Windows artifact - task: MicroBuildInsertVsPayload@5 displayName: ๐Ÿญ Insert VS Payload inputs: From d48cdf885d0e3661e442b5b955d3195469f298ff Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 10 Jun 2026 07:20:24 -0600 Subject: [PATCH 03/17] Fix GitHub Actions env file writes (528) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use explicit UTF-8 appends for GitHub Actions environment files so Linux runners don't hit an invalid empty-name env entry after build. This updates both the general env propagation helper and the pipeline variable definition script. Co-authored-by: ๐Ÿค– Copilot Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tools/Set-EnvVars.ps1 | 16 ++++++++++++++-- tools/variables/_define.ps1 | 14 +++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/tools/Set-EnvVars.ps1 b/tools/Set-EnvVars.ps1 index 2bd3ca4db..460e63e30 100644 --- a/tools/Set-EnvVars.ps1 +++ b/tools/Set-EnvVars.ps1 @@ -43,6 +43,18 @@ if ($env:GITHUB_ACTIONS) { Write-Host "GitHub Actions detected. Logging commands will be used to propagate environment variables and prepend path." } +function Add-GitHubActionsFileCommand { + param( + [Parameter(Mandatory = $true)] + [string]$Path, + [Parameter(Mandatory = $true)] + [string]$Value + ) + + $utf8NoBom = [System.Text.UTF8Encoding]::new($false) + [System.IO.File]::AppendAllText($Path, "$Value`n", $utf8NoBom) +} + $CmdEnvScript = '' $Variables.GetEnumerator() |% { Set-Item -LiteralPath env:$($_.Key) -Value $_.Value @@ -52,7 +64,7 @@ $Variables.GetEnumerator() |% { Write-Host "##vso[task.setvariable variable=$($_.Key);]$($_.Value)" } if ($env:GITHUB_ACTIONS) { - Add-Content -LiteralPath $env:GITHUB_ENV -Value "$($_.Key)=$($_.Value)" + Add-GitHubActionsFileCommand -Path $env:GITHUB_ENV -Value "$($_.Key)=$($_.Value)" } if ($cmdInstructions) { @@ -79,7 +91,7 @@ if ($PrependPath) { Write-Host "##vso[task.prependpath]$_" } if ($env:GITHUB_ACTIONS) { - Add-Content -LiteralPath $env:GITHUB_PATH -Value $_ + Add-GitHubActionsFileCommand -Path $env:GITHUB_PATH -Value $_ } $CmdEnvScript += "SET PATH=$_$pathDelimiter%PATH%" diff --git a/tools/variables/_define.ps1 b/tools/variables/_define.ps1 index d40e5cf14..8cb536c21 100644 --- a/tools/variables/_define.ps1 +++ b/tools/variables/_define.ps1 @@ -11,6 +11,18 @@ param ( ) +function Add-GitHubActionsFileCommand { + param( + [Parameter(Mandatory = $true)] + [string]$Path, + [Parameter(Mandatory = $true)] + [string]$Value + ) + + $utf8NoBom = [System.Text.UTF8Encoding]::new($false) + [System.IO.File]::AppendAllText($Path, "$Value`n", $utf8NoBom) +} + (& "$PSScriptRoot\_all.ps1").GetEnumerator() |% { # Always use ALL CAPS for env var names since Azure Pipelines converts variable names to all caps and on non-Windows OS, env vars are case sensitive. $keyCaps = $_.Key.ToUpper() @@ -24,7 +36,7 @@ param ( # and the second that works across jobs and stages but must be fully qualified when referenced. Write-Host "##vso[task.setvariable variable=$keyCaps;isOutput=true]$($_.Value)" } elseif ($env:GITHUB_ACTIONS) { - Add-Content -LiteralPath $env:GITHUB_ENV -Value "$keyCaps=$($_.Value)" + Add-GitHubActionsFileCommand -Path $env:GITHUB_ENV -Value "$keyCaps=$($_.Value)" } Set-Item -LiteralPath "env:$keyCaps" -Value $_.Value } From 910fad855551262c156477cf9d50d04b54c61a3e Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 10 Jun 2026 10:48:58 -0600 Subject: [PATCH 04/17] Update actions/checkout action to v6.0.3 --- .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 fa08fdb0c..96e06329a 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: ๐Ÿ”— Markup Link Checker (mlc) From 72ac8a906ecacc231b03fe992280f97ad9029ab6 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 10 Jun 2026 12:02:31 -0600 Subject: [PATCH 05/17] Improve PR checks after fixing dependency PRs --- .github/skills/bundle-dependency-prs/SKILL.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/skills/bundle-dependency-prs/SKILL.md b/.github/skills/bundle-dependency-prs/SKILL.md index a147e81e0..48dedbe9b 100644 --- a/.github/skills/bundle-dependency-prs/SKILL.md +++ b/.github/skills/bundle-dependency-prs/SKILL.md @@ -27,6 +27,7 @@ Before aggregating PRs, first try to fix any individual dependency update PRs wi 1. For the dependency PRs with failing build or test PR checks, check out their source branch and fix any issues. 2. Push your fixes as fresh commits to the individual dependency PRs. + If pushing to a repo in the `microsoft` org when the PR is authord by `renovate`, follow-up the push with a PR comment that says exactly this: "/azp run" which triggers PR checks to re-run. 3. If you can't fix a particular PR, add a comment to the PR describing your attempt and outcome. ## Group dependency PRs that are ready to go From 937aeb05c332bdc78f26e6420a7bd4438182ab83 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 11 Jun 2026 08:12:59 -0600 Subject: [PATCH 06/17] Update Microsoft Testing Platform to 18.8.0 --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index a10e35497..8630c4587 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,7 +10,7 @@ - + From 8ce74d4fc06c1923546ca84e8431b83a362f86d8 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 15 Jun 2026 08:32:30 -0600 Subject: [PATCH 07/17] Support multi-line env var values properly --- tools/Set-EnvVars.ps1 | 24 ++++++++++++++++-------- tools/variables/_define.ps1 | 14 +++++++++++--- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/tools/Set-EnvVars.ps1 b/tools/Set-EnvVars.ps1 index 460e63e30..6fa4ffb9c 100644 --- a/tools/Set-EnvVars.ps1 +++ b/tools/Set-EnvVars.ps1 @@ -43,16 +43,24 @@ if ($env:GITHUB_ACTIONS) { Write-Host "GitHub Actions detected. Logging commands will be used to propagate environment variables and prepend path." } -function Add-GitHubActionsFileCommand { +function Add-GitHubActionsEnvVariable { param( [Parameter(Mandatory = $true)] [string]$Path, [Parameter(Mandatory = $true)] - [string]$Value - ) - - $utf8NoBom = [System.Text.UTF8Encoding]::new($false) - [System.IO.File]::AppendAllText($Path, "$Value`n", $utf8NoBom) + [string]$Name, + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string]$Value + ) + + if ([string]::IsNullOrWhiteSpace($Name)) { + throw "GitHub Actions environment variable names must not be empty." + } + + $utf8NoBom = [System.Text.UTF8Encoding]::new($false) + $delimiter = [guid]::NewGuid().ToString('N') + [System.IO.File]::AppendAllText($Path, "$Name<<$delimiter`n$Value`n$delimiter`n", $utf8NoBom) } $CmdEnvScript = '' @@ -64,7 +72,7 @@ $Variables.GetEnumerator() |% { Write-Host "##vso[task.setvariable variable=$($_.Key);]$($_.Value)" } if ($env:GITHUB_ACTIONS) { - Add-GitHubActionsFileCommand -Path $env:GITHUB_ENV -Value "$($_.Key)=$($_.Value)" + Add-GitHubActionsEnvVariable -Path $env:GITHUB_ENV -Name $_.Key -Value ([string]$_.Value) } if ($cmdInstructions) { @@ -91,7 +99,7 @@ if ($PrependPath) { Write-Host "##vso[task.prependpath]$_" } if ($env:GITHUB_ACTIONS) { - Add-GitHubActionsFileCommand -Path $env:GITHUB_PATH -Value $_ + Add-GitHubActionsEnvVariable -Path $env:GITHUB_ENV -Name PATH -Value $newPathValue } $CmdEnvScript += "SET PATH=$_$pathDelimiter%PATH%" diff --git a/tools/variables/_define.ps1 b/tools/variables/_define.ps1 index 8cb536c21..4a8503d9c 100644 --- a/tools/variables/_define.ps1 +++ b/tools/variables/_define.ps1 @@ -11,16 +11,24 @@ param ( ) -function Add-GitHubActionsFileCommand { +function Add-GitHubActionsEnvVariable { param( [Parameter(Mandatory = $true)] [string]$Path, [Parameter(Mandatory = $true)] + [string]$Name, + [Parameter(Mandatory = $true)] + [AllowEmptyString()] [string]$Value ) + if ([string]::IsNullOrWhiteSpace($Name)) { + throw "GitHub Actions environment variable names must not be empty." + } + $utf8NoBom = [System.Text.UTF8Encoding]::new($false) - [System.IO.File]::AppendAllText($Path, "$Value`n", $utf8NoBom) + $delimiter = [guid]::NewGuid().ToString('N') + [System.IO.File]::AppendAllText($Path, "$Name<<$delimiter`n$Value`n$delimiter`n", $utf8NoBom) } (& "$PSScriptRoot\_all.ps1").GetEnumerator() |% { @@ -36,7 +44,7 @@ function Add-GitHubActionsFileCommand { # and the second that works across jobs and stages but must be fully qualified when referenced. Write-Host "##vso[task.setvariable variable=$keyCaps;isOutput=true]$($_.Value)" } elseif ($env:GITHUB_ACTIONS) { - Add-GitHubActionsFileCommand -Path $env:GITHUB_ENV -Value "$keyCaps=$($_.Value)" + Add-GitHubActionsEnvVariable -Path $env:GITHUB_ENV -Name $keyCaps -Value ([string]$_.Value) } Set-Item -LiteralPath "env:$keyCaps" -Value $_.Value } From 22ebcf56330c216c8b39d6b746b05b3ebda78c58 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 15 Jun 2026 08:36:28 -0600 Subject: [PATCH 08/17] Centralize the github env var function --- tools/GitHubActions.ps1 | 18 ++++++++++++++++++ tools/Set-EnvVars.ps1 | 37 ++++++++++--------------------------- tools/variables/_define.ps1 | 22 ++-------------------- 3 files changed, 30 insertions(+), 47 deletions(-) create mode 100644 tools/GitHubActions.ps1 diff --git a/tools/GitHubActions.ps1 b/tools/GitHubActions.ps1 new file mode 100644 index 000000000..c742a5888 --- /dev/null +++ b/tools/GitHubActions.ps1 @@ -0,0 +1,18 @@ +function Add-GitHubActionsEnvVariable { + param( + [string]$Path = $env:GITHUB_ENV, + [Parameter(Mandatory = $true)] + [string]$Name, + [Parameter(Mandatory = $true)] + [AllowEmptyString()] + [string]$Value + ) + + if ([string]::IsNullOrWhiteSpace($Name)) { + throw "GitHub Actions environment variable names must not be empty." + } + + $utf8NoBom = [System.Text.UTF8Encoding]::new($false) + $delimiter = [guid]::NewGuid().ToString('N') + [System.IO.File]::AppendAllText($Path, "$Name<<$delimiter`n$Value`n$delimiter`n", $utf8NoBom) +} diff --git a/tools/Set-EnvVars.ps1 b/tools/Set-EnvVars.ps1 index 6fa4ffb9c..0816c0e2c 100644 --- a/tools/Set-EnvVars.ps1 +++ b/tools/Set-EnvVars.ps1 @@ -12,13 +12,15 @@ The CmdEnvScriptPath environment variable may be optionally set to a path to a cmd shell script to be created (or appended to if it already exists) that will set the environment variables in cmd.exe that are set within the PowerShell environment. This is used by init.cmd in order to reapply any new environment variables to the parent cmd.exe process that were set in the powershell child process. #> -[CmdletBinding(SupportsShouldProcess=$true)] +[CmdletBinding(SupportsShouldProcess = $true)] Param( - [Parameter(Mandatory=$true, Position=1)] + [Parameter(Mandatory = $true, Position = 1)] $Variables, [string[]]$PrependPath ) +. "$PSScriptRoot\GitHubActions.ps1" + if ($Variables.Count -eq 0) { return $true } @@ -27,7 +29,8 @@ $cmdInstructions = !$env:TF_BUILD -and !$env:GITHUB_ACTIONS -and !$env:CmdEnvScr if ($cmdInstructions) { Write-Warning "Environment variables have been set that will be lost because you're running under cmd.exe" Write-Host "Environment variables that must be set manually:" -ForegroundColor Blue -} else { +} +else { Write-Host "Environment variables set:" -ForegroundColor Blue Write-Host ($Variables | Out-String) if ($PrependPath) { @@ -43,28 +46,8 @@ if ($env:GITHUB_ACTIONS) { Write-Host "GitHub Actions detected. Logging commands will be used to propagate environment variables and prepend path." } -function Add-GitHubActionsEnvVariable { - param( - [Parameter(Mandatory = $true)] - [string]$Path, - [Parameter(Mandatory = $true)] - [string]$Name, - [Parameter(Mandatory = $true)] - [AllowEmptyString()] - [string]$Value - ) - - if ([string]::IsNullOrWhiteSpace($Name)) { - throw "GitHub Actions environment variable names must not be empty." - } - - $utf8NoBom = [System.Text.UTF8Encoding]::new($false) - $delimiter = [guid]::NewGuid().ToString('N') - [System.IO.File]::AppendAllText($Path, "$Name<<$delimiter`n$Value`n$delimiter`n", $utf8NoBom) -} - $CmdEnvScript = '' -$Variables.GetEnumerator() |% { +$Variables.GetEnumerator() | % { Set-Item -LiteralPath env:$($_.Key) -Value $_.Value # If we're running in a cloud CI, set these environment variables so they propagate. @@ -72,7 +55,7 @@ $Variables.GetEnumerator() |% { Write-Host "##vso[task.setvariable variable=$($_.Key);]$($_.Value)" } if ($env:GITHUB_ACTIONS) { - Add-GitHubActionsEnvVariable -Path $env:GITHUB_ENV -Name $_.Key -Value ([string]$_.Value) + Add-GitHubActionsEnvVariable -Name $_.Key -Value ([string]$_.Value) } if ($cmdInstructions) { @@ -88,7 +71,7 @@ if ($IsMacOS -or $IsLinux) { } if ($PrependPath) { - $PrependPath |% { + $PrependPath | % { $newPathValue = "$_$pathDelimiter$env:PATH" Set-Item -LiteralPath env:PATH -Value $newPathValue if ($cmdInstructions) { @@ -99,7 +82,7 @@ if ($PrependPath) { Write-Host "##vso[task.prependpath]$_" } if ($env:GITHUB_ACTIONS) { - Add-GitHubActionsEnvVariable -Path $env:GITHUB_ENV -Name PATH -Value $newPathValue + Add-GitHubActionsEnvVariable -Name PATH -Value $newPathValue } $CmdEnvScript += "SET PATH=$_$pathDelimiter%PATH%" diff --git a/tools/variables/_define.ps1 b/tools/variables/_define.ps1 index 4a8503d9c..dfa9cba42 100644 --- a/tools/variables/_define.ps1 +++ b/tools/variables/_define.ps1 @@ -11,25 +11,7 @@ param ( ) -function Add-GitHubActionsEnvVariable { - param( - [Parameter(Mandatory = $true)] - [string]$Path, - [Parameter(Mandatory = $true)] - [string]$Name, - [Parameter(Mandatory = $true)] - [AllowEmptyString()] - [string]$Value - ) - - if ([string]::IsNullOrWhiteSpace($Name)) { - throw "GitHub Actions environment variable names must not be empty." - } - - $utf8NoBom = [System.Text.UTF8Encoding]::new($false) - $delimiter = [guid]::NewGuid().ToString('N') - [System.IO.File]::AppendAllText($Path, "$Name<<$delimiter`n$Value`n$delimiter`n", $utf8NoBom) -} +. "$PSScriptRoot\..\GitHubActions.ps1" (& "$PSScriptRoot\_all.ps1").GetEnumerator() |% { # Always use ALL CAPS for env var names since Azure Pipelines converts variable names to all caps and on non-Windows OS, env vars are case sensitive. @@ -44,7 +26,7 @@ function Add-GitHubActionsEnvVariable { # and the second that works across jobs and stages but must be fully qualified when referenced. Write-Host "##vso[task.setvariable variable=$keyCaps;isOutput=true]$($_.Value)" } elseif ($env:GITHUB_ACTIONS) { - Add-GitHubActionsEnvVariable -Path $env:GITHUB_ENV -Name $keyCaps -Value ([string]$_.Value) + Add-GitHubActionsEnvVariable -Name $keyCaps -Value ([string]$_.Value) } Set-Item -LiteralPath "env:$keyCaps" -Value $_.Value } From 4a5b860e5ed5e9a41599955a8d16f7dba1475028 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Jun 2026 18:02:26 -0600 Subject: [PATCH 09/17] Update dependency powershell to v7.6.3 (#530) 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 f88bae603..f82fc36a4 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "powershell": { - "version": "7.6.2", + "version": "7.6.3", "commands": [ "pwsh" ], From 3fcf71e38c502f58e3329a44c247d7d11ef74ae4 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 18 Jun 2026 12:30:32 -0600 Subject: [PATCH 10/17] Update actions/checkout action to v7 --- .github/workflows/build.yml | 104 ++++++++-------- .github/workflows/copilot-setup-steps.yml | 30 ++--- .github/workflows/docs.yml | 30 ++--- .github/workflows/libtemplate-update.yml | 140 +++++++++++----------- 4 files changed, 152 insertions(+), 152 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 69e7ae4f8..110b0af51 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,9 +3,9 @@ name: ๐Ÿญ Build on: push: branches: - - main - - 'v*.*' - - validate/* + - main + - "v*.*" + - validate/* pull_request: workflow_dispatch: @@ -23,60 +23,60 @@ jobs: fail-fast: false matrix: os: - - ubuntu-24.04 - - macOS-15 - - windows-2025 + - ubuntu-24.04 + - macOS-15 + - windows-2025 steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - with: - fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - - name: โš™ Install prerequisites - run: | - ./init.ps1 -UpgradePrerequisites - dotnet --info + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + 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 -t:build,pack --no-restore -c ${{ env.BUILDCONFIGURATION }} -warnAsError -warnNotAsError:NU1901,NU1902,NU1903,NU1904 /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: ๐Ÿ“š Verify docfx build - run: dotnet docfx docfx/docfx.json --warningsAsErrors --disableGitFeatures - if: runner.os == 'Linux' - - name: โš™ Update pipeline variables based on build outputs - run: tools/variables/_define.ps1 - shell: pwsh - - name: ๐Ÿ“ข Publish artifacts - uses: ./.github/actions/publish-artifacts - if: cancelled() == false - - name: ๐Ÿ“ข Publish code coverage results to codecov.io - 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 + # 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 -t:build,pack --no-restore -c ${{ env.BUILDCONFIGURATION }} -warnAsError -warnNotAsError:NU1901,NU1902,NU1903,NU1904 /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: ๐Ÿ“š Verify docfx build + run: dotnet docfx docfx/docfx.json --warningsAsErrors --disableGitFeatures + if: runner.os == 'Linux' + - name: โš™ Update pipeline variables based on build outputs + run: tools/variables/_define.ps1 + shell: pwsh + - name: ๐Ÿ“ข Publish artifacts + uses: ./.github/actions/publish-artifacts + if: cancelled() == false + - name: ๐Ÿ“ข Publish code coverage results to codecov.io + 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 docs: name: ๐Ÿ“ƒ Docs runs-on: ubuntu-latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - - name: ๐Ÿ”— Markup Link Checker (mlc) - 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/ + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: ๐Ÿ”— Markup Link Checker (mlc) + 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/ diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index d933871a5..e61bfd524 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -6,12 +6,12 @@ on: workflow_dispatch: push: branches: - - main + - main paths: - - .github/workflows/copilot-setup-steps.yml + - .github/workflows/copilot-setup-steps.yml pull_request: paths: - - .github/workflows/copilot-setup-steps.yml + - .github/workflows/copilot-setup-steps.yml jobs: # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot. @@ -26,16 +26,16 @@ 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@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - with: - fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - - name: โš™ Install prerequisites - run: | - ./init.ps1 -UpgradePrerequisites -NoNuGetCredProvider - dotnet --info + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + fetch-depth: 0 # avoid shallow clone so nbgv can do its work. + - name: โš™ Install prerequisites + run: | + ./init.ps1 -UpgradePrerequisites -NoNuGetCredProvider + dotnet --info - # Print mono version if it is present. - if (Get-Command mono -ErrorAction SilentlyContinue) { - mono --version - } - shell: pwsh + # Print mono version if it is present. + if (Get-Command mono -ErrorAction SilentlyContinue) { + mono --version + } + shell: pwsh diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 99b3c0583..6f0fbaa57 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -3,7 +3,7 @@ name: ๐Ÿ“š Docs on: push: branches: - - main + - main # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. @@ -24,20 +24,20 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - with: - fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - - name: โš™ Install prerequisites - run: ./init.ps1 -UpgradePrerequisites + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + fetch-depth: 0 # avoid shallow clone so nbgv can do its work. + - name: โš™ Install prerequisites + run: ./init.ps1 -UpgradePrerequisites - - run: dotnet docfx docfx/docfx.json - name: ๐Ÿ“š Generate documentation + - run: dotnet docfx docfx/docfx.json + name: ๐Ÿ“š Generate documentation - - name: Upload artifact - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 - with: - path: docfx/_site + - name: Upload artifact + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 + with: + path: docfx/_site - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 diff --git a/.github/workflows/libtemplate-update.yml b/.github/workflows/libtemplate-update.yml index fc8a631f6..6336d6380 100644 --- a/.github/workflows/libtemplate-update.yml +++ b/.github/workflows/libtemplate-update.yml @@ -7,7 +7,7 @@ name: โ›œ Library.Template update on: schedule: - - cron: "0 3 * * Mon" # Sun @ 8 or 9 PM Mountain Time (depending on DST) + - cron: "0 3 * * Mon" # Sun @ 8 or 9 PM Mountain Time (depending on DST) workflow_dispatch: jobs: @@ -17,82 +17,82 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - with: - fetch-depth: 0 # avoid shallow clone so nbgv can do its work. + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - - name: merge - id: merge - shell: pwsh - run: | - $LibTemplateBranch = & ./tools/Get-LibTemplateBasis.ps1 -ErrorIfNotRelated - if ($LASTEXITCODE -ne 0) { - exit $LASTEXITCODE - } - - git fetch https://github.com/aarnott/Library.Template $LibTemplateBranch - if ($LASTEXITCODE -ne 0) { - exit $LASTEXITCODE - } - $LibTemplateCommit = git rev-parse FETCH_HEAD - git diff --stat ...FETCH_HEAD - - if ((git rev-list FETCH_HEAD ^HEAD --count) -eq 0) { - Write-Host "There are no Library.Template updates to merge." - echo "uptodate=true" >> $env:GITHUB_OUTPUT - exit 0 - } + - name: merge + id: merge + shell: pwsh + run: | + $LibTemplateBranch = & ./tools/Get-LibTemplateBasis.ps1 -ErrorIfNotRelated + if ($LASTEXITCODE -ne 0) { + exit $LASTEXITCODE + } - # Pushing commits that add or change files under .github/workflows will cause our workflow to fail. - # But it usually isn't necessary because the target branch already has (or doesn't have) these changes. - # So if the merge doesn't bring in any changes to these files, try the merge locally and push that - # to keep github happy. - if ((git rev-list FETCH_HEAD ^HEAD --count -- .github/workflows) -eq 0) { - # Indeed there are no changes in that area. So merge locally to try to appease GitHub. - git checkout -b auto/libtemplateUpdate - git config user.name "Andrew Arnott" - git config user.email "andrewarnott@live.com" - git merge FETCH_HEAD + git fetch https://github.com/aarnott/Library.Template $LibTemplateBranch if ($LASTEXITCODE -ne 0) { - Write-Host "Merge conflicts prevent creating the pull request. Please run tools/MergeFrom-Template.ps1 locally and push the result as a pull request." - exit 2 + exit $LASTEXITCODE } + $LibTemplateCommit = git rev-parse FETCH_HEAD + git diff --stat ...FETCH_HEAD - git -c http.extraheader="AUTHORIZATION: bearer $env:GH_TOKEN" push origin -u HEAD - } else { - Write-Host "Changes to github workflows are included in this update. Please run tools/MergeFrom-Template.ps1 locally and push the result as a pull request." - exit 1 - } - - name: pull request - shell: pwsh - if: success() && steps.merge.outputs.uptodate != 'true' - run: | - # If there is already an active pull request, don't create a new one. - $existingPR = gh pr list -H auto/libtemplateUpdate --json url | ConvertFrom-Json - if ($existingPR) { - Write-Host "::warning::Skipping pull request creation because one already exists at $($existingPR[0].url)" - exit 0 - } + if ((git rev-list FETCH_HEAD ^HEAD --count) -eq 0) { + Write-Host "There are no Library.Template updates to merge." + echo "uptodate=true" >> $env:GITHUB_OUTPUT + exit 0 + } + + # Pushing commits that add or change files under .github/workflows will cause our workflow to fail. + # But it usually isn't necessary because the target branch already has (or doesn't have) these changes. + # So if the merge doesn't bring in any changes to these files, try the merge locally and push that + # to keep github happy. + if ((git rev-list FETCH_HEAD ^HEAD --count -- .github/workflows) -eq 0) { + # Indeed there are no changes in that area. So merge locally to try to appease GitHub. + git checkout -b auto/libtemplateUpdate + git config user.name "Andrew Arnott" + git config user.email "andrewarnott@live.com" + git merge FETCH_HEAD + if ($LASTEXITCODE -ne 0) { + Write-Host "Merge conflicts prevent creating the pull request. Please run tools/MergeFrom-Template.ps1 locally and push the result as a pull request." + exit 2 + } + + git -c http.extraheader="AUTHORIZATION: bearer $env:GH_TOKEN" push origin -u HEAD + } else { + Write-Host "Changes to github workflows are included in this update. Please run tools/MergeFrom-Template.ps1 locally and push the result as a pull request." + exit 1 + } + - name: pull request + shell: pwsh + if: success() && steps.merge.outputs.uptodate != 'true' + run: | + # If there is already an active pull request, don't create a new one. + $existingPR = gh pr list -H auto/libtemplateUpdate --json url | ConvertFrom-Json + if ($existingPR) { + Write-Host "::warning::Skipping pull request creation because one already exists at $($existingPR[0].url)" + exit 0 + } - $prTitle = "Merge latest Library.Template" - $prBody = "This merges the latest features and fixes from [Library.Template's branch](https://github.com/AArnott/Library.Template/tree/). + $prTitle = "Merge latest Library.Template" + $prBody = "This merges the latest features and fixes from [Library.Template's branch](https://github.com/AArnott/Library.Template/tree/). - โš ๏ธ Do **not** squash this pull request when completing it. You must *merge* it. + โš ๏ธ Do **not** squash this pull request when completing it. You must *merge* it. -
- Merge conflicts? - Resolve merge conflicts locally by carrying out these steps: +
+ Merge conflicts? + Resolve merge conflicts locally by carrying out these steps: - ``` - git fetch - git checkout auto/libtemplateUpdate - git merge origin/main - # resolve conflicts - git commit - git push - ``` -
" + ``` + git fetch + git checkout auto/libtemplateUpdate + git merge origin/main + # resolve conflicts + git commit + git push + ``` +
" - gh pr create -H auto/libtemplateUpdate -b $prBody -t $prTitle - env: - GH_TOKEN: ${{ github.token }} + gh pr create -H auto/libtemplateUpdate -b $prBody -t $prTitle + env: + GH_TOKEN: ${{ github.token }} From 93197387762654785bc0772c82bbd28f418a6fb9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 10:13:38 -0600 Subject: [PATCH 11/17] Update nbgv and nerdbank.gitversioning updates to 3.10.85 (531) 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 f82fc36a4..2ddce27dc 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -17,7 +17,7 @@ "rollForward": false }, "nbgv": { - "version": "3.9.50", + "version": "3.10.85", "commands": [ "nbgv" ], diff --git a/Directory.Packages.props b/Directory.Packages.props index 8630c4587..82ce8d720 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -23,7 +23,7 @@ - +
From 3f53cb6c23aacacd3ba715a1f01460eee869b527 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sat, 20 Jun 2026 11:27:25 -0600 Subject: [PATCH 12/17] Revert unintended whitespace changes --- .github/workflows/build.yml | 104 ++++++++-------- .github/workflows/copilot-setup-steps.yml | 30 ++--- .github/workflows/docs.yml | 30 ++--- .github/workflows/libtemplate-update.yml | 140 +++++++++++----------- 4 files changed, 152 insertions(+), 152 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 110b0af51..94a48d768 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,9 +3,9 @@ name: ๐Ÿญ Build on: push: branches: - - main - - "v*.*" - - validate/* + - main + - 'v*.*' + - validate/* pull_request: workflow_dispatch: @@ -23,60 +23,60 @@ jobs: fail-fast: false matrix: os: - - ubuntu-24.04 - - macOS-15 - - windows-2025 + - ubuntu-24.04 + - macOS-15 + - windows-2025 steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - - name: โš™ Install prerequisites - run: | - ./init.ps1 -UpgradePrerequisites - dotnet --info + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + 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 -t:build,pack --no-restore -c ${{ env.BUILDCONFIGURATION }} -warnAsError -warnNotAsError:NU1901,NU1902,NU1903,NU1904 /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: ๐Ÿ“š Verify docfx build - run: dotnet docfx docfx/docfx.json --warningsAsErrors --disableGitFeatures - if: runner.os == 'Linux' - - name: โš™ Update pipeline variables based on build outputs - run: tools/variables/_define.ps1 - shell: pwsh - - name: ๐Ÿ“ข Publish artifacts - uses: ./.github/actions/publish-artifacts - if: cancelled() == false - - name: ๐Ÿ“ข Publish code coverage results to codecov.io - 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 + # 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 -t:build,pack --no-restore -c ${{ env.BUILDCONFIGURATION }} -warnAsError -warnNotAsError:NU1901,NU1902,NU1903,NU1904 /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: ๐Ÿ“š Verify docfx build + run: dotnet docfx docfx/docfx.json --warningsAsErrors --disableGitFeatures + if: runner.os == 'Linux' + - name: โš™ Update pipeline variables based on build outputs + run: tools/variables/_define.ps1 + shell: pwsh + - name: ๐Ÿ“ข Publish artifacts + uses: ./.github/actions/publish-artifacts + if: cancelled() == false + - name: ๐Ÿ“ข Publish code coverage results to codecov.io + 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 docs: name: ๐Ÿ“ƒ Docs runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - name: ๐Ÿ”— Markup Link Checker (mlc) - 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/ + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: ๐Ÿ”— Markup Link Checker (mlc) + 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/ diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index e61bfd524..c0436e855 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -6,12 +6,12 @@ on: workflow_dispatch: push: branches: - - main + - main paths: - - .github/workflows/copilot-setup-steps.yml + - .github/workflows/copilot-setup-steps.yml pull_request: paths: - - .github/workflows/copilot-setup-steps.yml + - .github/workflows/copilot-setup-steps.yml jobs: # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot. @@ -26,16 +26,16 @@ 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@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - - name: โš™ Install prerequisites - run: | - ./init.ps1 -UpgradePrerequisites -NoNuGetCredProvider - dotnet --info + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + fetch-depth: 0 # avoid shallow clone so nbgv can do its work. + - name: โš™ Install prerequisites + run: | + ./init.ps1 -UpgradePrerequisites -NoNuGetCredProvider + dotnet --info - # Print mono version if it is present. - if (Get-Command mono -ErrorAction SilentlyContinue) { - mono --version - } - shell: pwsh + # Print mono version if it is present. + if (Get-Command mono -ErrorAction SilentlyContinue) { + mono --version + } + shell: pwsh diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 6f0fbaa57..9729dc34b 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -3,7 +3,7 @@ name: ๐Ÿ“š Docs on: push: branches: - - main + - main # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. @@ -24,20 +24,20 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - - name: โš™ Install prerequisites - run: ./init.ps1 -UpgradePrerequisites + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + fetch-depth: 0 # avoid shallow clone so nbgv can do its work. + - name: โš™ Install prerequisites + run: ./init.ps1 -UpgradePrerequisites - - run: dotnet docfx docfx/docfx.json - name: ๐Ÿ“š Generate documentation + - run: dotnet docfx docfx/docfx.json + name: ๐Ÿ“š Generate documentation - - name: Upload artifact - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 - with: - path: docfx/_site + - name: Upload artifact + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 + with: + path: docfx/_site - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 diff --git a/.github/workflows/libtemplate-update.yml b/.github/workflows/libtemplate-update.yml index 6336d6380..dfd3f578b 100644 --- a/.github/workflows/libtemplate-update.yml +++ b/.github/workflows/libtemplate-update.yml @@ -7,7 +7,7 @@ name: โ›œ Library.Template update on: schedule: - - cron: "0 3 * * Mon" # Sun @ 8 or 9 PM Mountain Time (depending on DST) + - cron: "0 3 * * Mon" # Sun @ 8 or 9 PM Mountain Time (depending on DST) workflow_dispatch: jobs: @@ -17,82 +17,82 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - fetch-depth: 0 # avoid shallow clone so nbgv can do its work. + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - - name: merge - id: merge - shell: pwsh - run: | - $LibTemplateBranch = & ./tools/Get-LibTemplateBasis.ps1 -ErrorIfNotRelated - if ($LASTEXITCODE -ne 0) { - exit $LASTEXITCODE - } + - name: merge + id: merge + shell: pwsh + run: | + $LibTemplateBranch = & ./tools/Get-LibTemplateBasis.ps1 -ErrorIfNotRelated + if ($LASTEXITCODE -ne 0) { + exit $LASTEXITCODE + } - git fetch https://github.com/aarnott/Library.Template $LibTemplateBranch - if ($LASTEXITCODE -ne 0) { - exit $LASTEXITCODE - } - $LibTemplateCommit = git rev-parse FETCH_HEAD - git diff --stat ...FETCH_HEAD + git fetch https://github.com/aarnott/Library.Template $LibTemplateBranch + if ($LASTEXITCODE -ne 0) { + exit $LASTEXITCODE + } + $LibTemplateCommit = git rev-parse FETCH_HEAD + git diff --stat ...FETCH_HEAD - if ((git rev-list FETCH_HEAD ^HEAD --count) -eq 0) { - Write-Host "There are no Library.Template updates to merge." - echo "uptodate=true" >> $env:GITHUB_OUTPUT - exit 0 - } + if ((git rev-list FETCH_HEAD ^HEAD --count) -eq 0) { + Write-Host "There are no Library.Template updates to merge." + echo "uptodate=true" >> $env:GITHUB_OUTPUT + exit 0 + } - # Pushing commits that add or change files under .github/workflows will cause our workflow to fail. - # But it usually isn't necessary because the target branch already has (or doesn't have) these changes. - # So if the merge doesn't bring in any changes to these files, try the merge locally and push that - # to keep github happy. - if ((git rev-list FETCH_HEAD ^HEAD --count -- .github/workflows) -eq 0) { - # Indeed there are no changes in that area. So merge locally to try to appease GitHub. - git checkout -b auto/libtemplateUpdate - git config user.name "Andrew Arnott" - git config user.email "andrewarnott@live.com" - git merge FETCH_HEAD - if ($LASTEXITCODE -ne 0) { - Write-Host "Merge conflicts prevent creating the pull request. Please run tools/MergeFrom-Template.ps1 locally and push the result as a pull request." - exit 2 - } - - git -c http.extraheader="AUTHORIZATION: bearer $env:GH_TOKEN" push origin -u HEAD - } else { - Write-Host "Changes to github workflows are included in this update. Please run tools/MergeFrom-Template.ps1 locally and push the result as a pull request." - exit 1 - } - - name: pull request - shell: pwsh - if: success() && steps.merge.outputs.uptodate != 'true' - run: | - # If there is already an active pull request, don't create a new one. - $existingPR = gh pr list -H auto/libtemplateUpdate --json url | ConvertFrom-Json - if ($existingPR) { - Write-Host "::warning::Skipping pull request creation because one already exists at $($existingPR[0].url)" - exit 0 + # Pushing commits that add or change files under .github/workflows will cause our workflow to fail. + # But it usually isn't necessary because the target branch already has (or doesn't have) these changes. + # So if the merge doesn't bring in any changes to these files, try the merge locally and push that + # to keep github happy. + if ((git rev-list FETCH_HEAD ^HEAD --count -- .github/workflows) -eq 0) { + # Indeed there are no changes in that area. So merge locally to try to appease GitHub. + git checkout -b auto/libtemplateUpdate + git config user.name "Andrew Arnott" + git config user.email "andrewarnott@live.com" + git merge FETCH_HEAD + if ($LASTEXITCODE -ne 0) { + Write-Host "Merge conflicts prevent creating the pull request. Please run tools/MergeFrom-Template.ps1 locally and push the result as a pull request." + exit 2 } - $prTitle = "Merge latest Library.Template" - $prBody = "This merges the latest features and fixes from [Library.Template's branch](https://github.com/AArnott/Library.Template/tree/). + git -c http.extraheader="AUTHORIZATION: bearer $env:GH_TOKEN" push origin -u HEAD + } else { + Write-Host "Changes to github workflows are included in this update. Please run tools/MergeFrom-Template.ps1 locally and push the result as a pull request." + exit 1 + } + - name: pull request + shell: pwsh + if: success() && steps.merge.outputs.uptodate != 'true' + run: | + # If there is already an active pull request, don't create a new one. + $existingPR = gh pr list -H auto/libtemplateUpdate --json url | ConvertFrom-Json + if ($existingPR) { + Write-Host "::warning::Skipping pull request creation because one already exists at $($existingPR[0].url)" + exit 0 + } + + $prTitle = "Merge latest Library.Template" + $prBody = "This merges the latest features and fixes from [Library.Template's branch](https://github.com/AArnott/Library.Template/tree/). - โš ๏ธ Do **not** squash this pull request when completing it. You must *merge* it. + โš ๏ธ Do **not** squash this pull request when completing it. You must *merge* it. -
- Merge conflicts? - Resolve merge conflicts locally by carrying out these steps: +
+ Merge conflicts? + Resolve merge conflicts locally by carrying out these steps: - ``` - git fetch - git checkout auto/libtemplateUpdate - git merge origin/main - # resolve conflicts - git commit - git push - ``` -
" + ``` + git fetch + git checkout auto/libtemplateUpdate + git merge origin/main + # resolve conflicts + git commit + git push + ``` +
" - gh pr create -H auto/libtemplateUpdate -b $prBody -t $prTitle - env: - GH_TOKEN: ${{ github.token }} + gh pr create -H auto/libtemplateUpdate -b $prBody -t $prTitle + env: + GH_TOKEN: ${{ github.token }} From 8a8921ae310197c01b11573034e4ac859269ed70 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 22 Jun 2026 11:11:10 -0600 Subject: [PATCH 13/17] Update jobs to ubuntu 24 --- azure-pipelines/archive-sourcecode.yml | 2 +- azure-pipelines/libtemplate-update.yml | 2 +- azure-pipelines/official.yml | 2 +- azure-pipelines/prepare-insertion-stages.yml | 2 +- azure-pipelines/release.yml | 4 ++-- azure-pipelines/unofficial.yml | 2 +- azure-pipelines/vs-validation.yml | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/azure-pipelines/archive-sourcecode.yml b/azure-pipelines/archive-sourcecode.yml index 211881fa7..9e075df5a 100644 --- a/azure-pipelines/archive-sourcecode.yml +++ b/azure-pipelines/archive-sourcecode.yml @@ -45,7 +45,7 @@ extends: pool: name: AzurePipelines-EO demands: - - ImageOverride -equals 1ESPT-Ubuntu22.04 + - ImageOverride -equals 1ESPT-Ubuntu24.04 os: Linux steps: diff --git a/azure-pipelines/libtemplate-update.yml b/azure-pipelines/libtemplate-update.yml index 384be7cfc..4efbd2079 100644 --- a/azure-pipelines/libtemplate-update.yml +++ b/azure-pipelines/libtemplate-update.yml @@ -45,7 +45,7 @@ extends: pool: name: AzurePipelines-EO demands: - - ImageOverride -equals 1ESPT-Ubuntu22.04 + - ImageOverride -equals 1ESPT-Ubuntu24.04 os: Linux steps: - checkout: self diff --git a/azure-pipelines/official.yml b/azure-pipelines/official.yml index 22a5d6a33..38e95f2f5 100644 --- a/azure-pipelines/official.yml +++ b/azure-pipelines/official.yml @@ -74,7 +74,7 @@ extends: linuxPool: name: AzurePipelines-EO demands: - - ImageOverride -equals 1ESPT-Ubuntu22.04 + - ImageOverride -equals 1ESPT-Ubuntu24.04 os: Linux macOSPool: name: Azure Pipelines diff --git a/azure-pipelines/prepare-insertion-stages.yml b/azure-pipelines/prepare-insertion-stages.yml index 9f934f92c..675912bce 100644 --- a/azure-pipelines/prepare-insertion-stages.yml +++ b/azure-pipelines/prepare-insertion-stages.yml @@ -51,7 +51,7 @@ stages: pool: name: AzurePipelines-EO demands: - - ImageOverride -equals 1ESPT-Ubuntu22.04 + - ImageOverride -equals 1ESPT-Ubuntu24.04 os: Linux templateContext: outputs: diff --git a/azure-pipelines/release.yml b/azure-pipelines/release.yml index edc565290..a16f98a4d 100644 --- a/azure-pipelines/release.yml +++ b/azure-pipelines/release.yml @@ -31,7 +31,7 @@ extends: pool: name: AzurePipelines-EO demands: - - ImageOverride -equals 1ESPT-Ubuntu22.04 + - ImageOverride -equals 1ESPT-Ubuntu24.04 os: Linux templateContext: outputs: @@ -54,7 +54,7 @@ extends: pool: name: AzurePipelines-EO demands: - - ImageOverride -equals 1ESPT-Ubuntu22.04 + - ImageOverride -equals 1ESPT-Ubuntu24.04 os: Linux templateContext: type: releaseJob diff --git a/azure-pipelines/unofficial.yml b/azure-pipelines/unofficial.yml index 36aaf6e50..51752535a 100644 --- a/azure-pipelines/unofficial.yml +++ b/azure-pipelines/unofficial.yml @@ -87,7 +87,7 @@ extends: linuxPool: name: AzurePipelines-EO demands: - - ImageOverride -equals 1ESPT-Ubuntu22.04 + - ImageOverride -equals 1ESPT-Ubuntu24.04 os: Linux macOSPool: name: Azure Pipelines diff --git a/azure-pipelines/vs-validation.yml b/azure-pipelines/vs-validation.yml index 6a839d472..0eb2c2abe 100644 --- a/azure-pipelines/vs-validation.yml +++ b/azure-pipelines/vs-validation.yml @@ -48,7 +48,7 @@ extends: linuxPool: name: AzurePipelines-EO demands: - - ImageOverride -equals 1ESPT-Ubuntu22.04 + - ImageOverride -equals 1ESPT-Ubuntu24.04 os: Linux macOSPool: name: Azure Pipelines From d7904f8c308a457ae2d06adea4040c1f8f2dc275 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 07:25:38 -0600 Subject: [PATCH 14/17] Update Dockerfile and global.json updates (532) 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 08c018507..635ed8c6e 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.301@sha256:548d93f8a18a1acbe6cc127bc4f47281430d34a9e35c18afa80a8d6741c2adc3 +FROM mcr.microsoft.com/dotnet/sdk:10.0.301@sha256:ea8bde36c11b6e7eec2656d0e59101d4462f6bd630730f2c8201ed0572b295d5 # 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 a1ba5694dbf42e55db3a4da4a10896a8c8ca586e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Jul 2026 16:33:41 +0000 Subject: [PATCH 15/17] Update Microsoft Testing Platform to 2.3.0 --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 82ce8d720..fa4d20367 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,7 +4,7 @@ true true - 2.2.3 + 2.3.0 From 35daa41ee3d87b5ac610ef03b49733ca77613695 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 7 Jul 2026 13:40:09 -0600 Subject: [PATCH 16/17] Pin Microsoft.Testing.Extensions.Telemetry to the common MTP version --- Directory.Packages.props | 1 + 1 file changed, 1 insertion(+) diff --git a/Directory.Packages.props b/Directory.Packages.props index fa4d20367..31eb8113a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -13,6 +13,7 @@ + From eba6257dfab62a90bbc00fbb9778d7a3382a0f9a Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 7 Jul 2026 15:48:59 -0600 Subject: [PATCH 17/17] Revert "Use default configuration for Network Isolation" (#534) --- 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 9e075df5a..cb8d68e9c 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,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable diff --git a/azure-pipelines/libtemplate-update.yml b/azure-pipelines/libtemplate-update.yml index 4efbd2079..acbfbacef 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,CFSClean2 sdl: sourceAnalysisPool: name: AzurePipelines-EO diff --git a/azure-pipelines/official.yml b/azure-pipelines/official.yml index 38e95f2f5..99815ebbe 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,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable codeSignValidation: diff --git a/azure-pipelines/release.yml b/azure-pipelines/release.yml index a16f98a4d..8b7f8c908 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,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable diff --git a/azure-pipelines/unofficial.yml b/azure-pipelines/unofficial.yml index 51752535a..efc60f322 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,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable credscan: diff --git a/azure-pipelines/vs-insertion.yml b/azure-pipelines/vs-insertion.yml index 5e5a476cf..edb114c46 100644 --- a/azure-pipelines/vs-insertion.yml +++ b/azure-pipelines/vs-insertion.yml @@ -22,6 +22,8 @@ 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 0eb2c2abe..3f2a194f6 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,CFSClean2 sdl: sourceAnalysisPool: VSEng-MicroBuildVSStable credscan: