Skip to content

Add cloud-setup.sh bootstrap script for Claude Code sandbox#144

Merged
jwoglom merged 3 commits into
devfrom
claude/fix-android-sdk-access-ABCBy
Apr 25, 2026
Merged

Add cloud-setup.sh bootstrap script for Claude Code sandbox#144
jwoglom merged 3 commits into
devfrom
claude/fix-android-sdk-access-ABCBy

Conversation

@jwoglom

@jwoglom jwoglom commented Apr 25, 2026

Copy link
Copy Markdown
Owner

Summary

Automates Android SDK and Robolectric setup for Claude Code cloud sandbox sessions by introducing a new bootstrap script (.claude/cloud-setup.sh) and updating documentation to reflect the automated setup flow.

Key Changes

  • New bootstrap script (.claude/cloud-setup.sh): Idempotent shell script that:

    • Downloads and installs Android SDK build-tools 35.0.0 and platforms android-35/36 with retry logic
    • Generates required package.xml metadata files for AGP recognition
    • Creates local.properties with correct SDK path
    • Pre-downloads Robolectric instrumented JARs (SDK 14 and 15) to ~/.robolectric/
    • Exports ANDROID_HOME, ANDROID_SDK_ROOT, and CI=true to both $CLAUDE_ENV_FILE and ~/.bashrc for persistence
    • Validates environment variables against session-level drift
    • Warms Gradle dependency cache with version-gated sentinel to avoid redundant runs
  • Updated AGENTS.md documentation:

    • Replaced 130+ lines of manual setup instructions with concise post-bootstrap summary
    • Removed detailed proxy configuration, manual curl/unzip steps, and package.xml creation instructions
    • Added troubleshooting section for SDK detection issues with recovery instructions
    • Simplified "Running builds and tests" to just the command examples (no env exports needed)

Implementation Details

  • Retry logic: Download failures trigger a 10-second delay and one automatic retry before failing
  • Idempotency: All operations check for existing files/directories and skip if already present; env var writes deduplicate exact lines to avoid accumulation
  • Belt-and-suspenders env export: Writes to both $CLAUDE_ENV_FILE (Claude's mechanism) and ~/.bashrc to handle cases where platform-level session env overrides one or the other
  • Sanity checks: Post-export validation warns if running env doesn't match installed SDK path, helping diagnose session-level env drift
  • Dependency cache warming: Gated by a sentinel file tracking CACHE_VERSION and SDK_ROOT to invalidate cache when SDK components change

https://claude.ai/code/session_01PBpz6hivdEDaPWDqkx8vDf

claude added 3 commits April 25, 2026 20:53
Captures the Android SDK + Robolectric bootstrap script the Claude Code
cloud sandbox runs, so it lives in version control alongside the code it
sets up. Fixes a session-env drift issue where ANDROID_HOME was sometimes
exported as the literal string "$REPO_ROOT/.android-sdk" (REPO_ROOT
unset), leaving agents convinced the SDK was missing:

- Writes ANDROID_HOME, ANDROID_SDK_ROOT, and CI=true to both
  $CLAUDE_ENV_FILE and ~/.bashrc, stripping prior exports first so the
  script is idempotent.
- Adds a sanity check that warns loudly when the running env doesn't
  match the installed SDK path, so future drift surfaces immediately
  instead of silently misleading agents.
The 130-line walkthrough of manual proxy config, curl-based SDK installs,
hand-written package.xml files, and Robolectric jar fetches was telling
agents to redo work that .claude/cloud-setup.sh now does automatically
before the session starts. Following those steps either succeeded
redundantly or failed partway and convinced agents the SDK was
unavailable.

Replace it with a short status section pointing at .claude/cloud-setup.sh,
and add a recovery hint for the literal "$REPO_ROOT/.android-sdk" env
drift case. Other cloud sandbox sections (Cursor Cloud) are left
unchanged.
Three steps still did work on every run even when nothing changed:
- local.properties was rewritten unconditionally
- env-var lines used sed-delete-then-append every run
- ./gradlew dependencies (multi-minute) ran every time

Now each step short-circuits when its target is already in the desired
state: local.properties is only rewritten if missing or content-mismatched,
env-var writes skip when the exact `export KEY=VALUE` line already exists,
and the gradle dependency warm-up is gated on a sentinel file
(.android-sdk/.gradle-deps-warmed) keyed on a CACHE_VERSION + SDK path
token. A re-run with everything in place now logs only a single
"skipping" line.
@jwoglom jwoglom merged commit 98e9a4d into dev Apr 25, 2026
1 check passed
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.

2 participants