From e308a02187449453714b8585af9fa2beea8f7efa Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Mon, 13 Jul 2026 10:31:24 -0500 Subject: [PATCH 1/4] [build] Avoid Azure authentication for local Gradle builds Remove the unused Azure Artifacts credential provider. CI consumes the Maven mirror anonymously, while the mirror helper authenticates through Azure CLI when dependencies need to be seeded. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: c002d2dd-f957-4940-92a4-d23037322e70 --- .github/instructions/gradle.instructions.md | 4 ---- eng/gradle/dependency-repositories.gradle | 3 --- eng/gradle/plugin-repositories.gradle | 10 ---------- src/manifestmerger/settings.gradle | 4 ---- src/proguard-android/settings.gradle | 4 ---- src/r8/settings.gradle | 4 ---- .../java/JavaLib/settings.gradle | 4 ---- 7 files changed, 33 deletions(-) diff --git a/.github/instructions/gradle.instructions.md b/.github/instructions/gradle.instructions.md index 28629fe2e73..41d18b54cca 100644 --- a/.github/instructions/gradle.instructions.md +++ b/.github/instructions/gradle.instructions.md @@ -12,9 +12,6 @@ All `src/*` Gradle projects share two repo config files: **`eng/gradle/plugin-re pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -plugins { - id 'com.microsoft.azure.artifacts.credprovider' version '1.1.1' -} dependencyResolutionManagement { apply from: "${rootDir}/../../eng/gradle/dependency-repositories.gradle", to: dependencyResolutionManagement } @@ -54,5 +51,4 @@ After it succeeds, just re-run the failed CI job. No PR edits needed — the pac ## Don'ts - Don't hard-code Maven repo URLs in `build.gradle` / `settings.gradle`; use the shared file. -- Don't wrap `plugins {}` in `if (...)` — Gradle rejects it. - Don't use modern `plugins { id 'com.android.application' version '...' }` DSL without confirming the plugin is in `dotnet-public-maven`; prefer `buildscript { ... } / apply plugin: '...'` when in doubt. \ No newline at end of file diff --git a/eng/gradle/dependency-repositories.gradle b/eng/gradle/dependency-repositories.gradle index ac491c649c2..9c441d7f5fe 100644 --- a/eng/gradle/dependency-repositories.gradle +++ b/eng/gradle/dependency-repositories.gradle @@ -3,9 +3,6 @@ // in this repo. See plugin-repositories.gradle for plugin resolution. // // Switches on RunningOnCI for the same CFSClean reasons described there. -// AzureArtifacts is intentionally NOT included here — it only hosts the -// credprovider plugin, so listing it in this scope would add a 404 round-trip -// to every dependency lookup. repositories { // AzDO uppercases pipeline variables when exporting them as env vars on diff --git a/eng/gradle/plugin-repositories.gradle b/eng/gradle/plugin-repositories.gradle index 5763cacff65..f09bfe892a4 100644 --- a/eng/gradle/plugin-repositories.gradle +++ b/eng/gradle/plugin-repositories.gradle @@ -7,9 +7,6 @@ // isolation compliance (https://aka.ms/1es/netiso/CFS). Locally and from // GitHub Actions (e.g. Dependabot), the standard Gradle Plugin Portal is used. // -// AzureArtifacts (anonymous public feed) is always included because every -// settings.gradle loads the artifacts-credprovider plugin from there. -// // The dnceng feed proxies public sources. Once any package has been pulled // through the feed (an authenticated request), it is cached and anonymous // reads work forever after. CI therefore does NOT need credentials — it just @@ -22,13 +19,6 @@ // After it succeeds, just re-run the failed CI job — no PR edit is needed. repositories { - // Anonymous public Azure Artifacts feed that hosts the - // artifacts-credprovider Gradle plugin (loaded by every settings.gradle). - maven { - url = 'https://pkgs.dev.azure.com/artifacts-public/PublicTools/_packaging/AzureArtifacts/maven/v1' - name = 'AzureArtifacts' - } - // AzDO uppercases pipeline variables when exporting them as env vars on // Linux/macOS agents, so check both spellings. def runningOnCI = System.getenv('RunningOnCI') ?: System.getenv('RUNNINGONCI') diff --git a/src/manifestmerger/settings.gradle b/src/manifestmerger/settings.gradle index 483063983cd..3e3476ad0db 100644 --- a/src/manifestmerger/settings.gradle +++ b/src/manifestmerger/settings.gradle @@ -3,10 +3,6 @@ pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -plugins { - id 'com.microsoft.azure.artifacts.credprovider' version '1.1.1' -} - dependencyResolutionManagement { apply from: "${rootDir}/../../eng/gradle/dependency-repositories.gradle", to: dependencyResolutionManagement } diff --git a/src/proguard-android/settings.gradle b/src/proguard-android/settings.gradle index f1d5c0e6326..81ae06902e4 100644 --- a/src/proguard-android/settings.gradle +++ b/src/proguard-android/settings.gradle @@ -3,10 +3,6 @@ pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -plugins { - id 'com.microsoft.azure.artifacts.credprovider' version '1.1.1' -} - dependencyResolutionManagement { apply from: "${rootDir}/../../eng/gradle/dependency-repositories.gradle", to: dependencyResolutionManagement } diff --git a/src/r8/settings.gradle b/src/r8/settings.gradle index 0d56e34025f..db2330c2990 100644 --- a/src/r8/settings.gradle +++ b/src/r8/settings.gradle @@ -3,10 +3,6 @@ pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -plugins { - id 'com.microsoft.azure.artifacts.credprovider' version '1.1.1' -} - dependencyResolutionManagement { apply from: "${rootDir}/../../eng/gradle/dependency-repositories.gradle", to: dependencyResolutionManagement } diff --git a/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle b/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle index 571862a24e5..3ffd8e8c9c6 100644 --- a/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle +++ b/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle @@ -3,10 +3,6 @@ pluginManagement { apply from: "${rootDir}/../../../../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -plugins { - id 'com.microsoft.azure.artifacts.credprovider' version '1.1.1' -} - dependencyResolutionManagement { apply from: "${rootDir}/../../../../../eng/gradle/dependency-repositories.gradle", to: dependencyResolutionManagement } From 47f22ddd4efa89eec78a0fb257da42aaf8318ce5 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Mon, 13 Jul 2026 10:35:29 -0500 Subject: [PATCH 2/4] [build] Load Gradle credential provider only on CI Keep Azure DevOps mirror authentication available when RunningOnCI is true, without resolving or applying the credential provider during local builds. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: c002d2dd-f957-4940-92a4-d23037322e70 --- .github/instructions/gradle.instructions.md | 7 +++++++ eng/gradle/credential-provider.gradle | 15 +++++++++++++++ src/manifestmerger/settings.gradle | 5 +++++ src/proguard-android/settings.gradle | 5 +++++ src/r8/settings.gradle | 5 +++++ .../java/JavaLib/settings.gradle | 5 +++++ 6 files changed, 42 insertions(+) create mode 100644 eng/gradle/credential-provider.gradle diff --git a/.github/instructions/gradle.instructions.md b/.github/instructions/gradle.instructions.md index 41d18b54cca..e2939b91136 100644 --- a/.github/instructions/gradle.instructions.md +++ b/.github/instructions/gradle.instructions.md @@ -12,6 +12,10 @@ All `src/*` Gradle projects share two repo config files: **`eng/gradle/plugin-re pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } +def runningOnCI = System.getenv('RunningOnCI') ?: System.getenv('RUNNINGONCI') +if (runningOnCI == 'true') { + apply from: "${rootDir}/../../eng/gradle/credential-provider.gradle" +} dependencyResolutionManagement { apply from: "${rootDir}/../../eng/gradle/dependency-repositories.gradle", to: dependencyResolutionManagement } @@ -27,6 +31,9 @@ Both files switch on `System.getenv('RunningOnCI')` (or `RUNNINGONCI` — AzDO u - **`RunningOnCI=true`** (Azure DevOps, set in `build-tools/automation/yaml-templates/variables.yaml`) → dnceng `dotnet-public-maven` feed (CFSClean isolation, https://aka.ms/1es/netiso/CFS). Anonymous read of cached packages. - **unset** (local, Dependabot, GitHub Actions) → `google()` + `mavenCentral()` + `gradlePluginPortal()` for plugins, `google()` + `mavenCentral()` for deps. No credentials needed. +The Azure Artifacts credential provider is also loaded only when +`RunningOnCI=true`, so local builds never attempt Azure authentication. + Test the CI path locally: `$env:RunningOnCI='true'` (PowerShell) or `RunningOnCI=true ...` (bash). ## When CI fails 401 on a Dependabot bump diff --git a/eng/gradle/credential-provider.gradle b/eng/gradle/credential-provider.gradle new file mode 100644 index 00000000000..b2b40ee84fc --- /dev/null +++ b/eng/gradle/credential-provider.gradle @@ -0,0 +1,15 @@ +// Azure DevOps uses this plugin to authenticate with the Maven mirror. +// This script is only applied when RunningOnCI=true. +buildscript { + repositories { + maven { + url = 'https://pkgs.dev.azure.com/artifacts-public/PublicTools/_packaging/AzureArtifacts/maven/v1' + name = 'AzureArtifacts' + } + } + dependencies { + classpath 'com.microsoft.azure:artifacts-gradle-credprovider:1.1.1' + } +} + +apply plugin: com.microsoft.azure.artifacts.credprovider.gradle.GradleCredentialProviderPlugin diff --git a/src/manifestmerger/settings.gradle b/src/manifestmerger/settings.gradle index 3e3476ad0db..48110c13fa2 100644 --- a/src/manifestmerger/settings.gradle +++ b/src/manifestmerger/settings.gradle @@ -3,6 +3,11 @@ pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } +def runningOnCI = System.getenv('RunningOnCI') ?: System.getenv('RUNNINGONCI') +if (runningOnCI == 'true') { + apply from: "${rootDir}/../../eng/gradle/credential-provider.gradle" +} + dependencyResolutionManagement { apply from: "${rootDir}/../../eng/gradle/dependency-repositories.gradle", to: dependencyResolutionManagement } diff --git a/src/proguard-android/settings.gradle b/src/proguard-android/settings.gradle index 81ae06902e4..ab92a0d4574 100644 --- a/src/proguard-android/settings.gradle +++ b/src/proguard-android/settings.gradle @@ -3,6 +3,11 @@ pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } +def runningOnCI = System.getenv('RunningOnCI') ?: System.getenv('RUNNINGONCI') +if (runningOnCI == 'true') { + apply from: "${rootDir}/../../eng/gradle/credential-provider.gradle" +} + dependencyResolutionManagement { apply from: "${rootDir}/../../eng/gradle/dependency-repositories.gradle", to: dependencyResolutionManagement } diff --git a/src/r8/settings.gradle b/src/r8/settings.gradle index db2330c2990..91a3f8d51f7 100644 --- a/src/r8/settings.gradle +++ b/src/r8/settings.gradle @@ -3,6 +3,11 @@ pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } +def runningOnCI = System.getenv('RunningOnCI') ?: System.getenv('RUNNINGONCI') +if (runningOnCI == 'true') { + apply from: "${rootDir}/../../eng/gradle/credential-provider.gradle" +} + dependencyResolutionManagement { apply from: "${rootDir}/../../eng/gradle/dependency-repositories.gradle", to: dependencyResolutionManagement } diff --git a/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle b/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle index 3ffd8e8c9c6..80332cc9262 100644 --- a/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle +++ b/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle @@ -3,6 +3,11 @@ pluginManagement { apply from: "${rootDir}/../../../../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } +def runningOnCI = System.getenv('RunningOnCI') ?: System.getenv('RUNNINGONCI') +if (runningOnCI == 'true') { + apply from: "${rootDir}/../../../../../eng/gradle/credential-provider.gradle" +} + dependencyResolutionManagement { apply from: "${rootDir}/../../../../../eng/gradle/dependency-repositories.gradle", to: dependencyResolutionManagement } From 51d6feea8a89f5daedc00916fba6ad69e15dd464 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Mon, 13 Jul 2026 10:51:25 -0500 Subject: [PATCH 3/4] [build] Normalize Gradle CI environment variable Use Azure DevOps' exported RUNNINGONCI spelling consistently and update the mirror helper to set that same environment variable for local cache warming. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: c002d2dd-f957-4940-92a4-d23037322e70 --- .github/instructions/gradle.instructions.md | 12 ++++++------ eng/gradle/credential-provider.gradle | 2 +- eng/gradle/dependency-repositories.gradle | 7 ++----- eng/gradle/mirror-dependencies.ps1 | 4 ++-- eng/gradle/plugin-repositories.gradle | 7 ++----- src/manifestmerger/settings.gradle | 3 +-- src/proguard-android/settings.gradle | 3 +-- src/r8/settings.gradle | 3 +-- .../java/JavaLib/settings.gradle | 3 +-- 9 files changed, 17 insertions(+), 27 deletions(-) diff --git a/.github/instructions/gradle.instructions.md b/.github/instructions/gradle.instructions.md index e2939b91136..353225a62cf 100644 --- a/.github/instructions/gradle.instructions.md +++ b/.github/instructions/gradle.instructions.md @@ -12,8 +12,7 @@ All `src/*` Gradle projects share two repo config files: **`eng/gradle/plugin-re pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -def runningOnCI = System.getenv('RunningOnCI') ?: System.getenv('RUNNINGONCI') -if (runningOnCI == 'true') { +if (System.getenv('RUNNINGONCI') == 'true') { apply from: "${rootDir}/../../eng/gradle/credential-provider.gradle" } dependencyResolutionManagement { @@ -26,15 +25,16 @@ rootProject.name = '' ## CI vs local -Both files switch on `System.getenv('RunningOnCI')` (or `RUNNINGONCI` — AzDO uppercases env vars on Linux/macOS agents): +Both files switch on `System.getenv('RUNNINGONCI')`. Azure DevOps exports the +`RunningOnCI` pipeline variable under this normalized environment-variable name. -- **`RunningOnCI=true`** (Azure DevOps, set in `build-tools/automation/yaml-templates/variables.yaml`) → dnceng `dotnet-public-maven` feed (CFSClean isolation, https://aka.ms/1es/netiso/CFS). Anonymous read of cached packages. +- **`RUNNINGONCI=true`** (Azure DevOps, sourced from `RunningOnCI` in `build-tools/automation/yaml-templates/variables.yaml`) → dnceng `dotnet-public-maven` feed (CFSClean isolation, https://aka.ms/1es/netiso/CFS). Anonymous read of cached packages. - **unset** (local, Dependabot, GitHub Actions) → `google()` + `mavenCentral()` + `gradlePluginPortal()` for plugins, `google()` + `mavenCentral()` for deps. No credentials needed. The Azure Artifacts credential provider is also loaded only when -`RunningOnCI=true`, so local builds never attempt Azure authentication. +`RUNNINGONCI=true`, so local builds never attempt Azure authentication. -Test the CI path locally: `$env:RunningOnCI='true'` (PowerShell) or `RunningOnCI=true ...` (bash). +Test the CI path locally: `$env:RUNNINGONCI='true'` (PowerShell) or `RUNNINGONCI=true ...` (bash). ## When CI fails 401 on a Dependabot bump diff --git a/eng/gradle/credential-provider.gradle b/eng/gradle/credential-provider.gradle index b2b40ee84fc..e033c62bbca 100644 --- a/eng/gradle/credential-provider.gradle +++ b/eng/gradle/credential-provider.gradle @@ -1,5 +1,5 @@ // Azure DevOps uses this plugin to authenticate with the Maven mirror. -// This script is only applied when RunningOnCI=true. +// This script is only applied when RUNNINGONCI=true. buildscript { repositories { maven { diff --git a/eng/gradle/dependency-repositories.gradle b/eng/gradle/dependency-repositories.gradle index 9c441d7f5fe..a9daafecc52 100644 --- a/eng/gradle/dependency-repositories.gradle +++ b/eng/gradle/dependency-repositories.gradle @@ -2,13 +2,10 @@ // (dependencyResolutionManagement.repositories) across every settings.gradle // in this repo. See plugin-repositories.gradle for plugin resolution. // -// Switches on RunningOnCI for the same CFSClean reasons described there. +// Switches on RUNNINGONCI for the same CFSClean reasons described there. repositories { - // AzDO uppercases pipeline variables when exporting them as env vars on - // Linux/macOS agents, so check both spellings. - def runningOnCI = System.getenv('RunningOnCI') ?: System.getenv('RUNNINGONCI') - if (runningOnCI == 'true') { + if (System.getenv('RUNNINGONCI') == 'true') { maven { url = 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-maven/maven/v1' name = 'dotnet-public-maven' diff --git a/eng/gradle/mirror-dependencies.ps1 b/eng/gradle/mirror-dependencies.ps1 index 20a225c9d21..5bbc0586a5d 100644 --- a/eng/gradle/mirror-dependencies.ps1 +++ b/eng/gradle/mirror-dependencies.ps1 @@ -11,7 +11,7 @@ so a developer has to authenticate locally once to seed the feed. This script does that by running the requested gradle build in a loop: - 1. Run gradle with RunningOnCI=true so it points at the dnceng feed. + 1. Run gradle with RUNNINGONCI=true so it points at the dnceng feed. 2. Parse any 'Could not GET' URLs out of the build log. 3. Re-fetch each failing URL with an Azure DevOps OAuth bearer token (obtained via `az account get-access-token`). The feed's upstream @@ -113,7 +113,7 @@ if ($AndroidHome) { Write-Host "ANDROID_HOME: $AndroidHome" } Get-AzDevOpsToken | Out-Null if ($AndroidHome) { $env:ANDROID_HOME = $AndroidHome } -$env:RunningOnCI = 'true' +$env:RUNNINGONCI = 'true' Push-Location $projectDirAbs try { diff --git a/eng/gradle/plugin-repositories.gradle b/eng/gradle/plugin-repositories.gradle index f09bfe892a4..898391470d1 100644 --- a/eng/gradle/plugin-repositories.gradle +++ b/eng/gradle/plugin-repositories.gradle @@ -2,7 +2,7 @@ // across every settings.gradle in this repo. See plugin-repositories.gradle's // sibling, dependency-repositories.gradle, for project dependency resolution. // -// In our Azure DevOps CI pipeline (RunningOnCI=true), plugins resolve through +// In our Azure DevOps CI pipeline (RUNNINGONCI=true), plugins resolve through // the dnceng Azure Artifacts feed (dotnet-public-maven) for CFSClean network // isolation compliance (https://aka.ms/1es/netiso/CFS). Locally and from // GitHub Actions (e.g. Dependabot), the standard Gradle Plugin Portal is used. @@ -19,10 +19,7 @@ // After it succeeds, just re-run the failed CI job — no PR edit is needed. repositories { - // AzDO uppercases pipeline variables when exporting them as env vars on - // Linux/macOS agents, so check both spellings. - def runningOnCI = System.getenv('RunningOnCI') ?: System.getenv('RUNNINGONCI') - if (runningOnCI == 'true') { + if (System.getenv('RUNNINGONCI') == 'true') { maven { url = 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-maven/maven/v1' name = 'dotnet-public-maven' diff --git a/src/manifestmerger/settings.gradle b/src/manifestmerger/settings.gradle index 48110c13fa2..64b4f10ce46 100644 --- a/src/manifestmerger/settings.gradle +++ b/src/manifestmerger/settings.gradle @@ -3,8 +3,7 @@ pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -def runningOnCI = System.getenv('RunningOnCI') ?: System.getenv('RUNNINGONCI') -if (runningOnCI == 'true') { +if (System.getenv('RUNNINGONCI') == 'true') { apply from: "${rootDir}/../../eng/gradle/credential-provider.gradle" } diff --git a/src/proguard-android/settings.gradle b/src/proguard-android/settings.gradle index ab92a0d4574..e2ebbb8cf73 100644 --- a/src/proguard-android/settings.gradle +++ b/src/proguard-android/settings.gradle @@ -3,8 +3,7 @@ pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -def runningOnCI = System.getenv('RunningOnCI') ?: System.getenv('RUNNINGONCI') -if (runningOnCI == 'true') { +if (System.getenv('RUNNINGONCI') == 'true') { apply from: "${rootDir}/../../eng/gradle/credential-provider.gradle" } diff --git a/src/r8/settings.gradle b/src/r8/settings.gradle index 91a3f8d51f7..9605706b525 100644 --- a/src/r8/settings.gradle +++ b/src/r8/settings.gradle @@ -3,8 +3,7 @@ pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -def runningOnCI = System.getenv('RunningOnCI') ?: System.getenv('RUNNINGONCI') -if (runningOnCI == 'true') { +if (System.getenv('RUNNINGONCI') == 'true') { apply from: "${rootDir}/../../eng/gradle/credential-provider.gradle" } diff --git a/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle b/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle index 80332cc9262..7b8de01d85f 100644 --- a/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle +++ b/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle @@ -3,8 +3,7 @@ pluginManagement { apply from: "${rootDir}/../../../../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -def runningOnCI = System.getenv('RunningOnCI') ?: System.getenv('RUNNINGONCI') -if (runningOnCI == 'true') { +if (System.getenv('RUNNINGONCI') == 'true') { apply from: "${rootDir}/../../../../../eng/gradle/credential-provider.gradle" } From d0fc80667d8d833690f44fba7beb5f02c0e6b4ee Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Mon, 13 Jul 2026 11:05:02 -0500 Subject: [PATCH 4/4] [build] Restrict Maven authentication to mirror seeding Use a dedicated environment variable set only by mirror-dependencies.ps1 to load the Azure Artifacts credential provider. Regular CI continues reading cached dependencies anonymously from the Maven mirror. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: c002d2dd-f957-4940-92a4-d23037322e70 --- .github/instructions/gradle.instructions.md | 7 ++++--- eng/gradle/credential-provider.gradle | 6 ++++-- eng/gradle/mirror-dependencies.ps1 | 1 + src/manifestmerger/settings.gradle | 2 +- src/proguard-android/settings.gradle | 2 +- src/r8/settings.gradle | 2 +- .../java/JavaLib/settings.gradle | 2 +- 7 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.github/instructions/gradle.instructions.md b/.github/instructions/gradle.instructions.md index 353225a62cf..b702b46d390 100644 --- a/.github/instructions/gradle.instructions.md +++ b/.github/instructions/gradle.instructions.md @@ -12,7 +12,7 @@ All `src/*` Gradle projects share two repo config files: **`eng/gradle/plugin-re pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -if (System.getenv('RUNNINGONCI') == 'true') { +if (System.getenv('ANDROID_MIRROR_MAVEN_DEPENDENCIES') == 'true') { apply from: "${rootDir}/../../eng/gradle/credential-provider.gradle" } dependencyResolutionManagement { @@ -31,8 +31,9 @@ Both files switch on `System.getenv('RUNNINGONCI')`. Azure DevOps exports the - **`RUNNINGONCI=true`** (Azure DevOps, sourced from `RunningOnCI` in `build-tools/automation/yaml-templates/variables.yaml`) → dnceng `dotnet-public-maven` feed (CFSClean isolation, https://aka.ms/1es/netiso/CFS). Anonymous read of cached packages. - **unset** (local, Dependabot, GitHub Actions) → `google()` + `mavenCentral()` + `gradlePluginPortal()` for plugins, `google()` + `mavenCentral()` for deps. No credentials needed. -The Azure Artifacts credential provider is also loaded only when -`RUNNINGONCI=true`, so local builds never attempt Azure authentication. +CI reads cached packages from the mirror anonymously. The Azure Artifacts +credential provider is loaded only when `ANDROID_MIRROR_MAVEN_DEPENDENCIES=true`; +`mirror-dependencies.ps1` sets this while seeding uncached packages. Test the CI path locally: `$env:RUNNINGONCI='true'` (PowerShell) or `RUNNINGONCI=true ...` (bash). diff --git a/eng/gradle/credential-provider.gradle b/eng/gradle/credential-provider.gradle index e033c62bbca..32f6fa95e8b 100644 --- a/eng/gradle/credential-provider.gradle +++ b/eng/gradle/credential-provider.gradle @@ -1,5 +1,5 @@ -// Azure DevOps uses this plugin to authenticate with the Maven mirror. -// This script is only applied when RUNNINGONCI=true. +// The dependency-mirroring helper uses this plugin to authenticate with the +// Maven mirror. Regular local and CI builds do not apply this script. buildscript { repositories { maven { @@ -12,4 +12,6 @@ buildscript { } } +// Plugins loaded through an applied script's buildscript classpath cannot be +// resolved by ID; Gradle requires the implementation class in this context. apply plugin: com.microsoft.azure.artifacts.credprovider.gradle.GradleCredentialProviderPlugin diff --git a/eng/gradle/mirror-dependencies.ps1 b/eng/gradle/mirror-dependencies.ps1 index 5bbc0586a5d..dedf0abbdfc 100644 --- a/eng/gradle/mirror-dependencies.ps1 +++ b/eng/gradle/mirror-dependencies.ps1 @@ -114,6 +114,7 @@ Get-AzDevOpsToken | Out-Null if ($AndroidHome) { $env:ANDROID_HOME = $AndroidHome } $env:RUNNINGONCI = 'true' +$env:ANDROID_MIRROR_MAVEN_DEPENDENCIES = 'true' Push-Location $projectDirAbs try { diff --git a/src/manifestmerger/settings.gradle b/src/manifestmerger/settings.gradle index 64b4f10ce46..47d043fb305 100644 --- a/src/manifestmerger/settings.gradle +++ b/src/manifestmerger/settings.gradle @@ -3,7 +3,7 @@ pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -if (System.getenv('RUNNINGONCI') == 'true') { +if (System.getenv('ANDROID_MIRROR_MAVEN_DEPENDENCIES') == 'true') { apply from: "${rootDir}/../../eng/gradle/credential-provider.gradle" } diff --git a/src/proguard-android/settings.gradle b/src/proguard-android/settings.gradle index e2ebbb8cf73..8a8d63d070d 100644 --- a/src/proguard-android/settings.gradle +++ b/src/proguard-android/settings.gradle @@ -3,7 +3,7 @@ pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -if (System.getenv('RUNNINGONCI') == 'true') { +if (System.getenv('ANDROID_MIRROR_MAVEN_DEPENDENCIES') == 'true') { apply from: "${rootDir}/../../eng/gradle/credential-provider.gradle" } diff --git a/src/r8/settings.gradle b/src/r8/settings.gradle index 9605706b525..39e8674b5d8 100644 --- a/src/r8/settings.gradle +++ b/src/r8/settings.gradle @@ -3,7 +3,7 @@ pluginManagement { apply from: "${rootDir}/../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -if (System.getenv('RUNNINGONCI') == 'true') { +if (System.getenv('ANDROID_MIRROR_MAVEN_DEPENDENCIES') == 'true') { apply from: "${rootDir}/../../eng/gradle/credential-provider.gradle" } diff --git a/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle b/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle index 7b8de01d85f..0f5b891e40c 100644 --- a/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle +++ b/tests/CodeGen-Binding/Xamarin.Android.LibraryProjectZip-LibBinding/java/JavaLib/settings.gradle @@ -3,7 +3,7 @@ pluginManagement { apply from: "${rootDir}/../../../../../eng/gradle/plugin-repositories.gradle", to: pluginManagement } -if (System.getenv('RUNNINGONCI') == 'true') { +if (System.getenv('ANDROID_MIRROR_MAVEN_DEPENDENCIES') == 'true') { apply from: "${rootDir}/../../../../../eng/gradle/credential-provider.gradle" }