Skip to content

Update to Gradle 9.5.0 - #3612

Open
rvandermeulen wants to merge 8 commits into
mozilla:mainfrom
rvandermeulen:rust-android-gradle-0.10
Open

Update to Gradle 9.5.0#3612
rvandermeulen wants to merge 8 commits into
mozilla:mainfrom
rvandermeulen:rust-android-gradle-0.10

Conversation

@rvandermeulen

@rvandermeulen rvandermeulen commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Updates Gradle from 8.14.3 to 9.5.0, and moves off the APIs that AGP 9 removes while staying on AGP 8.

9.5.0 is as far as we can go for now: Gradle 9.6.0 removes org.gradle.api.problems.internal.InternalProblems, which AGP 8.x's com.android.internal.library depends on, and 8.13.2 is the last AGP 8 release. Going further requires the AGP 9 upgrade, which is deliberately not part of this.

Breaking change for consumers of the Glean Gradle plugin. Gradle 9 removed Project.exec(), which JetBrains' gradle-python-envs calls internally. That plugin is unmaintained, 0.0.31 is its only recent release, and there is no Gradle 9 compatible version, so the Miniconda bootstrap is gone. The plugin now always creates a virtual environment with the standard library venv module, which is the path that already existed for offline builds. Applications need a Python 3.9 or later interpreter on the PATH, or GLEAN_PYTHON set, unless they supply their own environment via ext.gleanPythonEnvDir. They no longer need to apply com.jetbrains.python.envs themselves.

Note that on Debian and Ubuntu this also means python3-venv has to be installed, since a bare python3 there has no ensurepip. That is what the first commit does for our own Android CI jobs, and downstream consumers building on similar images will need the same. mozilla-central already sets gleanPythonEnvDir everywhere, so it is unaffected.

The rest of the stack prepares for AGP 9. Registering the uniffi bindings through androidComponents also let the lint baseline go away: the generated directory was being added to the Kotlin source set by hand, which is why lint treated the bindings as ordinary source and needed three NewApi suppressions.

Along the way this fixes three latent missing task dependencies, all of which had been masked by warm build directories and scheduling that happened to work:

  • copyGleanNative could copy the native libraries before Cargo had built them
  • the metrics generating tasks could run before the Python environment existed
  • the Maven artifact check ran before publish, found nothing, and passed

The last one is worth a second look: bin/check-artifact.sh treated "no artifact found" as success, so the release check in module-build would have gone green while verifying nothing. It now fails instead of skipping whenever it has nothing to inspect.

These were all found while trying to enable the configuration cache, which is not part of this PR. That turned up a problem outside this repo: with the cache on, a consumer task with a correct dependsOn on rust-android-gradle's cargo task still observes an empty output directory on a cold build, which suggests the plugin does not declare rustJniLibs in a way Gradle's parallel scheduler respects. The compatibility fixes are kept here since they are improvements in their own right, and enabling the cache can be revisited once that is sorted out.

Verified on a clean tree with a cold Python environment: full build, all three unit test variants, detekt, ktlint, offline builds, publishing, and the module-build and android-build CI task sequences.

Not covered: Windows, where the interpreter path changed from the conda layout to Scripts/python.

@rvandermeulen
rvandermeulen requested a review from a team as a code owner August 27, 2026 17:25
@rvandermeulen
rvandermeulen requested review from chutten and removed request for a team August 27, 2026 17:25
@rvandermeulen
rvandermeulen force-pushed the rust-android-gradle-0.10 branch from 6a4d43c to 6963f60 Compare August 27, 2026 17:25
@rvandermeulen
rvandermeulen removed the request for review from chutten August 27, 2026 17:49
@rvandermeulen
rvandermeulen marked this pull request as draft August 27, 2026 17:49
@rvandermeulen
rvandermeulen force-pushed the rust-android-gradle-0.10 branch 2 times, most recently from ef270e8 to f82a189 Compare August 27, 2026 19:14
@rvandermeulen
rvandermeulen marked this pull request as ready for review August 27, 2026 19:41
@rvandermeulen
rvandermeulen requested a review from badboy August 27, 2026 19:41
The Glean Gradle plugin is about to create its own virtual environment instead
of downloading a Miniconda, and cimg/android ships python3 without ensurepip.
The Python jobs already install this.
Gradle 9 removed Project.exec(). The generateUniffiBindings task now uses an
injected ExecOperations, and the Miniconda bootstrap is gone: JetBrains'
gradle-python-envs calls the removed API, is unmaintained, and has no Gradle 9
compatible release, so the plugin always uses the stdlib venv path that already
existed for offline builds.

Two other behavior changes: file() in the subprojects lint block now resolves
against each subproject rather than the root, so the baseline is anchored with
rootProject.file(); and 9.5 fails the build on plugin validation problems that
were previously warnings.

BREAKING CHANGE: applications applying the Glean Gradle plugin now need a
Python 3.9 or later interpreter on the PATH, or GLEAN_PYTHON set, unless they
supply their own environment via ext.gleanPythonEnvDir.
Switch the SDK version DSL to compileSdk/minSdk/targetSdk, drop a
libraryVariants block that only assigned unused locals, register the uniffi
bindings through androidComponents and addGeneratedSourceDirectory instead of
registerJavaGeneratingTask, and wire the JNI lib folder tasks to cargoBuild by
name.

The generated directory was also being added to the Kotlin source set by hand,
which is what made lint treat the bindings as ordinary source. AGP owns that
directory now and skips it, so the lint baseline has nothing left to suppress
and is removed.
AGP 8 still honours the properties whose defaults change in 9, so turn them on
now and absorb the behavior changes here instead of all at once during the
upgrade. The two that are left alone are documented inline.

Also switch to proguard-android-optimize.txt, which 9 requires, replace the
pre-AndroidX instrumentation runner, and stop using Gradle's internal
ArtifactAttributes now that a public equivalent exists.
ndkVersion was using the space-assignment syntax, which Gradle 10 removes.
Detekt's input and xml.enabled properties have been deprecated in favour of
source and xml.required since 1.21.

The remaining Gradle 10 deprecation warnings come from AGP's own dependency
declarations, not from this build.
copyGleanNative can copy the native libraries before Cargo has built them, the
metrics generating tasks can run before the Glean Python environment exists,
since finalizedBy only orders installGleanParser against preBuild, and the
Maven artifact check can run before publish. Each happens to work today only
because the outputs are usually left over from an earlier build, or because
the scheduler picks a workable order.

The check script also treated a missing artifact as success, so it could pass
while inspecting nothing. Make it fail instead of skipping.
The task action reached back into the project for the native library pattern,
the working directory and the uniffi config. Resolving them up front keeps the
action independent of the project, which the configuration cache requires.

The missing-library check was also unreachable, because singleFile throws
before the null test, hiding a clear error behind a generic one.
@rvandermeulen
rvandermeulen force-pushed the rust-android-gradle-0.10 branch from f82a189 to 541e12f Compare August 27, 2026 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant