From 17692b294d6285f7d4cce348aff0b0d2acfc82da Mon Sep 17 00:00:00 2001 From: Missy Messa Date: Mon, 31 Aug 2026 09:10:35 -0700 Subject: [PATCH 1/3] [release/8.0] Avoid downloading unused OneLoc PATs Import the legacy variable group only when the Ceapex or GitHub PAT fallback can be selected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bc4e1c74-f3b4-4965-932e-5e63cff7e877 --- eng/common/templates-official/job/onelocbuild.yml | 4 +++- eng/common/templates/job/onelocbuild.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/eng/common/templates-official/job/onelocbuild.yml b/eng/common/templates-official/job/onelocbuild.yml index 5840fe2fff8..8e82a870dea 100644 --- a/eng/common/templates-official/job/onelocbuild.yml +++ b/eng/common/templates-official/job/onelocbuild.yml @@ -48,7 +48,9 @@ jobs: displayName: OneLocBuild${{ parameters.JobNameSuffix }} variables: - - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat + # Attach legacy secrets only when either PAT fallback can be selected. + - ${{ if or(eq(parameters.CeapexServiceConnection, ''), and(ne(variables['System.TeamProject'], 'internal'), ne(variables['System.TeamProject'], 'DevDiv')), and(eq(parameters.RepoType, 'gitHub'), or(ne(parameters.UseGitHubAppAuthentication, true), and(ne(variables['System.TeamProject'], 'internal'), ne(variables['System.TeamProject'], 'DevDiv'), ne(parameters.UseGitHubAppAuthenticationInOtherProjects, true))))) }}: + - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat - name: _GenerateLocProjectArguments value: -SourcesDirectory ${{ parameters.SourcesDirectory }} -LanguageSet "${{ parameters.LanguageSet }}" diff --git a/eng/common/templates/job/onelocbuild.yml b/eng/common/templates/job/onelocbuild.yml index 1a8a07ca016..54aef43118f 100644 --- a/eng/common/templates/job/onelocbuild.yml +++ b/eng/common/templates/job/onelocbuild.yml @@ -48,7 +48,9 @@ jobs: displayName: OneLocBuild${{ parameters.JobNameSuffix }} variables: - - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat + # Attach legacy secrets only when either PAT fallback can be selected. + - ${{ if or(eq(parameters.CeapexServiceConnection, ''), and(ne(variables['System.TeamProject'], 'internal'), ne(variables['System.TeamProject'], 'DevDiv')), and(eq(parameters.RepoType, 'gitHub'), or(ne(parameters.UseGitHubAppAuthentication, true), and(ne(variables['System.TeamProject'], 'internal'), ne(variables['System.TeamProject'], 'DevDiv'), ne(parameters.UseGitHubAppAuthenticationInOtherProjects, true))))) }}: + - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat - name: _GenerateLocProjectArguments value: -SourcesDirectory ${{ parameters.SourcesDirectory }} -LanguageSet "${{ parameters.LanguageSet }}" From f5a228435cc6aa15d7e47d365097d76367c48370 Mon Sep 17 00:00:00 2001 From: Missy Messa Date: Thu, 3 Sep 2026 13:04:51 -0700 Subject: [PATCH 2/3] Remove OneLoc PAT fallback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Documentation/OneLocBuild.md | 11 ++--- .../templates-official/job/onelocbuild.yml | 47 +++++++------------ eng/common/templates/job/onelocbuild.yml | 47 +++++++------------ 3 files changed, 36 insertions(+), 69 deletions(-) diff --git a/Documentation/OneLocBuild.md b/Documentation/OneLocBuild.md index 139d7ecc592..09ecbc575a3 100644 --- a/Documentation/OneLocBuild.md +++ b/Documentation/OneLocBuild.md @@ -12,12 +12,11 @@ To make OneLocBuild easier to use, we have integrated the task into Arcade. This To see your repo's current loc configuration, please refer to https://aka.ms/locstats. For GitHub repositories built in `dnceng/internal` or `DevDiv/DevDiv`, the template uses a -short-lived GitHub App installation token for localization check-in by default. The target +short-lived GitHub App installation token for localization check-in. The target repository must be selected in the `dotnet OneLoc Localization` App installation, and the pipeline must be authorized for its project-scoped service connection: `dnceng-oneloc-githubapp` in `dnceng/internal` or `devdiv-oneloc-githubapp` in `DevDiv/DevDiv`. The App requires Contents and -Pull requests read/write permissions. Set `UseGitHubAppAuthentication: false` only as a temporary -opt-out to the PAT path. +Pull requests read/write permissions. ## Onboarding to OneLocBuild Using Arcade @@ -201,10 +200,8 @@ The parameters that can be passed to the template are as follows: | `LanguageSet` | `VS_Main_Languages` | This defines the `LanguageSet` of the LocProject.json as described in the [OneLocBuild task documentation](https://ceapex.visualstudio.com/CEINTL/_wiki/wikis/CEINTL.wiki/107/Localization-with-OneLocBuild-Task?anchor=languageset%2C-languages-(required)). | | `LclSource` | `LclFilesInRepo` | This passes the `LclSource` input to the OneLocBuild task as described in [its documentation](https://ceapex.visualstudio.com/CEINTL/_wiki/wikis/CEINTL.wiki/107/Localization-with-OneLocBuild-Task?anchor=languageset%2C-languages-(required)). For most repos, this should be set to `LclFilesfromPackage`. | | `LclPackageId` | `''` | When `LclSource` is set to `LclFilesfromPackage`, this passes in the package ID as described in the [OneLocBuild task documentation](https://ceapex.visualstudio.com/CEINTL/_wiki/wikis/CEINTL.wiki/107/Localization-with-OneLocBuild-Task?anchor=scenario-2%3A-lcl-files-from-a-package). | -| `CeapexServiceConnection` | `'dnceng-onelocbuild-ceapex'` | The project-scoped WIF service connection used to acquire a short-lived token for the Ceapex feeds. This path is enabled in `dnceng/internal` and `DevDiv/DevDiv`; other projects continue to use PAT-based authentication. Pipelines in either supported project must be authorized to use their project's connection. Set to `''` to explicitly use PAT-based authentication. | -| `UseGitHubAppAuthentication` | `true` | Use GitHub App authentication for the check-in PR in `dnceng/internal` and `DevDiv/DevDiv`. Set to `false` to select the PAT path. | -| `UseGitHubAppAuthenticationInOtherProjects` | `false` | Explicitly enable the App path outside `dnceng/internal` and `DevDiv/DevDiv` after provisioning equivalent infrastructure. | -| `GitHubAppServiceConnection` | `'dnceng-oneloc-githubapp'` | The WIF service connection used to sign the App JWT. Arcade remaps this default to `devdiv-oneloc-githubapp` in `DevDiv/DevDiv`; explicit overrides are preserved. | +| `CeapexServiceConnection` | `'dnceng-onelocbuild-ceapex'` | The project-scoped WIF service connection used to acquire a short-lived token for the Ceapex feeds. Pipelines must be authorized to use the connection. | +| `GitHubAppServiceConnection` | `'dnceng-oneloc-githubapp'` | The WIF service connection used to sign the App JWT. Arcade remaps this default to `devdiv-oneloc-githubapp` in `DevDiv/DevDiv`. | | `GitHubAppClientId` | `'Iv23lijBU8x3gc9lDOc9'` | The GitHub App client ID. | | `GitHubAppKeyVaultName` | `'EngKeyVault'` | Key Vault containing the App RSA signing key. | | `GitHubAppKeyName` | `'oneloc-localization-app-key'` | The App RSA signing key name. | diff --git a/eng/common/templates-official/job/onelocbuild.yml b/eng/common/templates-official/job/onelocbuild.yml index 8e82a870dea..9d1d6a85aff 100644 --- a/eng/common/templates-official/job/onelocbuild.yml +++ b/eng/common/templates-official/job/onelocbuild.yml @@ -5,19 +5,10 @@ parameters: # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool pool: '' - CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex - GithubPat: $(BotAccount-dotnet-bot-repo-PAT) - - # Service connection for WIF-based Entra authentication to ceapex feeds (replaces CeapexPat). - # The internal and DevDiv projects each provide a project-scoped connection with this name. - # Other projects, and any pipeline that sets this to '', fall back to CeapexPat. + # Project-scoped WIF service connection for Ceapex feed authentication. CeapexServiceConnection: 'dnceng-onelocbuild-ceapex' # 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' @@ -48,9 +39,6 @@ jobs: displayName: OneLocBuild${{ parameters.JobNameSuffix }} variables: - # Attach legacy secrets only when either PAT fallback can be selected. - - ${{ if or(eq(parameters.CeapexServiceConnection, ''), and(ne(variables['System.TeamProject'], 'internal'), ne(variables['System.TeamProject'], 'DevDiv')), and(eq(parameters.RepoType, 'gitHub'), or(ne(parameters.UseGitHubAppAuthentication, true), and(ne(variables['System.TeamProject'], 'internal'), ne(variables['System.TeamProject'], 'DevDiv'), ne(parameters.UseGitHubAppAuthenticationInOtherProjects, true))))) }}: - - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat - name: _GenerateLocProjectArguments value: -SourcesDirectory ${{ parameters.SourcesDirectory }} -LanguageSet "${{ parameters.LanguageSet }}" @@ -77,6 +65,11 @@ jobs: os: windows steps: + - ${{ if notIn(variables['System.TeamProject'], 'internal', 'DevDiv') }}: + - 'OneLocBuild is supported only in dnceng/internal and DevDiv/DevDiv.': error + - ${{ if eq(parameters.CeapexServiceConnection, '') }}: + - 'CeapexServiceConnection must identify a WIF service connection.': error + - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}: - task: Powershell@2 inputs: @@ -85,17 +78,15 @@ jobs: displayName: Generate LocProject.json condition: ${{ parameters.condition }} - # Acquire an Entra token for ceapex feed access in the supported internal and DevDiv projects. - - ${{ if and(ne(parameters.CeapexServiceConnection, ''), or(eq(variables['System.TeamProject'], 'internal'), eq(variables['System.TeamProject'], 'DevDiv'))) }}: - - template: /eng/common/templates-official/steps/get-federated-access-token.yml - parameters: - federatedServiceConnection: ${{ parameters.CeapexServiceConnection }} - outputVariableName: 'CeapexEntraToken' - condition: ${{ parameters.condition }} + # Acquire a short-lived Entra token for Ceapex feed access. + - template: /eng/common/templates-official/steps/get-federated-access-token.yml + parameters: + federatedServiceConnection: ${{ parameters.CeapexServiceConnection }} + outputVariableName: 'CeapexEntraToken' + condition: ${{ parameters.condition }} - # 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))) }}: + # Mint a short-lived GitHub App installation token for the loc check-in PR. + - ${{ if eq(parameters.RepoType, 'gitHub') }}: - template: /eng/common/templates-official/steps/get-github-app-token.yml parameters: ${{ if and(eq(variables['System.TeamProject'], 'DevDiv'), eq(parameters.GitHubAppServiceConnection, 'dnceng-oneloc-githubapp')) }}: @@ -125,16 +116,10 @@ jobs: ${{ if eq(parameters.RepoType, 'gitHub') }}: isShouldReusePrSelected: ${{ parameters.ReusePr }} packageSourceAuth: patAuth - ${{ if and(ne(parameters.CeapexServiceConnection, ''), or(eq(variables['System.TeamProject'], 'internal'), eq(variables['System.TeamProject'], 'DevDiv'))) }}: - patVariable: $(CeapexEntraToken) - ${{ if or(eq(parameters.CeapexServiceConnection, ''), and(ne(variables['System.TeamProject'], 'internal'), ne(variables['System.TeamProject'], 'DevDiv'))) }}: - patVariable: ${{ parameters.CeapexPat }} + patVariable: $(CeapexEntraToken) ${{ if eq(parameters.RepoType, 'gitHub') }}: repoType: ${{ parameters.RepoType }} - ${{ if and(eq(parameters.UseGitHubAppAuthentication, true), or(eq(variables['System.TeamProject'], 'internal'), eq(variables['System.TeamProject'], 'DevDiv'), eq(parameters.UseGitHubAppAuthenticationInOtherProjects, true))) }}: - gitHubPatVariable: "$(GitHubAppInstallationToken)" - ${{ else }}: - gitHubPatVariable: "${{ parameters.GithubPat }}" + gitHubPatVariable: "$(GitHubAppInstallationToken)" ${{ if ne(parameters.MirrorRepo, '') }}: isMirrorRepoSelected: true gitHubOrganization: ${{ parameters.GitHubOrg }} diff --git a/eng/common/templates/job/onelocbuild.yml b/eng/common/templates/job/onelocbuild.yml index 54aef43118f..3a6f5517a27 100644 --- a/eng/common/templates/job/onelocbuild.yml +++ b/eng/common/templates/job/onelocbuild.yml @@ -5,19 +5,10 @@ parameters: # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool pool: '' - CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex - GithubPat: $(BotAccount-dotnet-bot-repo-PAT) - - # Service connection for WIF-based Entra authentication to ceapex feeds (replaces CeapexPat). - # The internal and DevDiv projects each provide a project-scoped connection with this name. - # Other projects, and any pipeline that sets this to '', fall back to CeapexPat. + # Project-scoped WIF service connection for Ceapex feed authentication. CeapexServiceConnection: 'dnceng-onelocbuild-ceapex' # 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' @@ -48,9 +39,6 @@ jobs: displayName: OneLocBuild${{ parameters.JobNameSuffix }} variables: - # Attach legacy secrets only when either PAT fallback can be selected. - - ${{ if or(eq(parameters.CeapexServiceConnection, ''), and(ne(variables['System.TeamProject'], 'internal'), ne(variables['System.TeamProject'], 'DevDiv')), and(eq(parameters.RepoType, 'gitHub'), or(ne(parameters.UseGitHubAppAuthentication, true), and(ne(variables['System.TeamProject'], 'internal'), ne(variables['System.TeamProject'], 'DevDiv'), ne(parameters.UseGitHubAppAuthenticationInOtherProjects, true))))) }}: - - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat - name: _GenerateLocProjectArguments value: -SourcesDirectory ${{ parameters.SourcesDirectory }} -LanguageSet "${{ parameters.LanguageSet }}" @@ -74,6 +62,11 @@ jobs: demands: ImageOverride -equals windows.vs2022.amd64 steps: + - ${{ if notIn(variables['System.TeamProject'], 'internal', 'DevDiv') }}: + - 'OneLocBuild is supported only in dnceng/internal and DevDiv/DevDiv.': error + - ${{ if eq(parameters.CeapexServiceConnection, '') }}: + - 'CeapexServiceConnection must identify a WIF service connection.': error + - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}: - task: Powershell@2 inputs: @@ -82,17 +75,15 @@ jobs: displayName: Generate LocProject.json condition: ${{ parameters.condition }} - # Acquire an Entra token for ceapex feed access in the supported internal and DevDiv projects. - - ${{ 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 }} - outputVariableName: 'CeapexEntraToken' - condition: ${{ parameters.condition }} + # Acquire a short-lived Entra token for Ceapex feed access. + - template: /eng/common/templates/steps/get-federated-access-token.yml + parameters: + federatedServiceConnection: ${{ parameters.CeapexServiceConnection }} + outputVariableName: 'CeapexEntraToken' + condition: ${{ parameters.condition }} - # 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))) }}: + # Mint a short-lived GitHub App installation token for the loc check-in PR. + - ${{ if eq(parameters.RepoType, 'gitHub') }}: - template: /eng/common/templates/steps/get-github-app-token.yml parameters: ${{ if and(eq(variables['System.TeamProject'], 'DevDiv'), eq(parameters.GitHubAppServiceConnection, 'dnceng-oneloc-githubapp')) }}: @@ -122,16 +113,10 @@ jobs: ${{ if eq(parameters.RepoType, 'gitHub') }}: isShouldReusePrSelected: ${{ parameters.ReusePr }} packageSourceAuth: patAuth - ${{ if and(ne(parameters.CeapexServiceConnection, ''), or(eq(variables['System.TeamProject'], 'internal'), eq(variables['System.TeamProject'], 'DevDiv'))) }}: - patVariable: $(CeapexEntraToken) - ${{ if or(eq(parameters.CeapexServiceConnection, ''), and(ne(variables['System.TeamProject'], 'internal'), ne(variables['System.TeamProject'], 'DevDiv'))) }}: - patVariable: ${{ parameters.CeapexPat }} + patVariable: $(CeapexEntraToken) ${{ if eq(parameters.RepoType, 'gitHub') }}: repoType: ${{ parameters.RepoType }} - ${{ if and(eq(parameters.UseGitHubAppAuthentication, true), or(eq(variables['System.TeamProject'], 'internal'), eq(variables['System.TeamProject'], 'DevDiv'), eq(parameters.UseGitHubAppAuthenticationInOtherProjects, true))) }}: - gitHubPatVariable: "$(GitHubAppInstallationToken)" - ${{ else }}: - gitHubPatVariable: "${{ parameters.GithubPat }}" + gitHubPatVariable: "$(GitHubAppInstallationToken)" ${{ if ne(parameters.MirrorRepo, '') }}: isMirrorRepoSelected: true gitHubOrganization: ${{ parameters.GitHubOrg }} From a8f9f69b1a1f29a3e4452dce3ae210f5374e08b5 Mon Sep 17 00:00:00 2001 From: Missy Messa Date: Thu, 3 Sep 2026 13:06:14 -0700 Subject: [PATCH 3/3] Document OneLoc project support Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Documentation/OneLocBuild.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/OneLocBuild.md b/Documentation/OneLocBuild.md index 09ecbc575a3..245d14a92ec 100644 --- a/Documentation/OneLocBuild.md +++ b/Documentation/OneLocBuild.md @@ -200,7 +200,7 @@ The parameters that can be passed to the template are as follows: | `LanguageSet` | `VS_Main_Languages` | This defines the `LanguageSet` of the LocProject.json as described in the [OneLocBuild task documentation](https://ceapex.visualstudio.com/CEINTL/_wiki/wikis/CEINTL.wiki/107/Localization-with-OneLocBuild-Task?anchor=languageset%2C-languages-(required)). | | `LclSource` | `LclFilesInRepo` | This passes the `LclSource` input to the OneLocBuild task as described in [its documentation](https://ceapex.visualstudio.com/CEINTL/_wiki/wikis/CEINTL.wiki/107/Localization-with-OneLocBuild-Task?anchor=languageset%2C-languages-(required)). For most repos, this should be set to `LclFilesfromPackage`. | | `LclPackageId` | `''` | When `LclSource` is set to `LclFilesfromPackage`, this passes in the package ID as described in the [OneLocBuild task documentation](https://ceapex.visualstudio.com/CEINTL/_wiki/wikis/CEINTL.wiki/107/Localization-with-OneLocBuild-Task?anchor=scenario-2%3A-lcl-files-from-a-package). | -| `CeapexServiceConnection` | `'dnceng-onelocbuild-ceapex'` | The project-scoped WIF service connection used to acquire a short-lived token for the Ceapex feeds. Pipelines must be authorized to use the connection. | +| `CeapexServiceConnection` | `'dnceng-onelocbuild-ceapex'` | The project-scoped WIF service connection used to acquire a short-lived token for the Ceapex feeds. OneLocBuild supports only `dnceng/internal` and `DevDiv/DevDiv`; pipelines must be authorized to use the connection. | | `GitHubAppServiceConnection` | `'dnceng-oneloc-githubapp'` | The WIF service connection used to sign the App JWT. Arcade remaps this default to `devdiv-oneloc-githubapp` in `DevDiv/DevDiv`. | | `GitHubAppClientId` | `'Iv23lijBU8x3gc9lDOc9'` | The GitHub App client ID. | | `GitHubAppKeyVaultName` | `'EngKeyVault'` | Key Vault containing the App RSA signing key. |