.cursor/skills/android-release/SKILL.md
Build and upload an Android release based on an existing git tag. Runs lint and all tests first (unit and instrumented), bumps version to match the tag, builds release AAB and APK (without debug info), commits the version bump, and uploads the AAB to Google Play Store internal testing. Use when the user asks to make an Android release, build for Play Store, or upload to Google Play.
npx skillsauth add baijum/ukulele-companion android-releaseInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Build and upload an Android release based on an existing version tag created by the github-release skill.
v9.11.0) created via the github-release skillkeystore.properties at the project rootapp/play-service-account.json (see play-store-upload for setup)If the user specified a tag, validate it exists:
git tag -l v<version>
If no tag was specified, default to the latest tag:
git describe --tags --abbrev=0
Confirm the tag with the user before proceeding.
Follow the android-lint skill workflow:
./gradlew lintDebug
If lint fails, stop and fix the errors first. Do not proceed until lint passes.
./gradlew testDebugUnitTest
Follow the android-test-run skill workflow. Check for a running emulator (adb devices) and run:
./gradlew connectedAndroidTest
If any tests fail, stop the release and fix the failures first. Do not proceed to version bumping until lint and all tests pass.
Before bumping, verify the current versionName in build.gradle.kts matches expectations:
LATEST_TAG=$(git describe --tags --abbrev=0)
TAG_VERSION="${LATEST_TAG#v}"
GRADLE_VERSION=$(grep 'versionName' app/build.gradle.kts | head -1 | sed 's/.*"\(.*\)".*/\1/')
echo "Latest tag: $LATEST_TAG ($TAG_VERSION) | Gradle versionName: $GRADLE_VERSION"
if [ "$TAG_VERSION" != "$GRADLE_VERSION" ]; then
echo "⚠️ VERSION DRIFT DETECTED: Tag says $TAG_VERSION but Gradle says $GRADLE_VERSION"
fi
If version drift is detected, warn the user before proceeding. Version drift means users received APKs with a stale version string. For example, if the latest tag is v9.10.5 but versionName is "9.10.1", four releases shipped with the wrong user-visible version.
Read the current versionCode and versionName in app/build.gradle.kts:
defaultConfig {
versionCode = <current>
versionName = "<major>.<minor>.<patch>"
}
Set versionName to match the tag (e.g., tag v9.11.0 -> versionName = "9.11.0").
Increment versionCode by 1 regardless of version type.
Ask the user to confirm the new version before editing.
Run both Gradle tasks in a single invocation:
./gradlew assembleRelease bundleRelease
This produces release builds that are minified and resource-shrunk (no debug info):
| Artifact | Path | Notes |
|----------|------|-------|
| APK | app/build/outputs/apk/release/app-release.apk | Signed (when keystore.properties exists) |
| APK | app/build/outputs/apk/release/app-release-unsigned.apk | Unsigned (when keystore.properties is missing) |
| AAB | app/build/outputs/bundle/release/app-release.aab | Always signed by the play publisher plugin |
Confirm the AAB exists. The APK may be signed or unsigned depending on whether keystore.properties is present:
ls -lh app/build/outputs/apk/release/app-release*.apk \
app/build/outputs/bundle/release/app-release.aab
Stage the version change, commit, and push to main:
git add app/build.gradle.kts
git commit -m "Android: bump version to <versionName> (versionCode <versionCode>)"
git push
First, verify the service account key exists:
ls app/play-service-account.json
If the file is missing, warn the user and skip to Step 7. The AAB can be uploaded manually via the Google Play Console or by placing the service account key and re-running this step.
If the file exists, follow the play-store-upload skill workflow to upload the AAB to the Play Store internal testing track:
./gradlew publishReleaseBundle
block_until_ms: 120000 (upload can take 30-60s).Provide the user with:
v9.11.0)versionName / versionCode)tools
Record scene video clips for a TOML video project. Reads the android.toml or ios.toml to get the scene list and min_clip_duration, navigates to each screen via ADB (Android) or simctl (iOS), and records individual clips. Use when the user says /record-clips and provides a TOML path.
tools
Upload a release AAB to Google Play Store using the Gradle Play Publisher plugin. Use when the user asks to upload to Play Store, publish to Google Play, deploy to internal testing, promote a release, or mentions Play Console.
development
Promote a release from Google Play internal testing to a closed testing track (Alpha or App Hive Testing). Use when the user asks to promote a release, move to closed testing, push to alpha, push to App Hive Testing, or mentions track promotion.
development
Promote a release to Google Play open testing or production tracks. Supports full rollout and staged rollout to production. Use when the user asks to promote to open testing, beta, go to production, release to all users, staged rollout, or increase rollout percentage.