agentleFS
nikzlabsnikzlabs/shipit/.agents/skills/android-build/SKILL.md

android-build

Skill9 starsChanged 17 days agoApache-2.0View on GitHub

Build, test, debug, and preview Android apps inside a ShipIt session. Load when a task touches an Android/Gradle project (Kotlin/Java, build.gradle(.kts), AndroidManifest.xml, res/ layouts, Compose UI). Covers the baked toolchain (JDK/SDK/Gradle), the build → lint → snapshot-test loop, reading snapshot PNG diffs, on-demand SDK installs, and the emulator-as-Compose-service for a live device over adb.

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

6 rules. About 0 are common, 2 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Run Gradle from the dir with settings.gradle(.kts) + gradlew.

    line 19
  2. Very specific:

    Prefer the committed ./gradlew (pins the Gradle version).

    line 38
  3. Very specific:

    If the repo has no snapshot tests and you're changing UI, adding a small one for the affected screen is how you make the change verifiable.

    line 65
  4. Very specific:

    Don't add Android fields to shipit.yaml — the toolchain is ambient.

    line 95
  5. Distinctive:

    Don't reach for the emulator to check a layout — a snapshot test is faster, deterministic, and needs no KVM.

    line 97
  6. Distinctive:

    Don't run repo-root Gradle in a monorepo — scope to the Android module's dir so the web build is untouched.

    line 99

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Android build, test & preview

The Android toolchain is baked into every session container — JDK 17, the Android SDK, and Gradle 8.7 are always on PATH. A repo declares nothing to build (no shipit.yaml Android fields). Full command reference and env paths: /shipit-docs/android.md — read it for anything not covered here.

There are two surfaces: headless (build/lint/test/snapshot — this container, no device) and a running app (an emulator Compose service over adb).

Find the Gradle root first

Run Gradle from the dir with settings.gradle(.kts) + gradlew. In a monorepo (web app + an android/ module) just cd into it. If there are several Android app modules, flavors, or Gradle roots, list them and pick — or ask the user which to target. Don't guess off stray .gradle files.

cd android
./gradlew projects        # modules
./gradlew tasks --all     # available tasks (snapshot task names vary by library/variant)

The core loop: build → lint → snapshot

./gradlew assembleDebug   # did I break the build?
./gradlew lint            # manifest/resource/accessibility + edge-to-edge/inset checks
./gradlew test            # JVM unit tests (+ Robolectric if used)

Prefer the committed ./gradlew (pins the Gradle version). It downloads its dist once per fresh container; run the baked gradle to skip that if needed.

Reading the output is most of debugging — compile errors, lint findings, and test stack traces are in the command output. Fix the root cause from them.

"Did my UI/inset/padding change render right?" → a snapshot test

This is the key habit: visual verification is a snapshot test, not a screenshot of a running app. Snapshot tests (Paparazzi via layoutlib, Roborazzi via Robolectric) render a screen to a PNG on the JVM with no device, and the test sets up the data it renders — then diffs against a committed golden.

./gradlew verifyPaparazziDebug    # check renders against goldens (or verifyRoborazziDebug)
./gradlew recordPaparazziDebug    # regenerate goldens after an intended visual change

Loop when you touch UI:

  1. verify… → on failure it writes a diff PNG under the module's build/ (e.g. build/paparazzi/failures/).
  2. Read the diff PNG, and present it to the user (see /shipit-docs/present.md) so they see before/after with no device.
  3. Intended change → record… to update the golden, and commit it.

If the repo has no snapshot tests and you're changing UI, adding a small one for the affected screen is how you make the change verifiable. Pin the snapshot library to the repo's AGP. (layoutlib can't render a WebView — cover native chrome instead.)

Missing SDK component?

A build that needs an off-matrix compileSdk, an NDK, or CMake fails with a precise "missing package" error. Install exactly what it names and re-run — these are ephemeral (re-installed on demand after a restart):

sdkmanager --install "platforms;android-33"
sdkmanager --install "ndk;26.1.10909125"

Want a live device? Add an emulator Compose service

For runtime logs, touch interaction, or an interactive preview, add an emulator to docker-compose.yml with devices: ["/dev/kvm:/dev/kvm"] (needs /dev/kvm on the host). That exact mapping is the only device ShipIt allows — anything else is rejected, and an operator can disable even it with SESSION_ALLOW_DEV_KVM=0. The recipe and the full adb debug/drive triad (logcat, uiautomator dump = snapshot, input tap = press, screencap = screenshot, the Playwright-tools analog) are in /shipit-docs/android.md. Its web UI becomes the interactive preview via x-shipit-preview. No host KVM → Firebase Test Lab for batch test runs.

Don't

  • Don't add Android fields to shipit.yaml — the toolchain is ambient; there are none.
  • Don't reach for the emulator to check a layout — a snapshot test is faster, deterministic, and needs no KVM.
  • Don't run repo-root Gradle in a monorepo — scope to the Android module's dir so the web build is untouched.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.