From 1a2584d75e87e1d7bb16ec7e97b0df32e6074d37 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 15 Aug 2026 02:08:56 +0000 Subject: [PATCH 01/13] Update dependencies from build 327141 Updated Dependencies: Microsoft.DotNet.Arcade.Sdk (Version 10.0.0-beta.26412.103 -> 10.0.0-beta.26413.116) [[ commit created by automation ]] --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 6 +++--- eng/common/Get-GitHubAppToken.ps1 | 18 ++++++++++++++---- global.json | 2 +- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 60b2f2d0f9..eca7ee613f 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.103 + 10.0.0-beta.26413.116 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d507facdd3..1ec9f63a98 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + - + https://github.com/dotnet/dotnet - 493580a515a01970cfe1da2c7dd589efbaf36996 + 5549d455e17cefdd7e202cb31fce756a0847efc9 diff --git a/eng/common/Get-GitHubAppToken.ps1 b/eng/common/Get-GitHubAppToken.ps1 index 6b5899d7a2..9c7e3dcd6a 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 4f97a64339..bcf20b0564 100644 --- a/global.json +++ b/global.json @@ -8,7 +8,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26412.103" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26413.116" }, "sdk": { "version": "10.0.111" From 95ffe7c42c98efe374ec4defcc4f42e92a4846cc Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 16 Aug 2026 02:06:42 +0000 Subject: [PATCH 02/13] Update dependencies from build 327247 Updated Dependencies: Microsoft.DotNet.Arcade.Sdk (Version 10.0.0-beta.26413.116 -> 10.0.0-beta.26414.116) [[ commit created by automation ]] --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 6 +++--- global.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index eca7ee613f..a4a106dc15 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.116 + 10.0.0-beta.26414.116 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1ec9f63a98..0db2d733cc 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + - + https://github.com/dotnet/dotnet - 5549d455e17cefdd7e202cb31fce756a0847efc9 + 8e461aa6b46dbd52a5ec7533d8f4523454197a25 diff --git a/global.json b/global.json index bcf20b0564..2a7c099042 100644 --- a/global.json +++ b/global.json @@ -8,7 +8,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26413.116" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26414.116" }, "sdk": { "version": "10.0.111" From 684eca49f146259457dfe3dae712422d3f055824 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 18 Aug 2026 02:09:07 +0000 Subject: [PATCH 03/13] Update dependencies from build 327431 Updated Dependencies: Microsoft.DotNet.Arcade.Sdk (Version 10.0.0-beta.26414.116 -> 10.0.0-beta.26417.106) [[ commit created by automation ]] --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 6 +++--- global.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index a4a106dc15..d2927c0a41 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.26414.116 + 10.0.0-beta.26417.106 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0db2d733cc..b6d1969995 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + - + https://github.com/dotnet/dotnet - 8e461aa6b46dbd52a5ec7533d8f4523454197a25 + 07280ccb1b0a3e0affb64ce3d07abe9eda48ed19 diff --git a/global.json b/global.json index 2a7c099042..4b1aea23d5 100644 --- a/global.json +++ b/global.json @@ -8,7 +8,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26414.116" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26417.106" }, "sdk": { "version": "10.0.111" From 3ee16a395f5dc6dc0bddb0f2e8eb663a9255b283 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 19 Aug 2026 02:09:04 +0000 Subject: [PATCH 04/13] Update dependencies from build 327605 Updated Dependencies: Microsoft.DotNet.Arcade.Sdk (Version 10.0.0-beta.26417.106 -> 10.0.0-beta.26418.103) [[ commit created by automation ]] --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 6 +++--- global.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index d2927c0a41..04ddb8791c 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.26417.106 + 10.0.0-beta.26418.103 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b6d1969995..da3bc65552 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + - + https://github.com/dotnet/dotnet - 07280ccb1b0a3e0affb64ce3d07abe9eda48ed19 + d247057ae32ae36e14905eb8e776304a84433554 diff --git a/global.json b/global.json index 4b1aea23d5..04cd36a173 100644 --- a/global.json +++ b/global.json @@ -8,7 +8,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26417.106" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26418.103" }, "sdk": { "version": "10.0.111" From 3ce9b108d460da4911ee192895fb6a8b2ffe0fbe Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 26 Aug 2026 02:11:13 +0000 Subject: [PATCH 05/13] Update dependencies from build 328477 Updated Dependencies: Microsoft.DotNet.Arcade.Sdk (Version 10.0.0-beta.26418.103 -> 10.0.0-beta.26424.122) [[ commit created by automation ]] --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 6 ++--- eng/common/core-templates/job/onelocbuild.yml | 22 +++++++++++-------- global.json | 2 +- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 04ddb8791c..14d7ceda33 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.26418.103 + 10.0.0-beta.26424.122 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index da3bc65552..309dd6f3b6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + - + https://github.com/dotnet/dotnet - d247057ae32ae36e14905eb8e776304a84433554 + a6cb35bfde81c73e25feba2fe3d2a39c3fe118fd diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml index b28af6613c..726c2c1daf 100644 --- a/eng/common/core-templates/job/onelocbuild.yml +++ b/eng/common/core-templates/job/onelocbuild.yml @@ -14,10 +14,11 @@ 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. + # GitHub App authentication for the OneLoc check-in PR. + # dnceng/internal and DevDiv/DevDiv are enabled by default with their project-scoped service + # connections. Other projects must explicitly opt in after provisioning equivalent infrastructure. UseGitHubAppAuthentication: true + UseGitHubAppAuthenticationInOtherProjects: false GitHubAppServiceConnection: 'dnceng-oneloc-githubapp' GitHubAppClientId: 'Iv23lijBU8x3gc9lDOc9' GitHubAppKeyVaultName: 'EngKeyVault' @@ -97,13 +98,16 @@ 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')) }}: + # Mint a short-lived GitHub App installation token for the loc check-in PR. Use the connection + # provisioned in each supported project; other projects must explicitly opt in and override it. + - ${{ if and(eq(parameters.RepoType, 'gitHub'), eq(parameters.UseGitHubAppAuthentication, true), or(eq(variables['System.TeamProject'], 'internal'), eq(variables['System.TeamProject'], 'DevDiv'), eq(parameters.UseGitHubAppAuthenticationInOtherProjects, true))) }}: - template: /eng/common/core-templates/steps/get-github-app-token.yml parameters: is1ESPipeline: ${{ parameters.is1ESPipeline }} - azureSubscription: ${{ parameters.GitHubAppServiceConnection }} + ${{ if and(eq(variables['System.TeamProject'], 'DevDiv'), eq(parameters.GitHubAppServiceConnection, 'dnceng-oneloc-githubapp')) }}: + azureSubscription: 'devdiv-oneloc-githubapp' + ${{ else }}: + azureSubscription: ${{ parameters.GitHubAppServiceConnection }} keyVaultName: ${{ parameters.GitHubAppKeyVaultName }} keyName: ${{ parameters.GitHubAppKeyName }} appClientId: ${{ parameters.GitHubAppClientId }} @@ -132,9 +136,9 @@ jobs: patVariable: ${{ parameters.CeapexPat }} ${{ if eq(parameters.RepoType, 'gitHub') }}: repoType: ${{ parameters.RepoType }} - ${{ if and(eq(parameters.UseGitHubAppAuthentication, true), eq(variables['System.TeamProject'], 'internal')) }}: + ${{ if and(eq(parameters.UseGitHubAppAuthentication, true), or(eq(variables['System.TeamProject'], 'internal'), eq(variables['System.TeamProject'], 'DevDiv'), eq(parameters.UseGitHubAppAuthenticationInOtherProjects, true))) }}: gitHubPatVariable: "$(GitHubAppInstallationToken)" - ${{ if or(eq(parameters.UseGitHubAppAuthentication, false), ne(variables['System.TeamProject'], 'internal')) }}: + ${{ else }}: gitHubPatVariable: "${{ parameters.GithubPat }}" ${{ if ne(parameters.MirrorRepo, '') }}: isMirrorRepoSelected: true diff --git a/global.json b/global.json index 04cd36a173..4d6c6b6138 100644 --- a/global.json +++ b/global.json @@ -8,7 +8,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26418.103" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26424.122" }, "sdk": { "version": "10.0.111" From 66a77e916a049533ecc9f24c899453c33cd7db07 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 27 Aug 2026 02:11:26 +0000 Subject: [PATCH 06/13] Backflow from https://github.com/dotnet/dotnet / 31d4a0a build 328846 Diff: https://github.com/dotnet/dotnet/compare/a6cb35bfde81c73e25feba2fe3d2a39c3fe118fd..31d4a0a8497049bf6485dd830c8a9112c1557a99 From: https://github.com/dotnet/dotnet/commit/a6cb35bfde81c73e25feba2fe3d2a39c3fe118fd To: https://github.com/dotnet/dotnet/commit/31d4a0a8497049bf6485dd830c8a9112c1557a99 [[ commit created by automation ]] --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 56dda1e7d3..2dd7aafb17 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -4,7 +4,7 @@ - 2.0.12 + 2.0.13 servicing From 9d808f506835b13674bd6e408cfe92fd37e2bbbd Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 27 Aug 2026 02:11:26 +0000 Subject: [PATCH 07/13] Update dependencies from build 328846 Updated Dependencies: Microsoft.DotNet.Arcade.Sdk (Version 10.0.0-beta.26424.122 -> 10.0.0-beta.26426.108) [[ commit created by automation ]] --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 6 +++--- global.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 14d7ceda33..a8f9d43ef3 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.26424.122 + 10.0.0-beta.26426.108 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 309dd6f3b6..4aa0a11a4b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + - + https://github.com/dotnet/dotnet - a6cb35bfde81c73e25feba2fe3d2a39c3fe118fd + 31d4a0a8497049bf6485dd830c8a9112c1557a99 diff --git a/global.json b/global.json index 4d6c6b6138..ab6ce89c07 100644 --- a/global.json +++ b/global.json @@ -8,7 +8,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26424.122" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26426.108" }, "sdk": { "version": "10.0.111" From 17160397e2f77bb1a590867f509f8dfdf5abc8bb Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 28 Aug 2026 02:10:55 +0000 Subject: [PATCH 08/13] Update dependencies from build 328888 Updated Dependencies: Microsoft.DotNet.Arcade.Sdk (Version 10.0.0-beta.26426.108 -> 10.0.0-beta.26426.122) [[ commit created by automation ]] --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 6 +++--- global.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index a8f9d43ef3..62fdae7eea 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.26426.108 + 10.0.0-beta.26426.122 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4aa0a11a4b..9b5c6794eb 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + - + https://github.com/dotnet/dotnet - 31d4a0a8497049bf6485dd830c8a9112c1557a99 + c7ac883e69867495da925d6c0757b1662241fe1e diff --git a/global.json b/global.json index ab6ce89c07..442d682121 100644 --- a/global.json +++ b/global.json @@ -8,7 +8,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26426.108" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26426.122" }, "sdk": { "version": "10.0.111" From c7012744784ba86bae1059d49bac01ad1ad7cc15 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 29 Aug 2026 02:10:09 +0000 Subject: [PATCH 09/13] Update dependencies from build 329108 Updated Dependencies: Microsoft.DotNet.Arcade.Sdk (Version 10.0.0-beta.26426.122 -> 10.0.0-beta.26427.124) [[ commit created by automation ]] --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 6 +++--- eng/common/core-templates/job/onelocbuild.yml | 14 ++++++-------- global.json | 2 +- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 62fdae7eea..74ff489d59 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.26426.122 + 10.0.0-beta.26427.124 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9b5c6794eb..39dbb0f426 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + - + https://github.com/dotnet/dotnet - c7ac883e69867495da925d6c0757b1662241fe1e + 2c07be8ab38eb69e43aedf74ed288079c839b1dc diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml index 726c2c1daf..15d8c1571e 100644 --- a/eng/common/core-templates/job/onelocbuild.yml +++ b/eng/common/core-templates/job/onelocbuild.yml @@ -9,9 +9,8 @@ parameters: GithubPat: $(BotAccount-dotnet-bot-repo-PAT) # Service connection for WIF-based Entra authentication to ceapex feeds (replaces CeapexPat). - # When set, dnceng/internal builds acquire a federated Entra token instead of using a PAT. - # All other projects (e.g. DevDiv, public), where this dnceng-scoped service connection does not - # exist, and any pipeline that sets this to '' fall back to PAT-based auth via the CeapexPat parameter. + # The `internal` and `DevDiv` System.TeamProject values have same-named, project-scoped + # connections. Other values, and any pipeline that sets this to '', use the CeapexPat parameter. CeapexServiceConnection: 'dnceng-onelocbuild-ceapex' # GitHub App authentication for the OneLoc check-in PR. @@ -89,9 +88,8 @@ jobs: displayName: Generate LocProject.json condition: ${{ parameters.condition }} - # Acquire an Entra token for ceapex feed access via WIF (dnceng/internal only). - # All other projects use PAT-based auth, since the ceapex service connection is scoped to dnceng/internal. - - ${{ if and(ne(parameters.CeapexServiceConnection, ''), eq(variables['System.TeamProject'], 'internal')) }}: + # Acquire an Entra token when System.TeamProject is `internal` or `DevDiv`. + - ${{ if and(ne(parameters.CeapexServiceConnection, ''), or(eq(variables['System.TeamProject'], 'internal'), eq(variables['System.TeamProject'], 'DevDiv'))) }}: - template: /eng/common/templates/steps/get-federated-access-token.yml parameters: federatedServiceConnection: ${{ parameters.CeapexServiceConnection }} @@ -130,9 +128,9 @@ jobs: isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }} isShouldReusePrSelected: ${{ parameters.ReusePr }} packageSourceAuth: patAuth - ${{ if and(ne(parameters.CeapexServiceConnection, ''), eq(variables['System.TeamProject'], 'internal')) }}: + ${{ if and(ne(parameters.CeapexServiceConnection, ''), or(eq(variables['System.TeamProject'], 'internal'), eq(variables['System.TeamProject'], 'DevDiv'))) }}: patVariable: $(CeapexEntraToken) - ${{ if or(eq(parameters.CeapexServiceConnection, ''), ne(variables['System.TeamProject'], 'internal')) }}: + ${{ if or(eq(parameters.CeapexServiceConnection, ''), and(ne(variables['System.TeamProject'], 'internal'), ne(variables['System.TeamProject'], 'DevDiv'))) }}: patVariable: ${{ parameters.CeapexPat }} ${{ if eq(parameters.RepoType, 'gitHub') }}: repoType: ${{ parameters.RepoType }} diff --git a/global.json b/global.json index 442d682121..5c38bebf66 100644 --- a/global.json +++ b/global.json @@ -8,7 +8,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26426.122" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26427.124" }, "sdk": { "version": "10.0.111" From 745b315d92216b7e8087994d6eaac4ad4c3b3262 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 30 Aug 2026 02:08:51 +0000 Subject: [PATCH 10/13] Update dependencies from build 329279 Updated Dependencies: Microsoft.DotNet.Arcade.Sdk (Version 10.0.0-beta.26427.124 -> 10.0.0-beta.26428.112) [[ commit created by automation ]] --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 6 +++--- global.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 74ff489d59..8aa7dc23c0 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.26427.124 + 10.0.0-beta.26428.112 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 39dbb0f426..3c505e6fa7 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + - + https://github.com/dotnet/dotnet - 2c07be8ab38eb69e43aedf74ed288079c839b1dc + f78a4ffdfd6f69ddf95ca6470dbda0d53681230b diff --git a/global.json b/global.json index 5c38bebf66..2f2a5a3041 100644 --- a/global.json +++ b/global.json @@ -8,7 +8,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26427.124" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26428.112" }, "sdk": { "version": "10.0.111" From de1ded63808295c8fd23f78b3f8936a1081c4e51 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 31 Aug 2026 02:07:12 +0000 Subject: [PATCH 11/13] Update dependencies from build 329385 Updated Dependencies: Microsoft.DotNet.Arcade.Sdk (Version 10.0.0-beta.26428.112 -> 10.0.0-beta.26430.102) [[ commit created by automation ]] --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 6 +++--- global.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 8aa7dc23c0..a1ff30abfb 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.26428.112 + 10.0.0-beta.26430.102 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3c505e6fa7..66d40e8a68 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + - + https://github.com/dotnet/dotnet - f78a4ffdfd6f69ddf95ca6470dbda0d53681230b + c88ed25bf20322afdd9f4f8aef07b86130dde405 diff --git a/global.json b/global.json index 2f2a5a3041..feb654d887 100644 --- a/global.json +++ b/global.json @@ -8,7 +8,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26428.112" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26430.102" }, "sdk": { "version": "10.0.111" From 887f04646893dcd44075ba0668b0ad6a51649737 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 1 Sep 2026 02:13:02 +0000 Subject: [PATCH 12/13] Update dependencies from build 329526 Updated Dependencies: Microsoft.DotNet.Arcade.Sdk (Version 10.0.0-beta.26430.102 -> 10.0.0-beta.26431.103) [[ commit created by automation ]] --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 6 +++--- global.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index a1ff30abfb..06e03fb118 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.26430.102 + 10.0.0-beta.26431.103 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 66d40e8a68..1706851e1e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + - + https://github.com/dotnet/dotnet - c88ed25bf20322afdd9f4f8aef07b86130dde405 + 8a3c072ade7b5b3c0393767d08d86d657621763e diff --git a/global.json b/global.json index feb654d887..25802755c0 100644 --- a/global.json +++ b/global.json @@ -8,7 +8,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26430.102" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26431.103" }, "sdk": { "version": "10.0.111" From 9571aa1dd44e7d3a1879fcb6fa18c5c28c359ca2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 2 Sep 2026 02:12:57 +0000 Subject: [PATCH 13/13] Update dependencies from build 329877 Updated Dependencies: Microsoft.DotNet.Arcade.Sdk (Version 10.0.0-beta.26431.103 -> 10.0.0-beta.26451.111) [[ commit created by automation ]] --- eng/Version.Details.props | 2 +- eng/Version.Details.xml | 6 +- eng/common/Get-GitHubAppToken.ps1 | 13 +- .../core-templates/job/helix-job-monitor.yml | 278 ++++++++++++++++++ .../core-templates/steps/send-to-helix.yml | 21 +- global.json | 2 +- 6 files changed, 309 insertions(+), 13 deletions(-) create mode 100644 eng/common/core-templates/job/helix-job-monitor.yml diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 06e03fb118..fc2c5aa906 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.26431.103 + 10.0.0-beta.26451.111 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1706851e1e..a94464698d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,12 +1,12 @@ - + - + https://github.com/dotnet/dotnet - 8a3c072ade7b5b3c0393767d08d86d657621763e + 79b5a5ed23976dc183df144fbaa6ff39ca5b9826 diff --git a/eng/common/Get-GitHubAppToken.ps1 b/eng/common/Get-GitHubAppToken.ps1 index 9c7e3dcd6a..ea776bd6bc 100644 --- a/eng/common/Get-GitHubAppToken.ps1 +++ b/eng/common/Get-GitHubAppToken.ps1 @@ -110,19 +110,20 @@ $headers = @{ Write-Host "Looking up installation for '$InstallationOwner'..." try { - $installations = @() + $installations = [System.Collections.Generic.List[object]]::new() $page = 1 do { - # 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 - $pageInstallations = @($pageResponse) - $installations += $pageInstallations + $pageInstallationCount = 0 + foreach ($installation in $pageResponse) { + $installations.Add($installation) + $pageInstallationCount++ + } $page++ - } while ($pageInstallations.Count -eq 100) + } while ($pageInstallationCount -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." diff --git a/eng/common/core-templates/job/helix-job-monitor.yml b/eng/common/core-templates/job/helix-job-monitor.yml new file mode 100644 index 0000000000..53bbf74927 --- /dev/null +++ b/eng/common/core-templates/job/helix-job-monitor.yml @@ -0,0 +1,278 @@ +parameters: +# Maximum run time of the monitor job in minutes. Also used for --max-wait-minutes. +- name: timeoutInMinutes + type: number + default: 360 + +# Owner segment of the source repository (e.g. 'dotnet' for 'dotnet/runtime') passed via --organization. +# Defaults to the owner segment of BUILD_REPOSITORY_NAME when empty. +- name: organization + type: string + default: '' + +# Name of the source repository (e.g. 'runtime' for 'dotnet/runtime') passed via --repository. +# Defaults to the repo segment of BUILD_REPOSITORY_NAME when empty. +- name: repository + type: string + default: '' + +# Optional dependency list for the generated job. +- name: dependsOn + type: object + default: [] + +# Optional condition for the generated job. +- name: condition + type: string + default: '' + +# Whether failures in the monitor job should allow the pipeline to continue. +- name: continueOnError + type: boolean + default: false + +# NuGet package id of the Helix job monitor tool. +- name: toolPackageId + type: string + default: Microsoft.DotNet.Helix.JobMonitor + +# Console command exposed by the installed tool package. +- name: toolCommand + type: string + default: dotnet-helix-job-monitor + +# Optional explicit tool version. Only honored when 'toolNupkgArtifactName' is set; in the +# default code path the version is taken from the consuming repo's .config/dotnet-tools.json. +- name: toolVersion + type: string + default: '' + +# Base URI for the Helix service (--helix-base-uri). +- name: helixBaseUri + type: string + default: https://helix.dot.net/ + +# Helix API access token forwarded to the tool via the HELIX_ACCESSTOKEN environment variable. +- name: helixAccessToken + type: string + default: '' + +# Polling interval in seconds (--polling-interval-seconds). +- name: pollingIntervalSeconds + type: number + default: 30 + +# Maximum number of work items whose results may be downloaded, parsed, and +# uploaded concurrently. +- name: testResultUploadParallelism + type: number + default: 48 + +# When 'true' (the default), Helix work items that exit 0 but have failed AzDO test results +# are treated as failed: they count toward the monitor's exit code and are resubmitted by a +# later invocation's retry pass. Set to 'false' to fall back to exit-code-only outcomes. +# Forwarded as --fail-on-failed-tests. +- name: failWorkItemsWithFailedTests + type: boolean + default: true + +# When true, allow the monitor to succeed when this stage produces no Helix jobs in any attempt. +# Forwarded as --allow-no-helix-jobs. +- name: allowNoHelixJobs + type: boolean + default: false + +# When true, test results are reported to Azure DevOps using the fully qualified test name +# (Namespace.Type.Method) as the stable automatedTestName and the visible title is qualified as +# well (--use-fully-qualified-test-name). Opt-in because it changes AzDO test identity and display; +# primarily useful for frameworks like MSTest whose display name is only the method name. +- name: useFullyQualifiedTestName + type: boolean + default: false + +# Controls per-test output attachments. Defaults to Failed. +- name: testResultAttachmentMode + type: string + default: Failed + values: + - Failed + - All + - None + +# Advanced: optional pipeline artifact (produced earlier in this run) that contains the tool +# nupkg. When set, the artifact is downloaded and the tool is installed from the nupkg into +# a local tool-path; this bypasses the repo's .config/dotnet-tools.json manifest and is +# primarily intended for the Arcade repository itself, where the Helix job monitor tool is +# built in the same pipeline that runs this template. +# +# When this parameter is empty (the default), the consuming repository must declare the tool +# in its .config/dotnet-tools.json manifest (alongside other local .NET tools); the template +# will check out the repo and run 'dotnet tool restore' to install the version pinned there. +- name: toolNupkgArtifactName + type: string + default: '' + +# Advanced: sub-path within the downloaded artifact where the tool nupkg is located. Defaults +# to the standard Arcade non-shipping packages location for a Release build (relative to the +# pipeline artifact root, which is itself the build's 'artifacts' directory). +- name: toolNupkgArtifactSubPath + type: string + default: 'packages/Release/NonShipping' + +jobs: +- job: HelixJobMonitor + displayName: Monitor Helix Jobs + timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + continueOnError: ${{ parameters.continueOnError }} + ${{ if ne(length(parameters.dependsOn), 0) }}: + dependsOn: ${{ parameters.dependsOn }} + ${{ if ne(parameters.condition, '') }}: + condition: ${{ parameters.condition }} + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $(DncEngPublicBuildPool) + os: linux + demands: ImageOverride -equals build.azurelinux.3.amd64.open + ${{ else }}: + name: $(DncEngInternalBuildPool) + os: linux + demands: ImageOverride -equals build.azurelinux.3.amd64 + steps: + - checkout: self + fetchDepth: 1 + + - ${{ if ne(parameters.toolNupkgArtifactName, '') }}: + - task: DownloadPipelineArtifact@2 + displayName: Download Helix Job Monitor artifact + inputs: + buildType: current + artifactName: ${{ parameters.toolNupkgArtifactName }} + itemPattern: '${{ parameters.toolNupkgArtifactSubPath }}/${{ parameters.toolPackageId }}.*.nupkg' + targetPath: $(Agent.TempDirectory)/helix-job-monitor-nupkg + + - bash: | + set -euo pipefail + + toolPath="$AGENT_TEMPDIRECTORY/helix-job-monitor-tool" + mkdir -p "$toolPath" + + packageId='${{ parameters.toolPackageId }}' + toolVersion='${{ parameters.toolVersion }}' + nupkgArtifactSubPath='${{ parameters.toolNupkgArtifactSubPath }}' + nupkgDir="$AGENT_TEMPDIRECTORY/helix-job-monitor-nupkg/$nupkgArtifactSubPath" + + if [ ! -d "$nupkgDir" ]; then + echo "Expected nupkg directory '$nupkgDir' was not produced by the artifact download." >&2 + exit 1 + fi + + nupkg=$(find "$nupkgDir" -maxdepth 1 -type f -name "$packageId.*.nupkg" | head -n 1) + if [ -z "$nupkg" ]; then + echo "No '$packageId.*.nupkg' found in '$nupkgDir'." >&2 + exit 1 + fi + + # Derive the version from the nupkg filename so the local package is selected + # deterministically instead of resolving against any other configured feed. + nupkgBase=$(basename "$nupkg" .nupkg) + derivedVersion="${nupkgBase#${packageId}.}" + if [ -z "$toolVersion" ]; then + toolVersion="$derivedVersion" + fi + + echo "Using locally built '$packageId' version '$toolVersion' from '$nupkgDir'." + + # Create a minimal NuGet.config that only references the local nupkg directory. + # This avoids conflicts with the repo's package source mapping which blocks --add-source. + toolNugetConfig="$AGENT_TEMPDIRECTORY/helix-job-monitor-nuget.config" + printf '\n\n \n \n \n \n\n' "$nupkgDir" > "$toolNugetConfig" + + pushd "$(Build.SourcesDirectory)" > /dev/null + ./eng/common/dotnet.sh tool install \ + --tool-path "$toolPath" "$packageId" \ + --version "$toolVersion" \ + --configfile "$toolNugetConfig" + + # Locate the tool DLL so the run step can invoke it via ./eng/common/dotnet.sh exec. + toolDll=$(find "$toolPath/.store" -path '*/tools/*/any/*.deps.json' -type f | head -n 1) + toolDll="${toolDll%.deps.json}.dll" + if [ ! -f "$toolDll" ]; then + echo "Could not find tool DLL in '$toolPath/.store'." >&2 + exit 1 + fi + + echo "Tool DLL: $toolDll" + echo "##vso[task.setvariable variable=HelixJobMonitorDll]$toolDll" + displayName: Install Helix Job Monitor + + - ${{ else }}: + - bash: ./eng/common/dotnet.sh tool restore + displayName: Restore Helix Job Monitor + + - bash: | + set -euo pipefail + + toolArgs=( + --helix-base-uri '${{ parameters.helixBaseUri }}' + --polling-interval-seconds '${{ parameters.pollingIntervalSeconds }}' + --fail-on-failed-tests '${{ parameters.failWorkItemsWithFailedTests }}' + --allow-no-helix-jobs '${{ parameters.allowNoHelixJobs }}' + --use-fully-qualified-test-name '${{ parameters.useFullyQualifiedTestName }}' + --max-wait-minutes "$((${{ parameters.timeoutInMinutes }} - 5))" # Set the tool's timeout slightly lower than the Azure DevOps job timeout to allow it to exit gracefully. + --stage-name '$(System.StageName)' + --stage-attempt '$(System.StageAttempt)' + --job-attempt '$(System.JobAttempt)' + --test-result-upload-parallelism '${{ parameters.testResultUploadParallelism }}' + ) + + organization='${{ parameters.organization }}' + repository='${{ parameters.repository }}' + testResultAttachmentMode='${{ parameters.testResultAttachmentMode }}' + + # Fall back to Azure DevOps-provided environment variables when the caller did not + # supply organization / repository explicitly. BUILD_REPOSITORY_NAME is typically + # 'owner/repo' for GitHub-backed builds and 'owner-repo' for internal builds. + if [ -z "$organization" ] || [ -z "$repository" ]; then + buildRepoName="${BUILD_REPOSITORY_NAME:-}" + if [ -n "$buildRepoName" ] && [[ "$buildRepoName" == */* ]]; then + repoOwner="${buildRepoName%%/*}" + repoName="${buildRepoName#*/}" + elif [ -n "$buildRepoName" ] && [[ "$buildRepoName" == *-* ]]; then + repoOwner="${buildRepoName%%-*}" + repoName="${buildRepoName#*-}" + fi + + if [ -n "${repoOwner:-}" ] && [ -n "${repoName:-}" ]; then + if [ -z "$organization" ]; then organization="$repoOwner"; fi + if [ -z "$repository" ]; then repository="$repoName"; fi + fi + fi + + if [ -n "$organization" ]; then toolArgs+=( --organization "$organization" ); fi + if [ -n "$repository" ]; then toolArgs+=( --repository "$repository" ); fi + if [ -n "$testResultAttachmentMode" ]; then + toolArgs+=( --test-result-attachment-mode "$testResultAttachmentMode" ) + fi + + # Build.Reason and Build.SourceBranch are required to derive the Helix source filter + # the same way the Helix SDK submitter does (PR -> 'pr', internal -> 'official', + # otherwise -> 'ci'). Without these, manually-queued / scheduled / CI builds would + # be looked up under the wrong source prefix and find zero jobs. + toolArgs+=( --build-reason "$(Build.Reason)" ) + toolArgs+=( --source-branch "$(Build.SourceBranch)" ) + + if [ -n '${{ parameters.toolNupkgArtifactName }}' ]; then + # Tool was installed from a local nupkg; run the DLL via the repo-local dotnet. + export DOTNET_ROOT="$(Build.SourcesDirectory)/.dotnet" + ./eng/common/dotnet.sh exec "$(HelixJobMonitorDll)" "${toolArgs[@]}" + else + # Tool was restored from the local .config/dotnet-tools.json manifest; invoke it + # through the manifest from the repo root. + pushd "$BUILD_SOURCESDIRECTORY" > /dev/null + trap 'popd > /dev/null' EXIT + ./eng/common/dotnet.sh tool run '${{ parameters.toolCommand }}' -- "${toolArgs[@]}" + fi + displayName: Monitor Helix Jobs + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + HELIX_ACCESSTOKEN: ${{ parameters.helixAccessToken }} diff --git a/eng/common/core-templates/steps/send-to-helix.yml b/eng/common/core-templates/steps/send-to-helix.yml index 68fa739c4a..37678b0389 100644 --- a/eng/common/core-templates/steps/send-to-helix.yml +++ b/eng/common/core-templates/steps/send-to-helix.yml @@ -10,6 +10,7 @@ parameters: HelixConfiguration: '' # optional -- additional property attached to a job HelixPreCommands: '' # optional -- commands to run before Helix work item execution HelixPostCommands: '' # optional -- commands to run after Helix work item execution + UseHelixMonitor: false # optional -- true will submit Helix jobs configured for the standalone Helix Job Monitor (results are reported/waited on out-of-band; this step will not wait, and WaitForWorkItemCompletion will be overridden) WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects @@ -31,7 +32,15 @@ parameters: continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false steps: - - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY/${{ parameters.HelixProjectPath }} /restore /p:TreatWarningsAsErrors=false ${{ parameters.HelixProjectArguments }} /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env:BuildConfig\SendToHelix.binlog"' + - powershell: > + $(Build.SourcesDirectory)\eng\common\msbuild.ps1 + $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }} + /restore + /p:TreatWarningsAsErrors=false + /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }} + ${{ parameters.HelixProjectArguments }} + /t:Test + /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog displayName: ${{ parameters.DisplayNamePrefix }} (Windows) env: BuildConfig: $(_BuildConfig) @@ -61,7 +70,15 @@ steps: SYSTEM_ACCESSTOKEN: $(System.AccessToken) condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) continueOnError: ${{ parameters.continueOnError }} - - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/${{ parameters.HelixProjectPath }} /restore /p:TreatWarningsAsErrors=false ${{ parameters.HelixProjectArguments }} /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog + - script: > + $(Build.SourcesDirectory)/eng/common/msbuild.sh + $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }} + /restore + /p:TreatWarningsAsErrors=false + /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }} + ${{ parameters.HelixProjectArguments }} + /t:Test + /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog displayName: ${{ parameters.DisplayNamePrefix }} (Unix) env: BuildConfig: $(_BuildConfig) diff --git a/global.json b/global.json index 25802755c0..fb13a3d1d7 100644 --- a/global.json +++ b/global.json @@ -8,7 +8,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26431.103" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26451.111" }, "sdk": { "version": "10.0.111"