Skip to content

Add Gradle cache to official pack pipeline#35049

Merged
PureWeen merged 3 commits into
release/10.0.1xx-sr6from
fix/gradle-cache-pack-yml
Apr 21, 2026
Merged

Add Gradle cache to official pack pipeline#35049
PureWeen merged 3 commits into
release/10.0.1xx-sr6from
fix/gradle-cache-pack-yml

Conversation

@PureWeen

Copy link
Copy Markdown
Member

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 (dotnet-maui, definition 1095) for release/10.0.1xx-sr6 has been failing with Gradle network errors on Windows:

Permission denied: getsockopt
Could not GET https://repo.maven.apache.org/maven2/...
gradlew.bat exited with code 1

Build 2954057 failed even though it included the Gradle cache fix from PR #35016. The cache step was added to provision.yml, but the official Pack job uses pack.yml directly — which never calls provision.yml.

Fix

Add the same cache-gradle.yml template call to eng/pipelines/common/pack.yml before the pack step, matching the pattern already used in provision.yml.

Impact

This unblocks the 10.0.60 official build by ensuring the Gradle dependency cache is warm before the Pack step invokes Gradle on Windows agents with network isolation.

The cache-gradle.yml template was added to provision.yml in PR #35016,
but the official build's Pack job uses pack.yml directly which never
calls provision.yml. This caused the 10.0.60 official build to fail
with 'Permission denied: getsockopt' when Gradle tried to download
Maven dependencies on Windows agents with network isolation.

Adding the same Gradle cache template to pack.yml ensures the cache
is warm before the pack step invokes Gradle.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 20, 2026 20:03
@github-actions

github-actions Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35049

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35049"

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Gradle dependency caching to the shared pack.yml pipeline template so official pack jobs warm/restore the Gradle cache before invoking the pack step (helping avoid transient Maven/Gradle network failures on Windows agents).

Changes:

  • Invoke the existing shared cache-gradle.yml template from eng/pipelines/common/pack.yml before the pack build runs.

The Windows cache was empty (cache miss) because it had never been
populated. With network isolation blocking repo.maven.apache.org,
Windows builds can't download Gradle dependencies on first run.

Since Gradle dependencies are platform-independent Java JARs, add
a fallback restore key without Agent.OS so Windows can restore from
the macOS-populated cache.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread eng/pipelines/common/cache-gradle.yml Outdated
Comment on lines +40 to +41
"gradle" | "v1" | "$(Agent.OS)"
"gradle" | "v1"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this share the cache between all OSs? I don't know if their cache is cross-platform.

@PureWeen

PureWeen commented Apr 21, 2026

Copy link
Copy Markdown
Member Author

Replying to @jonathanpeppers' question on the cross-OS fallback key ("gradle" | "v1" on line 41):

Short answer: The Gradle dependency cache is mostly cross-platform, but not entirely. The fallback is a best-effort warm start, not a guaranteed full restore.

What works cross-OS:

  • Downloaded JARs, POMs, AARs in caches/modules-2/files-2.1/ — these are byte-identical across platforms (kotlin-stdlib, AndroidX, Gradle plugins, etc.). This is the bulk of the 1.2 GB cache.
  • Gradle's dependency cache uses relative paths internally, so file location differences aren't an issue.

What doesn't work cross-OS:

  • aapt2 uses OS-specific Maven classifiers (aapt2-*-osx.jar vs aapt2-*-windows.jar). Gradle resolves by classifier, so it would not try to use the macOS binary on Windows — it would attempt to download the Windows variant (which would fail under CFSClean anyway).
  • caches/transforms-*/ and caches/jars-*/ (script caches) — Gradle gracefully regenerates these on cache miss, so stale entries don't cause failures.
  • .lock files — Gradle handles stale locks gracefully.

Net effect: The cross-OS fallback gives Windows a warm start with ~95% of the dependencies pre-cached (all the pure Java artifacts). OS-specific artifacts (aapt2) would still need to be resolved. This is strictly better than a complete cache miss, and Gradle handles the incompatible entries gracefully (cache miss → regenerate, not crash).

That said — in practice, this build currently only has a Pack macOS job (no Pack Windows), so the cross-OS fallback isn't actually being exercised today. If a Windows Pack job is added in the future and CFSClean is still blocking Maven Central, the fallback alone won't be sufficient (aapt2 download would still fail). A Windows-specific cache would need to be populated separately, or aapt2's Maven domain would need to be allowlisted.

Happy to remove the cross-OS key if you think the partial-restore behavior is more confusing than helpful. The OS-specific keys ("gradle" | "v1" | "$(Agent.OS)") are the ones doing the real work.


Cross-checked with Sonnet 4.6, Codex 5.3, and Opus 4.6 — all agree the dependency artifacts are portable but OS-specific binaries (aapt2) are not. Gradle self-heals on incompatible cache entries rather than crashing.

Comment on lines +88 to +91
# Cache Gradle downloads to avoid transient network failures during Android binding builds
- template: /eng/pipelines/common/cache-gradle.yml@self
parameters:
checkoutDirectory: ${{ parameters.checkoutDirectory }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The general idea of restoring the cache here would improve this pipeline, for sure.

The OS-independent fallback key could restore macOS-cached aapt2
native binaries on Windows, which are not cross-platform compatible.
Keep only OS-specific restore keys.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@PureWeen PureWeen merged commit f880bab into release/10.0.1xx-sr6 Apr 21, 2026
9 of 37 checks passed
@PureWeen PureWeen deleted the fix/gradle-cache-pack-yml branch April 21, 2026 19:56
@PureWeen

Copy link
Copy Markdown
Member Author

/backport to main

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to main (link to workflow run)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants