Use Azure Artifacts Maven feed for CFSClean network isolation compliance#35089
Conversation
Replace mavenCentral(), google(), and gradlePluginPortal() with the dnceng public Azure Artifacts Maven feed in settings.gradle, matching the pattern used by dotnet/aspnetcore (PR dotnet/aspnetcore#64962). Also install an init.gradle into GRADLE_USER_HOME that redirects any remaining Maven Central/Google Maven repository references (e.g. from Microsoft.Android.Sdk.Bindings.Gradle.targets) to the same Azure Artifacts feed. This covers Gradle invocations outside of our control. Feed: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-maven/maven/v1 This is the proper fix for CFSClean network isolation blocking repo.maven.apache.org on Windows 1ES agents. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35089Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35089" |
There was a problem hiding this comment.
Pull request overview
This PR updates the Android/Gradle dependency resolution used by MAUI’s build and CI pipeline to comply with CFSClean network isolation by routing Maven/Google/Plugin Portal access through the public dnceng Azure Artifacts Maven feed.
Changes:
- Replace
google(),mavenCentral(), andgradlePluginPortal()usage in AndroidNative Gradle settings with the Azure Artifacts Maven feed and enforceFAIL_ON_PROJECT_REPOS. - Add a global
eng/init.gradleinit script intended to redirect Maven/Google/Plugin Portal repositories to the Azure Artifacts feed for Gradle invocations MAUI doesn’t directly control. - Update the Gradle cache pipeline template to copy
eng/init.gradleintoGRADLE_USER_HOME.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/Core/AndroidNative/settings.gradle | Routes plugin/dependency resolution through the Azure Artifacts Maven feed; enforces no project-level repos. |
| src/Core/AndroidNative/build.gradle | Removes buildscript repository declarations (but still uses buildscript classpath). |
| eng/pipelines/common/cache-gradle.yml | Copies eng/init.gradle into GRADLE_USER_HOME during cache setup on macOS/Windows. |
| eng/init.gradle | Adds an init script to rewrite certain Maven repository URLs to the Azure Artifacts feed. |
FAIL_ON_PROJECT_REPOS blocks buildscript classpath resolution when the Android SDK bindings Gradle targets invoke our project. Revert to PREFER_PROJECT and keep buildscript.repositories pointing to the Azure Artifacts feed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Cache@2 task can restore a stale init.gradle from a previous run. Move the init.gradle copy step after cache restore so the current version always wins. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
|
1 similar comment
|
|
|
|
2 similar comments
|
|
|
|
Create the feed repo once via findByName/maven, then only remove
matching repos in the all{} callback. Previously each matching repo
created a new duplicate dotnet-public-maven entry.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jonathanpeppers
left a comment
There was a problem hiding this comment.
This looks find 👍 , but I wonder if it blocks any contributors from building.
Microsoft.Android.Sdk 36.1.2's net.android.init.gradle.kts has a Kotlin type mismatch (String? vs Any) that fails with Gradle 9.x. The fix is merged upstream (dotnet/android#10738) but hasn't shipped in this SDK version. Revert to Gradle 8.13. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
New packages added to build.gradle must be ingested into the dotnet-public-maven Azure Artifacts feed before CI can use them. This script automates that process using the credential provider for auth and curl fallback for packages in scopes the Gradle plugin doesn't cover. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Explain why ingestion is needed (CFSClean + credential provider skips in CI), when to run it, how it works, and the common pitfall of local Gradle cache masking missing feed packages. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Android SDK's net.android.init.gradle.kts is incompatible with Gradle 9.x due to stricter Kotlin type checking (String? vs Any). Fix merged upstream (dotnet/android#10738) but not yet shipped in the SDK version used by this branch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- set -e killed the script when gradlew build failed (the normal case when packages need ingesting). Add || true to capture output. - set -e + pipefail killed the script when grep found no matching URLs, preventing the 'not a feed issue' diagnostic. Add || true. - Step 1 now logs a warning on failure instead of silently swallowing. - Step 1 shows last 20 lines instead of 3 for better diagnostics. - curl token moved from -H arg to --oauth2-bearer to avoid exposure in process listings (ps aux). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Hardcoded $HOME/.gradle could diverge from GRADLE_USER_HOME if it's overridden. Use the pipeline variable to ensure init.gradle is always copied to where Gradle actually reads it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Gradle on macOS only resolves aapt2-osx.jar. CI builds on Windows and Linux need their platform-specific variants pre-ingested too. The script now explicitly curls all three OS classifiers (osx, linux, windows) before running the Gradle build. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When agents or developers hit Gradle 401 errors from the Azure Artifacts feed, they'll now see clear guidance: run the ingestion script. Also added the Gradle 8.x version constraint. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This is always loaded regardless of which files are being worked on, so agents investigating CI failures will see the guidance to run eng/ingest-maven-deps.sh for Gradle 401 errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When agents investigate CI failures and see XAGRDL0000 or 401 errors from the Maven feed, they'll now see the exact fix (run the ingestion script) and explicit DO NOT guidance (don't remove CFSClean, don't upgrade Gradle, don't add mavenCentral() back). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Skill Validation Results❌ Static Checks FailedSkills checked: 15 | Agents checked: 0 Full validator output⏭️ LLM Evaluation: SkippedNo changed skills with eval tests found. |
Each file now has a distinct role: - copilot-instructions.md: always-on context (5 lines) - azdo-build-investigator: error signatures + DO NOTs for investigation - android.instructions.md: one-liner pointing to script Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Upstream issue filed: microsoft/artifacts-credprovider#671 — the Gradle credential provider plugin doesn't cover |
…compliance (#35169) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! Cherry-pick of #35089 from `release/10.0.1xx-sr6` to `main`. See #35089 for full details — routes Gradle/Maven dependency resolution through Azure Artifacts feed for CFSClean compliance. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Matt Mitchell (.NET) <mmitche@microsoft.com>
…an network isolation compliance (#35170) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! Cherry-pick of #35089 from `release/10.0.1xx-sr6` to `release/11.0.1xx-preview4`. See #35089 for full details — routes Gradle/Maven dependency resolution through Azure Artifacts feed for CFSClean compliance. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Matt Mitchell (.NET) <mmitche@microsoft.com>
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Problem
The official build pipeline (
dotnet-maui, def 1095) fails because CFSClean network isolation blocks direct access torepo.maven.apache.org. This breaks two separate Gradle invocations:src/Core/AndroidNativebuild — our own Gradle projectMicrosoft.Android.Sdk.Bindings.Gradle.targets— Android SDK binding generator inCore.csprojPer 1ES CFS guidance, the fix is to route all Maven dependency resolution through an Azure Artifacts feed with upstream sources.
Fix
Gradle configuration changes
settings.gradle— ReplacemavenCentral(),google(),gradlePluginPortal()with thedotnet-public-mavenAzure Artifacts feed. Add the Azure Artifacts Gradle credential provider plugin (v1.1.1) for local authentication.build.gradle— Pointbuildscript.repositoriesto the same feed for AGP classpath resolution.eng/init.gradle— Global Gradle init script that redirects any remaining Maven Central/Google Maven references (e.g. fromMicrosoft.Android.Sdk.Bindings.Gradle.targets) to the feed. Installed intoGRADLE_USER_HOMEby the pipeline.Pipeline changes
cache-gradle.yml— Copyinit.gradleintoGRADLE_USER_HOMEafter cache restore to prevent stale cached copies. Uses$(GRADLE_USER_HOME)variable for the destination path.Why the ingestion script (
eng/ingest-maven-deps.sh) is neededThe
dotnet-public-mavenfeed proxies Maven Central, but new packages require an authenticated first-time pull to be saved. The Gradle credential provider plugin has two limitations that preventdotnet buildfrom self-ingesting:TF_BUILD=True(Azure Pipelines), the plugin is a no-oppluginManagement.repositoriesandproject.repositories, but NOTbuildscript.repositoriesor AGP's internaldetachedConfigurationscopes. This meansdotnet buildlocally cannot ingest new packages through the Android SDK binding targets even with correct credentials.We verified this by adding an un-ingested package (
io.coil-kt:coil:2.7.0) —dotnet buildfails with 401 despite the credential provider authenticating successfully.Upstream issue: microsoft/artifacts-credprovider#671
The script works around these gaps by:
--refresh-dependenciesto bypass local cachecurlwith Bearer token for unreachable scopesRun
./eng/ingest-maven-deps.shafter adding or updating any Maven/Gradle dependency.Documentation updates
settings.gradle— explains the feed setup and when to run the scriptgradle-wrapper.properties— warning not to upgrade Gradle past 8.x (dotnet/android#10738)copilot-instructions.md— always-on guidance for Gradle 401 failuresazdo-build-investigator/SKILL.md— error signatures and DO NOTs for CI investigationandroid.instructions.md— quick reference for Android developersVerified
dotnet buildworks for already-ingested packages, fails for new ones (confirming script is needed)