Skip to content

fix(android): auto-detect the Android SDK when fresh worktrees lack local.properties#101273

Merged
steipete merged 1 commit into
mainfrom
fix/android-gradle-sdk-worktree-autodetect
Jul 7, 2026
Merged

fix(android): auto-detect the Android SDK when fresh worktrees lack local.properties#101273
steipete merged 1 commit into
mainfrom
fix/android-gradle-sdk-worktree-autodetect

Conversation

@steipete

@steipete steipete commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes an issue where developers running any SDK-dependent Android lane (pnpm android:test, android:assemble, android:install, android:run) from a fresh git worktree would hit SDK location not found even though an Android SDK is installed. apps/android/local.properties is gitignored, so new worktrees never carry it, and nothing else names the SDK unless ANDROID_HOME/ANDROID_SDK_ROOT happens to be exported. The ktlint lanes (android:format/android:lint) mask the gap because they never touch the SDK.

Why This Change Was Made

scripts/run-android-gradle.mjs now resolves the SDK before spawning Gradle: explicit ANDROID_HOME/ANDROID_SDK_ROOT and an existing local.properties keep full precedence, and only when neither names an SDK does the wrapper fall back to the Android Studio default install path (~/Library/Android/sdk on macOS, ~/Android/Sdk elsewhere) — and only if that directory actually exists. No files are written; the fallback is passed as ANDROID_HOME to the spawned process only. CI is unaffected since it exports ANDROID_HOME explicitly.

User Impact

Android Gradle lanes work out of the box in fresh worktrees and clones on machines with a default-located SDK, with no manual local.properties setup. Existing explicit configuration behaves exactly as before.

Evidence

Repro and fix on a fresh worktree (no local.properties, no SDK env vars):

  • Before: pnpm android:testSDK location not found. Define a valid SDK location with an ANDROID_HOME environment variable or by setting the sdk.dir path in your project's local properties file... (BUILD FAILED in 616ms)
  • After: env -u ANDROID_HOME -u ANDROID_SDK_ROOT pnpm android:testBUILD SUCCESSFUL (:app:testPlayDebugUnitTest)

Focused tests: test/scripts/run-android-gradle.test.ts — 8 passed, including 4 new resolveAndroidSdkEnv cases covering env-var precedence, local.properties precedence, per-platform default fallback, and missing-SDK passthrough.

@openclaw-barnacle openclaw-barnacle Bot added scripts Repository scripts size: S maintainer Maintainer-authored PR labels Jul 7, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d46241327e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (!existsSync(defaultSdkDir)) {
return env;
}
return { ...env, ANDROID_HOME: defaultSdkDir };

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.

P2 Badge Include platform-tools in fallback env

When this fallback is used for pnpm android:run/android:run:third-party with no SDK env vars and no adb on the shell PATH, Gradle can now install successfully but the post command is still spawned as bare adb from package.json:1498-1499. Adding only ANDROID_HOME here does not make adb discoverable by spawn, so the run lane still exits with ENOENT in the fresh-worktree/default-SDK case this change is trying to cover; add <defaultSdkDir>/platform-tools to PATH or resolve the post command from the SDK.

Useful? React with 👍 / 👎.

@clawsweeper

clawsweeper Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 6, 2026, 10:42 PM ET / 02:42 UTC.

Summary
The PR adds Android SDK discovery to scripts/run-android-gradle.mjs and unit coverage for env-var, local.properties, default-path, and missing-SDK cases.

PR surface: Tests +53, Other +27. Total +80 across 2 files.

Reproducibility: yes. By source inspection, android:run calls the wrapper with a post-command adb, while the PR's fallback env adds only ANDROID_HOME; on a default-SDK machine without platform-tools already on PATH, the post command still fails with ENOENT.

Review metrics: none identified.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦪 silver shellfish
Patch quality: 🦪 silver shellfish
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Add platform-tools to PATH or resolve the post-command adb from the discovered default SDK when fallback is used.
  • [P1] Add focused coverage for the default-SDK post-command path.
  • [P1] Update the PR body with redacted pnpm android:run terminal output or a recording after the fix; if automatic review does not rerun, ask a maintainer for @clawsweeper re-review.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR body includes copied before/after output for android:test, but not for the stated android:run path that still has an adb discovery gap; after fixing it, add redacted terminal output or a recording and update the PR body to trigger re-review.

Risk before merge

  • [P2] Real behavior proof covers android:test only; it does not demonstrate the stated android:run path after the fallback.

Maintainer options:

  1. Decide the mitigation before merge
    Keep the Gradle-side SDK fallback, but when the wrapper discovers a default SDK, also expose or resolve platform-tools/adb for post commands and prove both test and run lanes.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] Author or maintainer follow-up is needed because the PR has a narrow code blocker plus contributor-side run-lane proof that automation cannot supply for the original setup.

Security
Cleared: The diff only changes a local Android wrapper and tests, with no new dependencies, downloads, secret handling, workflow permissions, or package-resolution changes.

Review findings

  • [P2] Put fallback platform-tools on PATH — scripts/run-android-gradle.mjs:65
Review details

Best possible solution:

Keep the Gradle-side SDK fallback, but when the wrapper discovers a default SDK, also expose or resolve platform-tools/adb for post commands and prove both test and run lanes.

Do we have a high-confidence way to reproduce the issue?

Yes. By source inspection, android:run calls the wrapper with a post-command adb, while the PR's fallback env adds only ANDROID_HOME; on a default-SDK machine without platform-tools already on PATH, the post command still fails with ENOENT.

Is this the best way to solve the issue?

No. The wrapper is the right layer for the SDK fallback, but the best fix must also make the discovered SDK's adb available to post commands and cover that path with proof.

Full review comments:

  • [P2] Put fallback platform-tools on PATH — scripts/run-android-gradle.mjs:65
    This fallback returns an env with only ANDROID_HOME, but the wrapper reuses that env for the post command and package.json runs bare adb for android:run/android:run:third-party. In the fresh-worktree/default-SDK case where platform-tools is not already on PATH, Gradle can install successfully and the launch step still fails with ENOENT, so the run lane remains broken; add <defaultSdkDir>/platform-tools to PATH or resolve the post-command adb from the SDK.
    Confidence: 0.92

Overall correctness: patch is incorrect
Overall confidence: 0.9

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 632efa2d7343.

Label changes

Label changes:

  • add P2: This is a normal-priority Android developer workflow bug with limited blast radius to local Android script lanes.
  • add rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦪 silver shellfish.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body includes copied before/after output for android:test, but not for the stated android:run path that still has an adb discovery gap; after fixing it, add redacted terminal output or a recording and update the PR body to trigger re-review.

Label justifications:

  • P2: This is a normal-priority Android developer workflow bug with limited blast radius to local Android script lanes.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body includes copied before/after output for android:test, but not for the stated android:run path that still has an adb discovery gap; after fixing it, add redacted terminal output or a recording and update the PR body to trigger re-review.
Evidence reviewed

PR surface:

Tests +53, Other +27. Total +80 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 0 0 0 0
Tests 1 53 0 +53
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 1 31 4 +27
Total 2 84 4 +80

What I checked:

  • Repository policy applied: Read the full 287-line root policy plus scoped scripts/AGENTS.md, test/AGENTS.md, and apps/android/AGENTS.md; the read-beyond-diff and script-wrapper review guidance affected this verdict. (AGENTS.md:1, 632efa2d7343)
  • Fallback env omits platform-tools: At the reviewed head, resolveAndroidSdkEnv returns only ANDROID_HOME for the default SDK fallback and does not update PATH or resolve adb. (scripts/run-android-gradle.mjs:65, 4fae5be962a3)
  • Post command inherits the same incomplete env: The wrapper passes that env to the post command as well, so a bare post-command executable still depends on the caller's original PATH. (scripts/run-android-gradle.mjs:113, 4fae5be962a3)
  • Run lanes use bare adb: Current main defines android:run and android:run:third-party as wrapper calls with a post-command adb shell am start, so adb must be discoverable after the fallback. (package.json:1499, 632efa2d7343)
  • Documented user flow includes android:run: The Android README tells developers to install and launch with pnpm android:install and pnpm android:run, making the run lane part of the reviewed behavior surface. (apps/android/README.md:184, 632efa2d7343)
  • Prior review comment matches current head: A Codex review comment on the current head already flagged the same line for not exposing <defaultSdkDir>/platform-tools to the adb post command. (scripts/run-android-gradle.mjs:65, 4fae5be962a3)

Likely related people:

  • steipete: The current wrapper/package/docs behavior was introduced in merged PR fix(ci): stabilize Windows startup fallback tests #101223, whose central commits and blame for the Android wrapper path point to this login; the same person authored this focused follow-up PR. (role: recent area contributor; confidence: high; commits: dbba3d2a8ed2, 4fae5be962a3; files: scripts/run-android-gradle.mjs, package.json, apps/android/README.md)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels Jul 7, 2026
@steipete
steipete force-pushed the fix/android-gradle-sdk-worktree-autodetect branch from 4fae5be to d26d771 Compare July 7, 2026 09:09
@steipete
steipete merged commit bc5a82b into main Jul 7, 2026
86 checks passed
@steipete
steipete deleted the fix/android-gradle-sdk-worktree-autodetect branch July 7, 2026 09:22
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 8, 2026
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR P2 Normal backlog priority with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. scripts Repository scripts size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant