build-android-binary
Compile a PAM control's Android Kotlin module into the runtime-loadable DEX for a `.ppmplugin`. Creates a staged Gradle build with the pinned wrapper and `react-android` compile dependency, verifies manifest/module/package alignment and runtime-loading constraints, builds the release AAR, then runs…
Install / Use
npx skills add microsoft/power-platform-skills --skill build-android-binaryInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
Development & EngineeringSupported Platforms
Our assessment of build-android-binary
build-android-binary scores 85/100 on our quality scale, 2681st of 4,600 Development & Engineering skills we index.
Its SKILL.md is 20 KB long, well organised into 10 sections with 1 code example: a thorough specification that gives an agent plenty to work with.
It has 919 GitHub stars, a meaningful sign that others use it.
Maintenance, license and trust
- The repository was last updated 12 days ago, so build-android-binary is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
build-android-binary compared with similar skills
All 4 of these similar skills score higher than build-android-binary; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| build-android-binary (this skill)by microsoft | 85 | 919 | 12d ago | SKILL.md |
| Agent-Reachby Panniantong | 100 | 92.4k | 21d ago | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 74.5k | today | CLAUDE.md |
| ai-job-searchby MadsLorentzen | 100 | 45.1k | 1d ago | CLAUDE.md |
| claude-howtoby luongnv89 | 100 | 41.8k | 6d ago | CLAUDE.md |
Frequently asked questions
- How do I install build-android-binary?
- Run
npx skills add microsoft/power-platform-skills --skill build-android-binary. The install tabs above show the steps for each supported agent. - Which AI agents does build-android-binary work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is build-android-binary safe to use?
- It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is build-android-binary still maintained?
- The repository was last updated 12 days ago, so build-android-binary is actively maintained.
Skill content
View source on GitHubname: build-android-binary
description: "Compile a PAM control's Android Kotlin module into the runtime-loadable DEX for a .ppmplugin. Creates a staged Gradle build with the pinned wrapper and react-android compile dependency, verifies manifest/module/package alignment and runtime-loading constraints, builds the release AAR, then runs d8 --min-api 24. Writes ppmplugin/staging/android/<PascalName>Plugin.dex and surfaces actionable Gradle or d8 failures. Requires JDK 17+ and Android SDK Build-Tools 35.0.0; d8 is located from the SDK and system Gradle is optional. Run after /generate-ppmplugin-manifest and before /assemble-ppmplugin."
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, Skill
model: sonnet
/build-android-binary
Turns the extension's Android source (android/.../<Pascal>Module.kt + <Pascal>Package.kt) into the DEX binary that the wrap runtime loads at runtime via DexClassLoader. This is the heavyweight, toolchain-dependent step of producing a .ppmplugin: source code in, a runnable <Pascal>Plugin.dex out.
Naming note: this skill runs Gradle's
assembleReleasetask internally. Don't confuse that with/assemble-ppmplugin, which zips the final bundle — different layers. This skill produces a binary; that one produces the bundle.
Cross-platform: runs on macOS, Linux, and Windows — the Android path has no Mac-only step (JDK 17, Gradle, and Android SDK
d8exist on all three). Every shell command below is given in both bash and PowerShell forms per shared-instructions §5.
Read shared/ppmplugin-format.md §5 — the Android binary requirements this skill enforces.
What this skill does NOT do
- Does not author
manifest.json(run/generate-ppmplugin-manifestfirst — this skill reads it for cross-checks). - Does not zip the
.ppmplugin— that's/assemble-ppmplugin. - Does not build iOS — that's
/build-ios-binary(Mac-only). - Does not modify the canonical
android/— all standalone adjustments are made to a throwaway copy underppmplugin/staging/android-build/(Step 2). The source the engineer maintains is never touched.
Step 1 — Read shared docs + prereq block
- Read
shared/shared-instructions.mdandshared/ppmplugin-format.md. - Read
ppmplugin/staging/manifest.json. If absent, STOP withNEEDS_CONTEXT: manifest.json missing — run /generate-ppmplugin-manifest first(the build cross-checks against it). 2b. Read the## ppmplugin (third-party controls)block in.extension-state.md. If a DEX already exists atppmplugin/staging/android/<dex>, do NOT silently overwrite it — surface it (with its build timestamp) and ask viaAskUserQuestionwhether to replace it:- Source +
manifest.jsonunchanged since the recordedAndroid DEX: builttimestamp → recommend Keep existing (reuse) [default]; also offer Replace (rebuild). - Source or manifest changed → recommend Replace (rebuild) [default]; also offer Keep existing (note: stale — won't match current source). On Keep, skip straight to Step 6 (report) using the existing DEX. On Replace, continue the rebuild. Building is always safe to repeat — this gate just respects an artifact you may have produced on purpose.
- Source +
- Run prereq checks and print the visible block (shared-instructions §9.2). Policy: resolve, don't punt. Each check first tries to satisfy itself — locate a tool by its standard install path (not just PATH), or offer to run a safe install and execute it on
yes(§1.5 auto-fix flow). A check only hard-BLOCKs when it needs something genuinely un-resolvable without a human (e.g. a role grant). "Found but not on PATH" is NOT a block — use the absolute path. Checks:
| Check | Verify | Auto-fix |
|---|---|---|
| JDK 17 | java -version (17+) | OS-aware install per shared-instructions §1.5 (offer; user confirms) |
| Gradle (bootstrap only) | gradle --version — any version is fine; it only generates the pinned wrapper (Step 2.3). A system Gradle isn't used for the build, so don't flag its version here. | install Gradle (OS-aware) if absent |
| Android SDK Build-Tools 35 + d8 | Locate d8, don't require it on PATH (see below) | If found anywhere, PASS. Only if no d8 exists at all → auto-fix-on-confirm <sdkmanager> "build-tools;35.0.0". |
| Android platform 35 | <sdkmanager> --list_installed includes platforms;android-35, or $ANDROID_HOME/platforms/android-35/ exists | Auto-fix on confirm: run it (see below). |
Locating d8 (do NOT block just because it's not on PATH). A user with Android Studio has d8 installed but rarely on PATH. Resolve it to an absolute path and use that path in Step 5:
command -v d8/where d8.bat— if on PATH, use it.- Else search the SDK root (
$ANDROID_HOME, else$ANDROID_SDK_ROOT, else mac default~/Library/Android/sdk, win default%LOCALAPPDATA%\Android\Sdk): pickbuild-tools/35*/d8(mac/linux) orbuild-tools\35*\d8.bat(win). Prefer a 35.x build-tools; fall back to the highest available. - Record the absolute path as
$D8and PASS the check with a note:✓ d8 found at <path> (will invoke by absolute path). Do not require a PATH edit. - BLOCK only if no
d8exists anywhere → offer to install via<sdkmanager> "build-tools;35.0.0"(<sdkmanager>resolved the same way — search$ANDROID_HOME/cmdline-tools/*/bin/sdkmanagerand$ANDROID_HOME/tools/bin/sdkmanager, not just PATH).
Installing platform 35 (auto-fix on confirm). When the platform-35 check fails, OFFER to run the install and wait for yes (shared-instructions §1.5 — execute, don't just print):
# if sdkmanager is missing entirely (mac):
brew install --cask android-commandlinetools
# then (yes | … auto-accepts the SDK licenses):
yes | <sdkmanager> "platforms;android-35"
Re-verify after, then proceed. Only STOP if the user declines or the install fails.
Why platform 35 specifically: the standalone build compiles against compileSdk 35 (Step 2), because RN 0.79's react-android AAR is built against compileSdk 35 and AGP forces consumers to compileSdk ≥ 35. That requires platforms;android-35 and AGP 8.x (7.x can't compile against android-35). So 35 is the floor, not "34 or newer."
Step 2 — Stage a standalone build copy (canonical android/ stays pristine)
The repo's android/ is a bare library module meant to be consumed by the managed host build's Gradle: it relies on the host to supply rootProject.ext values (compileSdkVersion, minSdkVersion, kotlin_version, read via safeExtGet(...)) and to put React Native on the classpath. Standalone, none of that exists — so the safeExtGet fallbacks apply and React doesn't resolve. Rather than mutate the canonical android/build.gradle (which would degrade the real source to satisfy a throwaway build), build from a copy.
-
Copy
android/→ppmplugin/staging/android-build/. Delete + recopy fresh on every run so it never drifts from canonical. Apply these standalone adjustments to the COPY only:a. Pin React Native. The generator now writes
compileOnly "com.facebook.react:react-android:<rnVersion>"directly, so on a freshly scaffolded control this is already correct and the step is a no-op — verify and move on. Older controls carry the legacyimplementation 'com.facebook.react:react-native:+'(or thecompileOnlyvariant of it); rewrite those in the copy tocompileOnly "com.facebook.react:react-android:<rnVersion>"(<rnVersion>frompackage.jsondevDependencies, e.g.0.79.7). Standalone, the host doesn't supply React, and the modern Android coordinate isreact-android(resolves frommavenCentral()).compileOnlyso it is never bundled — RN is provided at runtime by the wrap shell. If you had to rewrite, say so: the canonical source is drifting and/debug-extensionshould fix it there.b. Pin compileSdk to 35. The standalone build has no managed host build
rootProject.ext, sosafeExtGet('compileSdkVersion', …)uses the control's own fallback (older controls default to 33) — which may be too low: RN 0.79'sreact-androidAAR is built against compileSdk 35, and AGP refuses to let acompileSdk < 35module compile against it. Set the copy'scompileSdkVersionto 35 (and ensureminSdkVersionis ≥ 24, the AAR's floor). This requires AGP 8.x (7.x can't compile against android-35). Seeppmplugin-format.md §5. LeavetargetSdkVersionas-is if already ≥ 35.c. Ensure both
google()andmavenCentral()are inrepositories. -
Add
settings.gradlein the copy declaring the library as its own root project:rootProject.name = "<lower>plugin" -
Add a Gradle wrapper pinned to the version RN 0.79 uses with AGP 8.8.2. RN 0.79 pairs AGP 8.8.2 with Gradle 8.13. The wrapper MUST pin 8.13 (AGP 8.8 needs Gradle 8.10.2+; older Gradle fails).
Preferred — write a pre-generated wrapper, skip the bootstrap. Write
gradle/wrapper/gradle-wrapper.propertiesdirectly into the staging copy, pinning both the distribution URL and its checksum, plus thegradle-wrapper.jar+gradlew/gradlew.batscripts:distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip distributionSha256Sum=20f1b1176237254a6fc204d8434196fa11a4cfb387567519c61556e8710aed78distributionSha256Sumis mandatory, not optional. The first./gradlewinvocation downloads and then executes that archive; HTTPS alone authenticates the host, not the bytes. With the pin, Gradle verifies the distribution and aborts on mismatch — fail-closed. The value above is the SHA-256 Gradle publishes athttps://services.gradle.org/distributions/gradle-8.13-bin.zip.sha256; it is a constant of the 8.13 pin, so re-derive it from that endpoint whenever the Gradle version inshared-instructions.md §0moves, and never hand-edit it to make a failing build pass.Verify the wrapper JAR before the first
./gradlew.gradle-wrapper.jaris executed bygradlew, so it needs the same treatment as the distribution: copy it only from a trusted source — the control's own committedandroid/gradle/wrapper/or a verified Gradle install — and verify it against the official Gradle 8.13 wrapper JAR SHA-256 published athttps://downloads.gradle.org/distributions/gradle-8.13-wrapper.jar.sha256.Official checksum (8.13):
81a82aaea5abcc8ff68b3dfcb58b3c3c429378efd98e7433460610fecd7ae45fFail closed:
cd ppmplugin/staging/android-build EXPECTED_WRAPPER_SHA256=81a82aaea5abcc8ff68b3dfcb58b3c3c429378efd98e7433460610fecd7ae45f ACTUAL=$(shasum -a 256 gradle/wrapper/gradle-wrapper.jar | cut -d' ' -f1) [ "$ACTUAL" = "$EXPECTED_WRAPPER_SHA256" ] || { echo "BLOCKED: gradle-wrapper.jar SHA-256 mismatch — expected $EXPECTED_WRAPPER_SHA256, got $ACTUAL"; exit 1; }Never fetch either artifact from an unpinned third-party mirror, and never skip the check because the build is "just a throwaway staging copy" — the staging copy runs on the same machine with the same privileges.
Fallback — if you must run
gradle wrapperand the system Gradle is too old for AGP 8.8.2: temporarily movebuild.gradleaside so the wrapper task has nothing to evaluate, generate the wrapper, then restore:cd ppmplugin/staging/android-build mv build.gradle build.gradle.tmp gradle wrapper --gradle-version 8.13 --distribution-type bin \ --gradle-distribution-sha256-sum 20f1b1176237254a6fc204d8434196fa11a4cfb387567519c61556e8710ae
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
92.4kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
74.5kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
ai-job-search
45.1kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
claude-howto
41.8kA visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
