From e4d167c8957d8039b34d7f34a2f7f5899656db54 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 6 Aug 2026 14:56:38 +0200 Subject: [PATCH 1/9] Update dependencies from https://github.com/dotnet/arcade build 20260805.5 Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26379.2 -> To Version 10.0.0-beta.26405.5 --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 4 ++-- eng/common/core-templates/job/publish-build-assets.yml | 1 - eng/common/core-templates/jobs/codeql-build.yml | 1 - eng/common/core-templates/post-build/common-variables.yml | 2 -- eng/common/core-templates/steps/publish-logs.yml | 2 -- global.json | 2 +- 7 files changed, 4 insertions(+), 10 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 14342e49c4b..e5153f0f701 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -6,7 +6,7 @@ This file should be imported by eng/Versions.props - 10.0.0-beta.26379.2 + 10.0.0-beta.26405.5 18.0.2 18.0.2 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3aab3c89882..1896d8db72b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -80,9 +80,9 @@ - + https://github.com/dotnet/arcade - c5d54a9de6e0e20a85e37fa3576a37235276772b + 39512636419fde2a7592617a4a1f17a41d3f0d83 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml index 53af522d6d4..98329da4588 100644 --- a/eng/common/core-templates/job/publish-build-assets.yml +++ b/eng/common/core-templates/job/publish-build-assets.yml @@ -58,7 +58,6 @@ jobs: parameters: is1ESPipeline: ${{ parameters.is1ESPipeline }} - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: Publish-Build-Assets - group: AzureDevOps-Artifact-Feeds-Pats - name: runCodesignValidationInjection value: false diff --git a/eng/common/core-templates/jobs/codeql-build.yml b/eng/common/core-templates/jobs/codeql-build.yml index dbc14ac580a..7d5e0473a1d 100644 --- a/eng/common/core-templates/jobs/codeql-build.yml +++ b/eng/common/core-templates/jobs/codeql-build.yml @@ -18,7 +18,6 @@ jobs: enableTelemetry: true variables: - - group: Publish-Build-Assets # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in # sync with the packages.config file. - name: DefaultGuardianVersion diff --git a/eng/common/core-templates/post-build/common-variables.yml b/eng/common/core-templates/post-build/common-variables.yml index d5627a994ae..3413a9a573e 100644 --- a/eng/common/core-templates/post-build/common-variables.yml +++ b/eng/common/core-templates/post-build/common-variables.yml @@ -1,6 +1,4 @@ variables: - - group: Publish-Build-Assets - # Whether the build is internal or not - name: IsInternalBuild value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} diff --git a/eng/common/core-templates/steps/publish-logs.yml b/eng/common/core-templates/steps/publish-logs.yml index 4411b3b0eeb..faf703157c8 100644 --- a/eng/common/core-templates/steps/publish-logs.yml +++ b/eng/common/core-templates/steps/publish-logs.yml @@ -30,8 +30,6 @@ steps: -TokensFilePath '$(System.DefaultWorkingDirectory)/eng/BinlogSecretsRedactionFile.txt' -runtimeSourceFeed https://ci.dot.net/internal -runtimeSourceFeedKey '$(dotnetbuilds-internal-container-read-token-base64)' - '$(publishing-dnceng-devdiv-code-r-build-re)' - '$(akams-client-id)' '$(dn-bot-all-orgs-build-rw-code-rw)' '$(System.AccessToken)' ${{parameters.CustomSensitiveDataList}} diff --git a/global.json b/global.json index 51e7fcbad76..8202122a37f 100644 --- a/global.json +++ b/global.json @@ -22,7 +22,7 @@ "perl": "5.38.2.2" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26379.2", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26405.5", "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2" } } From b6a74457bbc70734b803d504c9f8d51c6d3dd287 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 6 Aug 2026 14:56:38 +0200 Subject: [PATCH 2/9] Disable publish for FSharp.Benchmarks.sln build to fix arcade Publish.proj failure Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- eng/Build.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/eng/Build.ps1 b/eng/Build.ps1 index 5b3c5c48a49..c402578486f 100644 --- a/eng/Build.ps1 +++ b/eng/Build.ps1 @@ -606,7 +606,11 @@ try { } if ($testBenchmarks) { + # Benchmarks do not produce any publishing artifacts, and arcade publish.proj is failing when it encounters 0 items to publish. + $originalPublishValue = $publish + $publish = $False BuildSolution "FSharp.Benchmarks.sln" $False + $publish = $originalPublishValue } # When building in product build mode, only build the compiler solution. From 48a90adaf1daed06e50d49014965cea8d434686d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 7 Aug 2026 02:04:54 +0000 Subject: [PATCH 3/9] Update dependencies from https://github.com/dotnet/arcade build 20260806.9 On relative base path root Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26379.2 -> To Version 10.0.0-beta.26406.9 --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 4 +- eng/common/Get-GitHubAppToken.ps1 | 154 ++++++++++++++++++ eng/common/core-templates/job/onelocbuild.yml | 28 +++- .../job/publish-build-assets.yml | 1 - .../steps/get-github-app-token.yml | 79 +++++++++ .../steps/get-github-app-token.yml | 7 + .../templates/steps/get-github-app-token.yml | 7 + global.json | 2 +- 9 files changed, 278 insertions(+), 6 deletions(-) create mode 100644 eng/common/Get-GitHubAppToken.ps1 create mode 100644 eng/common/core-templates/steps/get-github-app-token.yml create mode 100644 eng/common/templates-official/steps/get-github-app-token.yml create mode 100644 eng/common/templates/steps/get-github-app-token.yml diff --git a/eng/Version.Details.props b/eng/Version.Details.props index e5153f0f701..d80cd377563 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -6,7 +6,7 @@ This file should be imported by eng/Versions.props - 10.0.0-beta.26405.5 + 10.0.0-beta.26406.9 18.0.2 18.0.2 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1896d8db72b..3199c7b52f4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -80,9 +80,9 @@ - + https://github.com/dotnet/arcade - 39512636419fde2a7592617a4a1f17a41d3f0d83 + af57946065838fca9b1745ab055d5a15a4783fba https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/common/Get-GitHubAppToken.ps1 b/eng/common/Get-GitHubAppToken.ps1 new file mode 100644 index 00000000000..6b5899d7a29 --- /dev/null +++ b/eng/common/Get-GitHubAppToken.ps1 @@ -0,0 +1,154 @@ +# Mints a short-lived GitHub App installation access token by signing a JWT +# with a private key stored in Azure Key Vault (RSA, RS256). The signed JWT is +# exchanged with the GitHub API for a token scoped to a single installation. +# +# Requirements: +# - A GitHub App whose private key has been uploaded into Key Vault as an RSA +# key (the PEM converted to a Key Vault *key*, NOT stored as a secret). +# - The caller (the federated Azure service connection used to run this script) +# must have the `Key Vault Crypto User` role (or at minimum the `Sign` +# action) on that key. +# - The App must be installed on the target organization/account +# (`InstallationOwner`) with the permissions/repositories it needs. +# +# Installation tokens (ghs_*) are exempt from the enterprise classic-PAT +# lifetime policy, which is why this replaces the long-lived PAT. + +[CmdletBinding()] +param( + # Name of the Key Vault that holds the GitHub App's RSA signing key. + [Parameter(Mandatory = $true)] + [string] $KeyVaultName, + + # Name of the RSA key inside the Key Vault (the App's private key). + [Parameter(Mandatory = $true)] + [string] $KeyName, + + # The GitHub App's Client ID (the value to put in the `iss` JWT claim). + [Parameter(Mandatory = $true)] + [string] $AppClientId, + + # Login of the organization or user account whose installation we should + # mint the token for (e.g. `dotnet`, `microsoft`). + [Parameter(Mandatory = $true)] + [string] $InstallationOwner, + + # Optional Azure DevOps pipeline variable name to set with the installation + # token (marked as a secret). When not specified, the token is written to + # stdout instead. + [Parameter(Mandatory = $false)] + [string] $OutputVariableName +) + +$ErrorActionPreference = 'Stop' +$PSNativeCommandUseErrorActionPreference = $true + +. $PSScriptRoot\pipeline-logging-functions.ps1 + +function ConvertTo-Base64Url([byte[]] $bytes) { + return [Convert]::ToBase64String($bytes).TrimEnd('=').Replace('+', '-').Replace('/', '_') +} + +# Build JWT header and payload. Use [ordered] hashtables so JSON +# serialization is deterministic. +$jwtHeader = [ordered]@{ + alg = 'RS256' + typ = 'JWT' +} +$now = [System.DateTimeOffset]::UtcNow +$jwtPayload = [ordered]@{ + iat = $now.AddMinutes(-1).ToUnixTimeSeconds() + exp = $now.AddMinutes(5).ToUnixTimeSeconds() + iss = $AppClientId +} + +$headerEncoded = ConvertTo-Base64Url ([System.Text.Encoding]::UTF8.GetBytes(($jwtHeader | ConvertTo-Json -Compress))) +$payloadEncoded = ConvertTo-Base64Url ([System.Text.Encoding]::UTF8.GetBytes(($jwtPayload | ConvertTo-Json -Compress))) +$signingInput = "$headerEncoded.$payloadEncoded" + +# Key Vault `sign` expects the *digest* (base64), not the raw bytes. +$sha256 = [System.Security.Cryptography.SHA256]::Create() +$digestBytes = $sha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($signingInput)) +$digestBase64 = [Convert]::ToBase64String($digestBytes) + +Write-Host "Signing JWT with key '$KeyName' in vault '$KeyVaultName'..." +$previousNativeCommandErrorPreference = $PSNativeCommandUseErrorActionPreference +try { + # Azure CLI can emit non-fatal Python warnings to stderr even when signing succeeds. + # Use the exit code to determine success for this invocation. + $PSNativeCommandUseErrorActionPreference = $false + $signatureBase64 = az keyvault key sign ` + --vault-name $KeyVaultName ` + --name $KeyName ` + --algorithm RS256 ` + --digest $digestBase64 ` + --query signature ` + --output tsv ` + --only-show-errors + $signExitCode = $LASTEXITCODE +} +catch { + Write-PipelineTelemetryError -Category 'Build' -Message "Failed to sign the JWT via Key Vault (key '$KeyName', vault '$KeyVaultName'): $_. Verify the service connection identity has the 'Key Vault Crypto User' role (Sign action) on the key." + exit 1 +} +finally { + $PSNativeCommandUseErrorActionPreference = $previousNativeCommandErrorPreference +} +if ($signExitCode -ne 0 -or [string]::IsNullOrWhiteSpace($signatureBase64)) { + Write-PipelineTelemetryError -Category 'Build' -Message "'az keyvault key sign' exited with code $signExitCode for key '$KeyName' in vault '$KeyVaultName'. Verify the service connection identity has the 'Key Vault Crypto User' role (Sign action) on the key." + exit 1 +} +$signatureUrl = $signatureBase64.Trim().TrimEnd('=').Replace('+', '-').Replace('/', '_') +$jwt = "$signingInput.$signatureUrl" + +$headers = @{ + Authorization = "Bearer $jwt" + 'X-GitHub-Api-Version' = '2022-11-28' + Accept = 'application/vnd.github+json' + 'User-Agent' = 'dotnet-arcade-onelocbuild' +} + +Write-Host "Looking up installation for '$InstallationOwner'..." +try { + $installations = @() + $page = 1 + do { + $pageInstallations = @(Invoke-RestMethod ` + -Uri "https://api.github.com/app/installations?per_page=100&page=$page" ` + -Headers $headers ` + -Method Get) + $installations += $pageInstallations + $page++ + } while ($pageInstallations.Count -eq 100) +} +catch { + Write-PipelineTelemetryError -Category 'Build' -Message "Failed to list GitHub App installations: $_. The signed JWT may be invalid or the App's Client ID ('$AppClientId') may be incorrect." + exit 1 +} +$installation = $installations | Where-Object { $_.account.login -ieq $InstallationOwner } | Select-Object -First 1 +if (-not $installation) { + $found = ($installations | ForEach-Object { $_.account.login }) -join ', ' + Write-PipelineTelemetryError -Category 'Build' -Message "No installation found for '$InstallationOwner'. App is installed on: $found" + exit 1 +} + +try { + $tokenResponse = Invoke-RestMethod ` + -Uri "https://api.github.com/app/installations/$($installation.id)/access_tokens" ` + -Headers $headers ` + -Method Post ` + -ContentType 'application/json' +} +catch { + Write-PipelineTelemetryError -Category 'Build' -Message "Failed to mint an installation access token for '$InstallationOwner' (installation $($installation.id)): $_" + exit 1 +} + +Write-Host "Got installation token for '$InstallationOwner' (expires $($tokenResponse.expires_at))." +if ($OutputVariableName) { + Write-Host "Setting pipeline variable '$OutputVariableName'." + Write-Host "##vso[task.setvariable variable=$OutputVariableName;issecret=true]$($tokenResponse.token)" +} +else { + Write-Host $tokenResponse.token -ForegroundColor Green +} diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml index 12d7e55a94b..b28af6613c2 100644 --- a/eng/common/core-templates/job/onelocbuild.yml +++ b/eng/common/core-templates/job/onelocbuild.yml @@ -14,6 +14,15 @@ parameters: # exist, and any pipeline that sets this to '' fall back to PAT-based auth via the CeapexPat parameter. CeapexServiceConnection: 'dnceng-onelocbuild-ceapex' + # GitHub App authentication for the OneLoc check-in PR (dnceng/internal only). + # The infrastructure identifiers are centralized here and the App path is enabled by default. + # DevDiv requires its own project-scoped service connection before this path can be enabled there. + UseGitHubAppAuthentication: true + GitHubAppServiceConnection: 'dnceng-oneloc-githubapp' + GitHubAppClientId: 'Iv23lijBU8x3gc9lDOc9' + GitHubAppKeyVaultName: 'EngKeyVault' + GitHubAppKeyName: 'oneloc-localization-app-key' + SourcesDirectory: $(System.DefaultWorkingDirectory) CreatePr: true AutoCompletePr: false @@ -88,6 +97,20 @@ jobs: outputVariableName: 'CeapexEntraToken' condition: ${{ parameters.condition }} + # Mint a short-lived GitHub App installation token for the loc check-in PR (dnceng/internal only). + # All other projects fall back to PAT-based auth, since the app service connection is scoped to dnceng/internal. + - ${{ if and(eq(parameters.RepoType, 'gitHub'), eq(parameters.UseGitHubAppAuthentication, true), eq(variables['System.TeamProject'], 'internal')) }}: + - template: /eng/common/core-templates/steps/get-github-app-token.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + azureSubscription: ${{ parameters.GitHubAppServiceConnection }} + keyVaultName: ${{ parameters.GitHubAppKeyVaultName }} + keyName: ${{ parameters.GitHubAppKeyName }} + appClientId: ${{ parameters.GitHubAppClientId }} + installationOwner: ${{ parameters.GitHubOrg }} + outputVariableName: 'GitHubAppInstallationToken' + condition: ${{ parameters.condition }} + - task: OneLocBuild@2 displayName: OneLocBuild env: @@ -109,7 +132,10 @@ jobs: patVariable: ${{ parameters.CeapexPat }} ${{ if eq(parameters.RepoType, 'gitHub') }}: repoType: ${{ parameters.RepoType }} - gitHubPatVariable: "${{ parameters.GithubPat }}" + ${{ if and(eq(parameters.UseGitHubAppAuthentication, true), eq(variables['System.TeamProject'], 'internal')) }}: + gitHubPatVariable: "$(GitHubAppInstallationToken)" + ${{ if or(eq(parameters.UseGitHubAppAuthentication, false), ne(variables['System.TeamProject'], 'internal')) }}: + gitHubPatVariable: "${{ parameters.GithubPat }}" ${{ if ne(parameters.MirrorRepo, '') }}: isMirrorRepoSelected: true gitHubOrganization: ${{ parameters.GitHubOrg }} diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml index 98329da4588..718b7f0a0ac 100644 --- a/eng/common/core-templates/job/publish-build-assets.yml +++ b/eng/common/core-templates/job/publish-build-assets.yml @@ -58,7 +58,6 @@ jobs: parameters: is1ESPipeline: ${{ parameters.is1ESPipeline }} - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: AzureDevOps-Artifact-Feeds-Pats - name: runCodesignValidationInjection value: false # unconditional - needed for logs publishing (redactor tool version) diff --git a/eng/common/core-templates/steps/get-github-app-token.yml b/eng/common/core-templates/steps/get-github-app-token.yml new file mode 100644 index 00000000000..6d42a48d3c3 --- /dev/null +++ b/eng/common/core-templates/steps/get-github-app-token.yml @@ -0,0 +1,79 @@ +# Mints a short-lived GitHub App installation access token by signing a JWT +# with a private key stored in Azure Key Vault (RSA, RS256). The JWT is +# exchanged with the GitHub API for a token scoped to a single installation. +# +# Requirements (per GitHub App you want to authenticate as): +# - A GitHub App with its private key uploaded into Key Vault as an RSA key +# (PEM converted to a key, NOT stored as a secret). +# - The Azure service connection passed via `azureSubscription` must be +# granted the `Key Vault Crypto User` role (or at minimum `Sign` action) +# on that key. +# - The App must be installed on the target organization/account +# (`installationOwner`) with the permissions/repositories you need. +# +# Output: a secret pipeline variable named ${{ parameters.outputVariableName }} +# containing the installation access token. Token lifetime is ~1 hour and is +# automatically scrubbed from logs. Installation tokens are exempt from the +# enterprise classic-PAT lifetime policy. + +parameters: +# Azure DevOps service connection (federated) that can call +# `az keyvault key sign` on the App's signing key. +- name: azureSubscription + type: string + +# Name of the Key Vault that holds the GitHub App's RSA signing key. +- name: keyVaultName + type: string + +# Name of the RSA key inside the Key Vault (the App's private key). +- name: keyName + type: string + +# The GitHub App's Client ID (the value to put in the `iss` JWT claim). +# Prefer this over the numeric App ID; GitHub accepts either, but Client ID +# is the documented form going forward. +- name: appClientId + type: string + +# Login of the organization or user account whose installation we should +# mint the token for (e.g. `dotnet`, `microsoft`). +- name: installationOwner + type: string + +# Name of the pipeline variable that will receive the installation token. +- name: outputVariableName + type: string + +- name: is1ESPipeline + type: boolean + +- name: stepName + type: string + default: getGitHubAppInstallationToken + +- name: condition + type: string + default: '' + +- name: displayName + type: string + default: Get GitHub App installation token + +steps: +- task: AzureCLI@2 + displayName: ${{ parameters.displayName }} + name: ${{ parameters.stepName }} + ${{ if ne(parameters.condition, '') }}: + condition: ${{ parameters.condition }} + inputs: + azureSubscription: ${{ parameters.azureSubscription }} + scriptType: pscore + scriptLocation: inlineScript + inlineScript: | + & "$(System.DefaultWorkingDirectory)/eng/common/Get-GitHubAppToken.ps1" ` + -KeyVaultName '${{ parameters.keyVaultName }}' ` + -KeyName '${{ parameters.keyName }}' ` + -AppClientId '${{ parameters.appClientId }}' ` + -InstallationOwner '${{ parameters.installationOwner }}' ` + -OutputVariableName '${{ parameters.outputVariableName }}' diff --git a/eng/common/templates-official/steps/get-github-app-token.yml b/eng/common/templates-official/steps/get-github-app-token.yml new file mode 100644 index 00000000000..c89f3641a4d --- /dev/null +++ b/eng/common/templates-official/steps/get-github-app-token.yml @@ -0,0 +1,7 @@ +steps: +- template: /eng/common/core-templates/steps/get-github-app-token.yml + parameters: + is1ESPipeline: true + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/get-github-app-token.yml b/eng/common/templates/steps/get-github-app-token.yml new file mode 100644 index 00000000000..79e182c6416 --- /dev/null +++ b/eng/common/templates/steps/get-github-app-token.yml @@ -0,0 +1,7 @@ +steps: +- template: /eng/common/core-templates/steps/get-github-app-token.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/global.json b/global.json index 8202122a37f..c4531f3f4b4 100644 --- a/global.json +++ b/global.json @@ -22,7 +22,7 @@ "perl": "5.38.2.2" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26405.5", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26406.9", "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2" } } From cfc9af74cc72a89a3413d793e44c454890e8cce3 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 11 Aug 2026 02:05:25 +0000 Subject: [PATCH 4/9] Update dependencies from https://github.com/dotnet/arcade build 20260810.1 On relative base path root Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26379.2 -> To Version 10.0.0-beta.26410.1 --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 4 ++-- global.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index d80cd377563..b027ad73945 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -6,7 +6,7 @@ This file should be imported by eng/Versions.props - 10.0.0-beta.26406.9 + 10.0.0-beta.26410.1 18.0.2 18.0.2 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3199c7b52f4..6dfb23eba4d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -80,9 +80,9 @@ - + https://github.com/dotnet/arcade - af57946065838fca9b1745ab055d5a15a4783fba + f0580c1beaa25ecdb341ad8396df48acf433fbec https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/global.json b/global.json index c4531f3f4b4..7b623d60e0a 100644 --- a/global.json +++ b/global.json @@ -22,7 +22,7 @@ "perl": "5.38.2.2" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26406.9", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26410.1", "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2" } } From 2523b1c309de53a4a0e058542cc4f223f1501a5d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 12 Aug 2026 02:05:46 +0000 Subject: [PATCH 5/9] Update dependencies from https://github.com/dotnet/arcade build 20260811.3 On relative base path root Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26379.2 -> To Version 10.0.0-beta.26411.3 --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 4 ++-- eng/common/Get-GitHubAppToken.ps1 | 18 ++++++++++++++---- global.json | 2 +- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index b027ad73945..be1f92cdd0a 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -6,7 +6,7 @@ This file should be imported by eng/Versions.props - 10.0.0-beta.26410.1 + 10.0.0-beta.26411.3 18.0.2 18.0.2 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6dfb23eba4d..2142bac8e11 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -80,9 +80,9 @@ - + https://github.com/dotnet/arcade - f0580c1beaa25ecdb341ad8396df48acf433fbec + 6a3a6bdbe2195bb7420b24a3d76e1fd66d7bbc35 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/common/Get-GitHubAppToken.ps1 b/eng/common/Get-GitHubAppToken.ps1 index 6b5899d7a29..9c7e3dcd6ac 100644 --- a/eng/common/Get-GitHubAppToken.ps1 +++ b/eng/common/Get-GitHubAppToken.ps1 @@ -113,10 +113,13 @@ try { $installations = @() $page = 1 do { - $pageInstallations = @(Invoke-RestMethod ` + # Assign the response before wrapping it in @(). PowerShell otherwise + # preserves a top-level JSON array as one nested pipeline object. + $pageResponse = Invoke-RestMethod ` -Uri "https://api.github.com/app/installations?per_page=100&page=$page" ` -Headers $headers ` - -Method Get) + -Method Get + $pageInstallations = @($pageResponse) $installations += $pageInstallations $page++ } while ($pageInstallations.Count -eq 100) @@ -125,12 +128,19 @@ catch { Write-PipelineTelemetryError -Category 'Build' -Message "Failed to list GitHub App installations: $_. The signed JWT may be invalid or the App's Client ID ('$AppClientId') may be incorrect." exit 1 } -$installation = $installations | Where-Object { $_.account.login -ieq $InstallationOwner } | Select-Object -First 1 -if (-not $installation) { +$matchingInstallations = @($installations | Where-Object { $_.account.login -ieq $InstallationOwner }) +if ($matchingInstallations.Count -eq 0) { $found = ($installations | ForEach-Object { $_.account.login }) -join ', ' Write-PipelineTelemetryError -Category 'Build' -Message "No installation found for '$InstallationOwner'. App is installed on: $found" exit 1 } +if ($matchingInstallations.Count -ne 1) { + $matchingIds = ($matchingInstallations | ForEach-Object { $_.id }) -join ', ' + Write-PipelineTelemetryError -Category 'Build' -Message "Found multiple installations for '$InstallationOwner': $matchingIds" + exit 1 +} +$installation = $matchingInstallations[0] +Write-Host "Using installation $($installation.id) for '$($installation.account.login)'." try { $tokenResponse = Invoke-RestMethod ` diff --git a/global.json b/global.json index 7b623d60e0a..736140f42e0 100644 --- a/global.json +++ b/global.json @@ -22,7 +22,7 @@ "perl": "5.38.2.2" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26410.1", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26411.3", "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2" } } From 24b18f8d704aa754e5c78d95f5b72ef7b037e277 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 13 Aug 2026 02:03:55 +0000 Subject: [PATCH 6/9] Update dependencies from https://github.com/dotnet/arcade build 20260812.3 On relative base path root Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26379.2 -> To Version 10.0.0-beta.26412.3 --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 4 ++-- eng/common/build.ps1 | 2 ++ eng/common/build.sh | 6 ++++++ eng/common/tools.ps1 | 8 ++++++++ eng/common/tools.sh | 10 +++++++++- global.json | 2 +- 7 files changed, 29 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index be1f92cdd0a..36d28bd217d 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -6,7 +6,7 @@ This file should be imported by eng/Versions.props - 10.0.0-beta.26411.3 + 10.0.0-beta.26412.3 18.0.2 18.0.2 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2142bac8e11..ecf743f188b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -80,9 +80,9 @@ - + https://github.com/dotnet/arcade - 6a3a6bdbe2195bb7420b24a3d76e1fd66d7bbc35 + cc913986bd49ba62a2606fe232f79cd5d5294f19 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/common/build.ps1 b/eng/common/build.ps1 index 8cfee107e7a..18397a60eb8 100644 --- a/eng/common/build.ps1 +++ b/eng/common/build.ps1 @@ -6,6 +6,7 @@ Param( [string][Alias('v')]$verbosity = "minimal", [string] $msbuildEngine = $null, [bool] $warnAsError = $true, + [string] $warnNotAsError = '', [bool] $nodeReuse = $true, [switch] $buildCheck = $false, [switch][Alias('r')]$restore, @@ -70,6 +71,7 @@ function Print-Usage() { Write-Host " -excludeCIBinarylog Don't output binary log (short: -nobl)" Write-Host " -prepareMachine Prepare machine for CI run, clean up processes after build" Write-Host " -warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" + Write-Host " -warnNotAsError Sets a semi-colon delimited list of warning codes that should not be treated as errors" Write-Host " -msbuildEngine Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)." Write-Host " -excludePrereleaseVS Set to exclude build engines in prerelease versions of Visual Studio" Write-Host " -nativeToolsOnMachine Sets the native tools on machine environment variable (indicating that the script should use native tools on machine)" diff --git a/eng/common/build.sh b/eng/common/build.sh index 9767bb411a4..c8bea7cbc2d 100755 --- a/eng/common/build.sh +++ b/eng/common/build.sh @@ -42,6 +42,7 @@ usage() echo " --prepareMachine Prepare machine for CI run, clean up processes after build" echo " --nodeReuse Sets nodereuse msbuild parameter ('true' or 'false')" echo " --warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" + echo " --warnNotAsError Sets a semi-colon delimited list of warning codes that should not be treated as errors" echo " --buildCheck Sets /check msbuild parameter" echo " --fromVMR Set when building from within the VMR" echo "" @@ -78,6 +79,7 @@ ci=false clean=false warn_as_error=true +warn_not_as_error='' node_reuse=true build_check=false binary_log=false @@ -176,6 +178,10 @@ while [[ $# > 0 ]]; do warn_as_error=$2 shift ;; + -warnnotaserror) + warn_not_as_error=$2 + shift + ;; -nodereuse) node_reuse=$2 shift diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index c6a1d6eaec4..bde220ad85b 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -34,6 +34,9 @@ # Configures warning treatment in msbuild. [bool]$warnAsError = if (Test-Path variable:warnAsError) { $warnAsError } else { $true } +# Specifies semi-colon delimited list of warning codes that should not be treated as errors. +[string]$warnNotAsError = if (Test-Path variable:warnNotAsError) { $warnNotAsError } else { '' } + # Specifies which msbuild engine to use for build: 'vs', 'dotnet' or unspecified (determined based on presence of tools.vs in global.json). [string]$msbuildEngine = if (Test-Path variable:msbuildEngine) { $msbuildEngine } else { $null } @@ -836,6 +839,11 @@ function MSBuild-Core() { $cmdArgs += ' /p:TreatWarningsAsErrors=false' } + if ($warnAsError -and $warnNotAsError) { + $escapedWarnNotAsError = $warnNotAsError -replace ';', '%3B' + $cmdArgs += " /warnnotaserror:$warnNotAsError /p:AdditionalWarningsNotAsErrors=$escapedWarnNotAsError" + } + foreach ($arg in $args) { if ($null -ne $arg -and $arg.Trim() -ne "") { if ($arg.EndsWith('\')) { diff --git a/eng/common/tools.sh b/eng/common/tools.sh index 62aeb73fe51..df76f062a76 100755 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -52,6 +52,9 @@ fi # Configures warning treatment in msbuild. warn_as_error=${warn_as_error:-true} +# Specifies semi-colon delimited list of warning codes that should not be treated as errors. +warn_not_as_error=${warn_not_as_error:-''} + # True to attempt using .NET Core already that meets requirements specified in global.json # installed on the machine instead of downloading one. use_installed_dotnet_cli=${use_installed_dotnet_cli:-true} @@ -532,7 +535,12 @@ function MSBuild-Core { mt_switch="-mt" fi - RunBuildTool "$_InitializeBuildToolCommand" /m /nologo /clp:Summary /v:$verbosity /nr:$node_reuse $warnaserror_switch $mt_switch /p:TreatWarningsAsErrors=$warn_as_error /p:ContinuousIntegrationBuild=$ci "$@" + local warnnotaserror_switch="" + if [[ -n "$warn_not_as_error" && "$warn_as_error" == true ]]; then + warnnotaserror_switch="/warnnotaserror:$warn_not_as_error /p:AdditionalWarningsNotAsErrors=${warn_not_as_error//;/%3B}" + fi + + RunBuildTool "$_InitializeBuildToolCommand" /m /nologo /clp:Summary /v:$verbosity /nr:$node_reuse $warnaserror_switch $mt_switch $warnnotaserror_switch /p:TreatWarningsAsErrors=$warn_as_error /p:ContinuousIntegrationBuild=$ci "$@" } function GetDarc { diff --git a/global.json b/global.json index 736140f42e0..100956f42b1 100644 --- a/global.json +++ b/global.json @@ -22,7 +22,7 @@ "perl": "5.38.2.2" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26411.3", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26412.3", "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2" } } From df81e488628ae059eacfdc297cd2f321976c1b7d Mon Sep 17 00:00:00 2001 From: Copilot Date: Thu, 13 Aug 2026 17:53:59 +0200 Subject: [PATCH 7/9] Suppress MessagePack GHSA-4qm4-8hg2-g2xm NuGet audit advisory The arcade dependency update surfaced NU1902 for MessagePack 2.5.108 (GHSA-4qm4-8hg2-g2xm), which flows transitively via Microsoft.CommonLanguageServerProtocol.Framework. NuGet audit warnings are treated as errors in CI, failing all Windows build/test jobs. Add the advisory to the existing NuGetAuditSuppress list; the package does not ship in FSharp.Core or the compiler. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Directory.Build.props | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index c4097099466..6488ea2053e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -108,7 +108,8 @@ - + + From d597d969321bcbe523bd1178a4fce3a32f02997c Mon Sep 17 00:00:00 2001 From: Copilot Date: Fri, 14 Aug 2026 15:21:57 +0200 Subject: [PATCH 8/9] Update dependencies from https://github.com/dotnet/arcade build 20260813.3 Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26412.3 -> To Version 10.0.0-beta.26413.3 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 4 ++-- global.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 36d28bd217d..9b8790940cc 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -6,7 +6,7 @@ This file should be imported by eng/Versions.props - 10.0.0-beta.26412.3 + 10.0.0-beta.26413.3 18.0.2 18.0.2 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ecf743f188b..c539a48b8e1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -80,9 +80,9 @@ - + https://github.com/dotnet/arcade - cc913986bd49ba62a2606fe232f79cd5d5294f19 + 774a363a5c4a34b2795ff0814b0d508a9e94c60f https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/global.json b/global.json index 100956f42b1..fffa86eae2b 100644 --- a/global.json +++ b/global.json @@ -22,7 +22,7 @@ "perl": "5.38.2.2" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26412.3", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26413.3", "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2" } } From 58693931a21733bda53d64a92b242b3891fde1db Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 15 Aug 2026 02:02:36 +0000 Subject: [PATCH 9/9] Update dependencies from https://github.com/dotnet/arcade build 20260814.3 On relative base path root Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26379.2 -> To Version 10.0.0-beta.26414.3 --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 4 ++-- global.json | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 9b8790940cc..c3becbd0e92 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -6,7 +6,7 @@ This file should be imported by eng/Versions.props - 10.0.0-beta.26413.3 + 10.0.0-beta.26414.3 18.0.2 18.0.2 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c539a48b8e1..889758acb0d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -80,9 +80,9 @@ - + https://github.com/dotnet/arcade - 774a363a5c4a34b2795ff0814b0d508a9e94c60f + caa49f7726ab75f513f2fb814030657cf1afc0e4 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/global.json b/global.json index fffa86eae2b..0cfc79e34ef 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.110", + "version": "10.0.111", "allowPrerelease": true, "paths": [ ".dotnet", @@ -9,7 +9,7 @@ "errorMessage": "The .NET SDK could not be found, please run ./eng/common/dotnet.sh." }, "tools": { - "dotnet": "10.0.110", + "dotnet": "10.0.111", "vs": { "version": "17.8", "components": [ @@ -22,7 +22,7 @@ "perl": "5.38.2.2" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26413.3", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26414.3", "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2" } }