build: vendor secrets-gradle-plugin with an Isolated-Projects fix - #6595
build: vendor secrets-gradle-plugin with an Isolated-Projects fix#6595jamesarich wants to merge 1 commit into
Conversation
Google's secrets-gradle-plugin 2.0.1 reads properties via project.rootProject.file(), which Isolated Projects forbids — Gradle 9.7+ fails every androidApp build over it. Upstream is dormant (no release since 2022) and the one-line fix has sat unmerged in google/secrets-gradle-plugin#104 since March, so waiting is not a strategy and this blocks the Gradle 9.7 bump. Vendor the plugin (Apache-2.0, ~180 lines) into build-logic as meshtastic.android.secrets, byte-identical except: - property files resolve via isolated.rootProject (the IP-safe idiom) - legacy Variant API helpers dropped (classes removed in AGP 9; dead paths) - buildConfigFields made null-safe (nullable since AGP 9) The vendored files keep Google's license header and are excluded from spotless/detekt so they stay diffable against upstream. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe build replaces the external Google Secrets plugin alias with a vendored convention plugin. The plugin loads property files and injects values into Android variant ChangesAndroid secrets integration
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant AndroidApp
participant SecretsPlugin
participant RootProject
participant AndroidVariant
participant BuildConfig
participant Manifest
AndroidApp->>SecretsPlugin: apply meshtastic.android.secrets
SecretsPlugin->>RootProject: load configured property files
SecretsPlugin->>AndroidVariant: inject variant properties
AndroidVariant->>BuildConfig: write string fields
AndroidVariant->>Manifest: populate placeholders
🚥 Pre-merge checks | ✅ 6✅ Passed checks (6 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@build-logic/convention/build.gradle.kts`:
- Around line 81-82: Remove the secrets_gradle_plugin exclusion from Spotless at
build-logic/convention/build.gradle.kts:81-82 and from Detekt at
build-logic/convention/build.gradle.kts:106-107, then update the vendored Kotlin
sources under secrets_gradle_plugin so both quality checks pass.
In
`@build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPluginExtension.kt`:
- Line 31: Update the ignoreList initializer in SecretsPluginExtension so each
extension receives an independent mutable copy by using
defaultIgnoreList.toMutableList(), preventing changes in one plugin application
from affecting others.
- Line 17: Move the vendored Secrets Gradle Plugin classes from the Google
package to the org.meshtastic package: update the package declarations in
SecretsPluginExtension.kt, Extensions.kt, and SecretsPlugin.kt, and relocate
their source directories accordingly. In
build-logic/convention/build.gradle.kts, update the androidSecrets plugin
registration implementationClass to reference the new org.meshtastic
SecretsPlugin path.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: cc349f16-90d4-46f6-8b13-db8faff75c89
📒 Files selected for processing (7)
androidApp/build.gradle.ktsbuild-logic/convention/build.gradle.ktsbuild-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/Extensions.ktbuild-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPlugin.ktbuild-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPluginExtension.ktbuild.gradle.ktsgradle/libs.versions.toml
💤 Files with no reviewable changes (1)
- build.gradle.kts
| // secrets_gradle_plugin is vendored third-party code (Apache-2.0) keeping Google's header. | ||
| targetExclude("**/build/**/*.kt", "**/secrets_gradle_plugin/**") |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== repo files matching build-logic/convention/build.gradle.kts =="
git ls-files | grep -F 'build-logic/convention/build.gradle.kts' || true
echo "== relevant lines =="
if [ -f build-logic/convention/build.gradle.kts ]; then
nl -ba build-logic/convention/build.gradle.kts | sed -n '65,115p'
fi
echo "== secrets_gradle_plugin locations =="
git ls-files | grep -E 'secrets_gradle_plugin' || true
echo "== spotless/detekt config references =="
rg -n "targetExclude|secrets_gradle_plugin|dev\\.detekt\\.gradle\\.Detekt|tasks\\.withType<dev\\.detekt\\.gradle\\.Detekt>" -S .Repository: meshtastic/Meshtastic-Android
Length of output: 334
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== relevant lines =="
if [ -f build-logic/convention/build.gradle.kts ]; then
sed -n '65,115p' build-logic/convention/build.gradle.kts | awk '{printf "%7d %s\n", NR+64, $0}'
fi
echo "== secrets_gradle_plugin locations =="
git ls-files | grep -E 'secrets_gradle_plugin' || true
echo "== spotless/detekt config references =="
grep -RInE "targetExclude|secrets_gradle_plugin|dev\.detekt\.gradle\.Detekt|tasks\.withType<dev\.detekt\.gradle\.Detekt>" . || true
echo "== changed files/stat =="
git diff --name-status -- build-logic/convention/build.gradle.kts || true
git status --shortRepository: meshtastic/Meshtastic-Android
Length of output: 4598
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== vendored files =="
for f in \
build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/Extensions.kt \
build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPlugin.kt \
build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPluginExtension.kt
do
echo "--- $f ---"
head -60 "$f"
done
echo "== build-root spotless/detekt files =="
git ls-files ':!build-logic' | \
xargs -r grep -l -E 'spotless|detekt|targetExclude|secrets_gradle_plugin' | \
head -50Repository: meshtastic/Meshtastic-Android
Length of output: 10594
Keep vendored Kotlin sources in the quality gates.
Remove the Spotless and Detekt exclusions for secrets_gradle_plugin, then update these Kotlin sources until both checks pass.
build-logic/convention/build.gradle.kts#L82: remove the Spotless exclusion for**/secrets_gradle_plugin/**.build-logic/convention/build.gradle.kts#L107: remove the Detekt exclusion for**/secrets_gradle_plugin/**.
📍 Affects 1 file
build-logic/convention/build.gradle.kts#L81-L82(this comment)build-logic/convention/build.gradle.kts#L106-L107
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@build-logic/convention/build.gradle.kts` around lines 81 - 82, Remove the
secrets_gradle_plugin exclusion from Spotless at
build-logic/convention/build.gradle.kts:81-82 and from Detekt at
build-logic/convention/build.gradle.kts:106-107, then update the vendored Kotlin
sources under secrets_gradle_plugin so both quality checks pass.
Source: Coding guidelines
| // | ||
| // Vendored unmodified from google/secrets-gradle-plugin v2.0.1 — see SecretsPlugin.kt for why. | ||
|
|
||
| package com.google.android.libraries.mapsplatform.secrets_gradle_plugin |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== candidate files =="
git ls-files 'build-logic/convention/src/main/kotlin/**/*' | rg 'Secrets|Extensions|build.gradle.kts$|gradle/libs.versions.toml$' || true
echo "== relevant package declarations and implementation refs =="
for f in \
build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPluginExtension.kt \
build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/Extensions.kt \
build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPlugin.kt \
build-logic/convention/build.gradle.kts
do
if [ -f "$f" ]; then
echo "--- $f"
nl -ba "$f" | sed -n '1,220p'
else
echo "missing: $f"
fi
done
echo "== build-logic convention source package usage search =="
rg -n "package (com\.google|org\.meshtastic|.*secrets_gradle_plugin|.*androidSecrets|implementationClass|meshtastic\.android\.secrets)" build-logic/convention src build.gradle.kts settings.gradle.kts || true
echo "== kotlin imports/usages of vendored classes =="
rg -n "com\.google\.android\.libraries\.mapsplatform\.secrets_gradle_plugin|SecretsPlugin|SecretsPluginExtension|androidSecrets" . || trueRepository: meshtastic/Meshtastic-Android
Length of output: 875
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== candidate line content =="
for f in \
build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPluginExtension.kt \
build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/Extensions.kt \
build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPlugin.kt \
build-logic/convention/build.gradle.kts
do
if [ -f "$f" ]; then
echo "--- $f"
grep -nE '^(package|register\("androidSecrets"\) \{|id\s*=|implementationClass\s*=)' "$f" || true
else
echo "missing: $f"
fi
done
echo "== build.gradle.kts relevant section =="
grep -nE 'androidSecrets|implementationClass|com\.google\.android\.libraries\.mapsplatform\.secrets_gradle_plugin|meshtastic\.android\.secrets' build-logic/convention/build.gradle.kts || true
echo "== broader usage/import search =="
rg -n "com\.google\.android\.libraries\.mapsplatform\.secrets_gradle_plugin|SecretsPlugin|SecretsPluginExtension|androidSecrets|meshtastic\.android\.secrets" . || trueRepository: meshtastic/Meshtastic-Android
Length of output: 5152
Move the vendored Secrets Gradle Plugin classes to an org.meshtastic.* package.
The new Kotlin files still declare com.google.android.libraries.mapsplatform.secrets_gradle_plugin, and the androidSecrets plugin registration points to that Google package. Relocate the sources with the package declarations, then update one implementationClass entry in build-logic/convention/build.gradle.kts to the new SecretsPlugin path.
📍 Affects 4 files
build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPluginExtension.kt#L17-L17(this comment)build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/Extensions.kt#L25-L25build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPlugin.kt#L23-L23build-logic/convention/build.gradle.kts#L135-L139
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPluginExtension.kt`
at line 17, Move the vendored Secrets Gradle Plugin classes from the Google
package to the org.meshtastic package: update the package declarations in
SecretsPluginExtension.kt, Extensions.kt, and SecretsPlugin.kt, and relocate
their source directories accordingly. In
build-logic/convention/build.gradle.kts, update the androidSecrets plugin
registration implementationClass to reference the new org.meshtastic
SecretsPlugin path.
Source: Coding guidelines
| /** | ||
| * A list of keys this plugin should ignore and not inject. Defaults to $defaultIgnoreList | ||
| */ | ||
| var ignoreList: MutableList<String> = defaultIgnoreList |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Create an independent ignore list for each extension.
Line 31 assigns the shared mutable defaultIgnoreList to every plugin application. If one project changes secrets.ignoreList, later projects receive the changed list. Initialize this value with defaultIgnoreList.toMutableList().
Proposed fix
- var ignoreList: MutableList<String> = defaultIgnoreList
+ var ignoreList: MutableList<String> = defaultIgnoreList.toMutableList()📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| var ignoreList: MutableList<String> = defaultIgnoreList | |
| var ignoreList: MutableList<String> = defaultIgnoreList.toMutableList() |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@build-logic/convention/src/main/kotlin/com/google/android/libraries/mapsplatform/secrets_gradle_plugin/SecretsPluginExtension.kt`
at line 31, Update the ignoreList initializer in SecretsPluginExtension so each
extension receives an independent mutable copy by using
defaultIgnoreList.toMutableList(), preventing changes in one plugin application
from affecting others.
Why
Gradle 9.7.0 (Renovate #6589) hard-fails every
androidAppbuild: Google's secrets-gradle-plugin 2.0.1 reads its properties files throughproject.rootProject.file(), which Isolated Projects forbids and 9.7+ enforces. There is no upstream escape hatch — 2.0.1 is the latest release (Feb 2022), the tagged 2.0.2 was never published, and the one-line fix has sat unmerged in google/secrets-gradle-plugin#104 since March on a repo with no release in four years. This unblocks #6589 without giving up Isolated Projects.🛠️ Improvements
build-logicasmeshtastic.android.secrets, byte-identical to upstream v2.0.1 except:isolated.rootProject— the IP-safe idiom the rest ofbuild-logicalready usesAppExtension/InternalBaseVariant) dropped — dead code paths here, and the classes no longer exist in AGP 9buildConfigFieldsmade null-safe (nullable since AGP 9)🧹 Cleanup
secretsplugin from the version catalog and the rootapply falseline;androidAppnow appliesmeshtastic.android.secrets.Testing Performed
spotlessApply spotlessCheck detekt assembleDebug test allTests— green (the soleallTestsfailure isBleAddressLoggingTest's scope guard, which pre-exists on a cleanmaintree when run from a.claude/worktreescheckout and is unrelated; tracked separately).googleDebugmanifest carriescom.google.android.geo.API_KEYfromlocal.properties, andBuildConfigcarriesMAPS_API_KEY/datadogApplicationId/datadogClientToken.:androidAppconfiguration passes with this plugin where 2.0.1 failed.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes