updraft-android plugin integration
| Type | Skill |
| Plugin | awl-android · v0.0.19 |
| Invoke | /awl-android:updraft-plugin-integration |
| Source | plugins/awl-android/skills/updraft-plugin-integration/SKILL.md |
When Claude uses it
Section titled “When Claude uses it”Complete integration guide for the Updraft Android Gradle plugin. Use when adding Updraft to an Android project for automated APK/AAB uploads to the Updraft distribution platform.
Definition
Section titled “Definition”updraft (com.appswithlove.updraft:updraft) is an Android Gradle plugin that uploads APK and AAB files to Updraft — a mobile app distribution platform. It registers Gradle tasks per build variant and automatically attaches Git metadata (branch, commit, tags, URL) to each upload.
Version compatibility:
- AGP ≥ 9.0 → plugin version
3.0.0 - AGP < 9.0 → plugin version
2.3.0
0. Before Writing Any Code — Required Questions
Section titled “0. Before Writing Any Code — Required Questions”Ask the user these questions using askUserQuestionTool before touching any files:
-
Upload scope — “Which build variants should be configured for Updraft uploads?”
- Release variants only (e.g.,
release,stagingRelease,prodRelease) - All variants including debug
- Only specific variants (follow up with a free-text question to get exact names)
- Release variants only (e.g.,
-
Release notes — “How should release notes be sourced for each upload?”
- Last git commit message (default — no config needed)
- Static text in the
updraft {}DSL block - Text file (
src/main/updraft/release-notes.txt) - Gradle CLI property passed at runtime (
-PreleaseNotes="...")
Also ask the user (free text) for the Updraft upload URL(s) — one per variant/app, copied from the Updraft dashboard (App Settings → copy the upload URL from the curl command). Do not proceed without the URLs. Ask whether the URLs may be committed or should stay out of the repo (the AWL templates read them from UPDRAFT_URL_DEV / UPDRAFT_URL_PROD, see section 3.2).
Do not proceed until you have answers to all questions.
1. Detect AGP Version
Section titled “1. Detect AGP Version”Before adding the plugin, read the project’s AGP version to determine which plugin version to use.
Check these files in order until you find the version:
gradle/libs.versions.toml:
[versions]agp = "X.Y.Z"Root build.gradle.kts:
id("com.android.application") version "X.Y.Z"// orclasspath("com.android.tools.build:gradle:X.Y.Z")Root build.gradle (Groovy):
classpath 'com.android.tools.build:gradle:X.Y.Z'Decision:
| AGP version | Plugin version to use |
|---|---|
| ≥ 9.0.0 | 3.0.0 |
| < 9.0.0 | 2.3.0 |
Use the resolved version as <plugin-version> throughout all steps below.
2. Gradle Setup
Section titled “2. Gradle Setup”Version catalog rule: If
gradle/libs.versions.tomlexists in the project, all plugin and dependency declarations must go through the version catalog. Never hardcode versions inline when the catalog is present.
2.1 Add to version catalog (if gradle/libs.versions.toml exists)
Section titled “2.1 Add to version catalog (if gradle/libs.versions.toml exists)”[versions]updraft = "<plugin-version>"
[plugins]updraft = { id = "com.appswithlove.updraft", version.ref = "updraft" }2.2 Apply the plugin in the app module
Section titled “2.2 Apply the plugin in the app module”Apply the plugin to every app module that will upload builds.
Version catalog — Kotlin DSL (app/build.gradle.kts)
Section titled “Version catalog — Kotlin DSL (app/build.gradle.kts)”plugins { alias(libs.plugins.updraft)}No version catalog — Kotlin DSL (app/build.gradle.kts)
Section titled “No version catalog — Kotlin DSL (app/build.gradle.kts)”plugins { id("com.appswithlove.updraft") version "<plugin-version>"}No version catalog — Groovy (app/build.gradle)
Section titled “No version catalog — Groovy (app/build.gradle)”plugins { id 'com.appswithlove.updraft' version '<plugin-version>'}Legacy buildscript approach
Section titled “Legacy buildscript approach”If the project uses buildscript {} in the root build file instead of the plugins {} DSL:
Root build.gradle.kts:
buildscript { repositories { mavenCentral() } dependencies { classpath("com.appswithlove.updraft:updraft:<plugin-version>") }}Root build.gradle (Groovy):
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.appswithlove.updraft:updraft:<plugin-version>' }}Then apply in app/build.gradle.kts:
apply(plugin = "com.appswithlove.updraft")Or app/build.gradle (Groovy):
apply plugin: 'com.appswithlove.updraft'After adding the plugin, sync Gradle and confirm it completes without errors before continuing.
3. Configure Upload URLs
Section titled “3. Configure Upload URLs”Add the updraft {} block to the app module’s build file. It maps capitalized variant names to lists of upload URLs.
3.1 URL key format
Section titled “3.1 URL key format”| Variant name | Config key |
|---|---|
release |
"Release" |
debug |
"Debug" |
stagingRelease |
"StagingRelease" |
prodRelease |
"ProdRelease" |
A single variant can upload to multiple Updraft apps by listing multiple URLs.
3.2 Kotlin DSL (app/build.gradle.kts)
Section titled “3.2 Kotlin DSL (app/build.gradle.kts)”Preferred shape (AWL KMP template, androidApp/build.gradle.kts): the URLs stay out of the repo and come from the environment (CI variables UPDRAFT_URL_DEV / UPDRAFT_URL_PROD) or from the gitignored keystore.properties, through the same secret() helper the release signing config uses. A variant whose URL is unset gets no entry, so its upload task is a no-op:
val keystoreProps = Properties().also { props -> val f = rootProject.file("keystore.properties") if (f.exists()) f.inputStream().use { props.load(it) }}
fun secret(name: String): String? = System.getenv(name) ?: keystoreProps.getProperty(name)
updraft { urls = listOfNotNull( secret("UPDRAFT_URL_DEV")?.let { "DevDebug" to listOf(it) }, secret("UPDRAFT_URL_PROD")?.let { "ProdRelease" to listOf(it) }, ).toMap() // release notes default to last git commit message}Reuse an existing secret() helper if the module already has one. Committed URLs (only when the user allows it):
updraft { urls = mapOf( "Release" to listOf("https://app.getupdraft.com/api/app_upload/<your-token>/") )}Multi-variant / multi-destination example:
updraft { urls = mapOf( "StagingRelease" to listOf("https://app.getupdraft.com/api/app_upload/<staging-token>/"), "ProdRelease" to listOf( "https://app.getupdraft.com/api/app_upload/<prod-token-1>/", "https://app.getupdraft.com/api/app_upload/<prod-token-2>/" ) )}3.3 Groovy (app/build.gradle)
Section titled “3.3 Groovy (app/build.gradle)”updraft { urls = [ "Release": ["https://app.getupdraft.com/api/app_upload/<your-token>/"] ]}Only configure the variants the user requested in section 0. Variants not listed in urls have their tasks registered but will not upload anything.
4. Release Notes
Section titled “4. Release Notes”Configure based on the user’s answer from section 0.
Priority (highest to lowest): CLI property → DSL releaseNotes → text file → last commit message.
Option A — Last git commit message (default)
Section titled “Option A — Last git commit message (default)”No configuration needed. The plugin uses the last commit message automatically when none of the other options are set.
Option B — Static text in DSL
Section titled “Option B — Static text in DSL”Kotlin DSL:
updraft { urls = mapOf(/* ... */) releaseNotes = "Build for QA review"}Groovy:
updraft { urls = [/* ... */] releaseNotes = "Build for QA review"}Option C — Text file
Section titled “Option C — Text file”Create one of:
app/src/main/updraft/release-notes.txt— applies to all variantsapp/src/<flavorName>/updraft/release-notes.txt— applies to a specific flavor only
No DSL property needed; the plugin picks up the file automatically.
Option D — Gradle CLI property (runtime, no DSL change needed)
Section titled “Option D — Gradle CLI property (runtime, no DSL change needed)”Pass the notes at invocation time:
./gradlew updraftRelease -PreleaseNotes="Sprint 42 build"5. Available Gradle Tasks
Section titled “5. Available Gradle Tasks”The plugin registers one task per variant per artifact type after syncing:
| Task pattern | Artifact | Example |
|---|---|---|
updraft<Variant> |
APK | updraftRelease, updraftStagingRelease |
updraftBundle<Variant> |
AAB | updraftBundleRelease, updraftBundleProdRelease |
These tasks depend on assemble<Variant> / bundle<Variant> respectively — the build runs automatically before the upload. The AWL android CI component runs :<module>:updraftBundle<Variant> in its updraftDev / updraftProd jobs once enable_updraft_dev / enable_updraft_prod are set (see the android cicd pipeline setup skill); an unsigned release variant makes that task fail on a filename mismatch, so pair it with signing_from_ci: true.
Run locally:
# Upload APK./gradlew updraftRelease
# Upload AAB./gradlew updraftBundleRelease6. Verification
Section titled “6. Verification”- Sync Gradle — confirm no errors after adding the plugin and configuration.
- List tasks — run
./gradlew tasks | grep -i updraftto confirm tasks are registered for the configured variants. - Run a task —
./gradlew updraftRelease(replace with the relevant variant). - Check output — a successful upload prints a public link to the uploaded build.
- If a task is missing — the variant key in
urlsis likely wrong. Recheck capitalization (e.g.,"StagingRelease"not"stagingRelease").
7. Key Constraints
Section titled “7. Key Constraints”| Constraint | Detail |
|---|---|
| AGP version | Plugin 3.0.0 requires AGP ≥ 9.0. Use 2.3.0 for older AGP. |
| curl required | Plugin uses system curl for uploads. Must be in PATH on the machine running the task. |
| URL source | Upload URLs come from the Updraft dashboard — the plugin cannot generate them. Keep them in CI variables / keystore.properties rather than in the build file (section 3.2). |
| Variant key capitalization | Keys in urls must use capitalized variant names ("Release" not "release"). |
| No separate API key | Auth is embedded in the upload URL — no extra credentials config needed. |
| Multiple URLs per variant | A single variant can target multiple Updraft apps by listing multiple URLs. |
| Git metadata | Branch, commit, tags, and remote URL are collected automatically from the local Git repo. |
| Maven Central | Plugin is on Maven Central — no extra repository block needed in most modern projects. |
8. Public API Reference
Section titled “8. Public API Reference”| Symbol | Kind | Purpose |
|---|---|---|
com.appswithlove.updraft |
Plugin ID | Applied in plugins {} block |
updraft {} |
Extension block | Configure upload URLs and release notes |
urls |
Map<String, List<String>> |
Maps capitalized variant names to lists of upload URLs |
releaseNotes |
String? |
Optional static release notes text (default: last git commit message) |
updraft<Variant> |
Gradle task | Builds and uploads the APK for the named variant |
updraftBundle<Variant> |
Gradle task | Builds and uploads the AAB for the named variant |

