Skip to main content

Gradle plugin — Builds & uploads

Build-time tasks

Uploads are handled by the Bugsee CLI

The mapping, native-symbol, and build-info / size-analysis upload tasks shell out to the Bugsee CLI rather than embedding their own HTTP, compression, retry, and chunking stack. You don't install or invoke it — the plugin downloads and pins a compatible version automatically. If you need to upload outside Gradle (a custom pipeline, a separate CI step), you can drive the same uploads directly: see Debug information files for mappings and native symbols, and Builds & artefacts for the build record and size-analysis artefact.

The plugin registers per-variant tasks:

TaskTriggerPurpose
createBugsee<Variant>ManifestConfigWired into SingleArtifact.MERGED_MANIFEST transform.Injects a deterministic per-build fallback BUILD_UUID (derived from the merged manifest + variant name + plugin version) into the merged AndroidManifest.xml. The SDK reads this when no asset-channel UUID is available.
resolveBugsee<Variant>BuildId + injectBugsee<Variant>BuildIdPost-R8 (listens to SingleArtifact.OBFUSCATION_MAPPING_FILE) + assets transform (SingleArtifact.ASSETS).When R8 is enabled, derives the BUILD_UUID from a hash of the mapping.txt content — every bytecode change flips the UUID, so the server-side mapping lookup is correct even without a versionCode bump. Writes assets/bugsee_build_id.properties, which the SDK reads at first launch (preferred over the manifest fallback). When R8 is off, the asset carries the same fallback UUID the manifest holds.
uploadBugsee<Variant>MappingFinalizes assemble<Variant> and bundle<Variant>.Uploads the ProGuard / R8 mapping file under the post-R8-resolved BUILD_UUID so the server can symbolicate obfuscated stack traces against the exact build the SDK reports at runtime.
uploadBugsee<Variant>NativeFinalizes assemble<Variant> / bundle<Variant> when bugsee { ndk { enabled.set(true) } }.Uploads NDK native debug symbols (after extract<Variant>NativeDebugMetadata) so native crashes can be symbolicated.
uploadBugsee<Variant>BundleFinalizes bundle<Variant> for every Release variant when bugsee { buildInfo { enabled.set(true) } } (the default).Registers the build record on Bugsee servers (version, configuration, VCS context, timings, artefact size). When buildInfo.sizeAnalysis.enabled = true also uploads the AAB for size analysis.
uploadBugsee<Variant>ApkFinalizes assemble<Variant> for every Release variant when bugsee { buildInfo { enabled.set(true) } } (the default).Same as above for APK builds.

Build info & Size analysis

The plugin's upload step has two layers, configured independently.

Build info (bugsee.buildInfo) — default ON, Release-only. Every Release archive registers a build record on Bugsee servers carrying:

  • uuid, package_id, version, build, build_configuration, format
  • VCS context (commit SHA, branch, base branch, PR number, repo, provider) when resolvable from CI env vars or a local git invocation
  • Build-machine label (GITHUB_RUNNER_NAME, hostname, …), plugin version, Gradle version, compileSdk
  • Per-category Gradle timings (managed-code / native / resources / packaging / other), top-N slowest tasks, total wall-clock
  • Raw artefact byte count

The record exists from the moment of the upload — no artefact bytes are sent by default. Build info unlocks crash-context enrichment (commit lookup), build-history navigation in the dashboard, and the in-build size-check baseline. Set buildInfo.enabled = false to opt out entirely (firewalled CI, privacy-sensitive builds).

Size analysis (bugsee.buildInfo.sizeAnalysis) — default OFF, sub-feature of build info. When enabled, the same upload task additionally requests a presigned PUT URL from the server and ships the artefact zip (AAB / APK + optional mapping.txt) for server-side tree analysis, size diffs, and optimization insights.

Validation rule: buildInfo.sizeAnalysis.enabled = true while buildInfo.enabled = false logs a warning and skips both — size analysis on its own has nothing to attach to.

The release-only filter can be widened to all build types via buildInfo.allBuildTypes = true (useful for projects with custom non-debug configurations like staging, internalRelease).

Both registration paths emit a build.created webhook — see Webhook events → build.created for the payload shape on each trigger.

Chunked upload (bugsee.buildInfo.sizeAnalysis.chunkedUpload) — default OFF. Opt-in optimisation for the size-analysis upload. The artefact is split into content-addressed chunks; on subsequent builds only the chunks that actually changed are re-uploaded, typically cutting upload time by 70–90% on incremental CI. Has no effect when buildInfo.sizeAnalysis.enabled = false. Lives inside the sizeAnalysis block.

Hand the setup to your AI coding assistant

If you use a local AI coding assistant (Claude Code, Cursor, GitHub Copilot, Windsurf, etc.), paste the prompt below. It enables size analysis with the minimum config and then walks you through each optional tweak interactively — you can skip straight through if none apply.

Enable Bugsee build size analysis for my Android app, then walk me
through optional tweaks.

PART 1 — required setup
========================

1. Find the app module's Gradle build script. Look for the
`com.android.application` plugin in `*/build.gradle.kts` (Kotlin DSL)
or `*/build.gradle` (Groovy DSL) — the file that contains it is the
app module's build script.

2. Confirm the Bugsee Gradle plugin is applied in that file
(`id("com.bugsee.android.gradle")` in Kotlin DSL, or
`apply plugin: 'com.bugsee.android.gradle'` /
`id 'com.bugsee.android.gradle'` in Groovy). If it isn't, STOP and
tell me — I need to follow the SDK installation instructions first.
Do not add the plugin yourself.

3. Locate the existing `bugsee { ... }` extension block. Add (or merge)
the `buildInfo.sizeAnalysis` sub-block with `enabled.set(true)`
(Kotlin DSL) or `enabled = true` (Groovy DSL). End state for Kotlin
DSL:

bugsee {
buildInfo {
sizeAnalysis {
enabled.set(true)
}
}
}

Note: the Bugsee app token is wired up at SDK installation time
(in `AndroidManifest.xml` meta-data, or via `appToken(...)` inside
the `bugsee` DSL block). Size analysis re-uses it — do NOT add a
separate token to the Gradle config.

PART 2 — optional tweaks
========================

Now walk me through each option below ONE AT A TIME. For each option:

a. Read me the full description so I know what it does and why I
might want it. Don't summarise — read it as written.
b. Ask yes/no.
c. If no, move on without editing anything.
d. If yes, apply the change and show me the resulting
`bugsee { ... }` block before moving to the next option.

When all four options are done, summarise what changed (or say
"no changes" if I said no to everything).

----------------------------------------------------------------------
Option 1 — Override the configuration label

What it does: Builds sharing a "configuration label" are diffed
against each other on the Bugsee dashboard. By default the plugin
uses the Gradle variant name (`release`, `freeRelease`, `proRelease`,
etc.), which means different flavours appear as separate timelines.

When you want it: Your CI produces multiple comparable flavours
(e.g. `freeRelease` + `proRelease` that ship the same way) and you'd
rather see them in a single timeline so size diffs are meaningful.

When you skip it: You only ship one release flavour, or your flavours
legitimately have different size footprints and shouldn't be diffed.

If yes: ask me which label string to use, then inside the
`buildInfo.sizeAnalysis` sub-block add
`buildConfiguration.set("<my-label>")` (Kotlin DSL) or
`buildConfiguration = "<my-label>"` (Groovy DSL).

----------------------------------------------------------------------
Option 2 — Speed up CI with chunked upload

What it does: Enables a deduplicated chunk-upload protocol. The
artifact is split into content-addressed chunks; on subsequent
builds only the chunks that actually changed get re-uploaded.

When you want it: Your CI runs frequently and most builds are
incremental — chunked upload typically cuts upload time by 70–90%
on subsequent builds. The big win is on long pipelines where upload
bandwidth dominates.

When you skip it: One-off / infrequent builds, or you've already
hit some chunked-upload-specific issue in the past.

If yes: inside the `buildInfo.sizeAnalysis` sub-block (same block
as `enabled`, NOT a separate sibling), add
`chunkedUpload.set(true)` (Kotlin DSL) or `chunkedUpload = true`
(Groovy DSL).

----------------------------------------------------------------------
Option 3 — In-build size regression check

What it does: Compares each build's artifact size against the
most-recent prior build for the same configuration. Crossing the
warning threshold prints a warning in Gradle output; crossing the
fail threshold fails the build. Either gate is independently
optional (`0` disables it).

When you want it: You want a guardrail that catches size
regressions before they ship — especially useful on PR pipelines
so reviewers see "this PR adds 4% download size" alongside test
results.

When you skip it: You're still establishing a baseline (the very
first builds), or you'd rather watch size on the dashboard than
block CI on it.

If yes: ask me for the warning percentage (default 5.0) and the
fail percentage (default 10.0) — either can be `0` to disable. Then
add a nested `sizeCheck` block under `buildInfo` (alongside
`sizeAnalysis`):

bugsee {
buildInfo {
sizeCheck {
enabled.set(true)
warningPercent.set(<value>)
failPercent.set(<value>)
}
sizeAnalysis {
enabled.set(true)
}
}
}

`buildInfo` itself is ON by default — do NOT set `buildInfo.enabled`
explicitly.

----------------------------------------------------------------------
Option 4 — ProGuard / R8 mapping

No question to ask — just inform me: if my build produces a
`mapping.txt`, the plugin uploads it alongside the bundle
automatically. The dashboard shows deobfuscated class names in the
size breakdown. Nothing to configure.

----------------------------------------------------------------------

Do not run Gradle yourself — I'll verify by building when I'm ready.

In-build size check (bugsee.buildInfo.sizeCheck)

Compares the freshly built artefact's file size against the most recent prior build's recorded artifact_size for the same (package_id, format, build_configuration) tuple. Crossing a configured threshold emits a Gradle warning; crossing a fail threshold throws GradleException and fails the upload task.

Each gate is independently optional — a 0 (or unset) disables that gate. Fail wins over warn; percent gate is checked before bytes within the same severity. Negative deltas (artefact shrunk) never trigger anything.

Also configurable via:

  • Environment variablesBUGSEE_SIZE_CHECK_ENABLED, BUGSEE_SIZE_CHECK_WARNING_PCT, BUGSEE_SIZE_CHECK_FAIL_PCT, BUGSEE_SIZE_CHECK_WARNING_BYTES, BUGSEE_SIZE_CHECK_FAIL_BYTES.
  • bugsee.propertiesplugin.buildInfo.sizeCheck.enabled, plugin.buildInfo.sizeCheck.warningPercent, plugin.buildInfo.sizeCheck.failPercent, plugin.buildInfo.sizeCheck.warningBytes, plugin.buildInfo.sizeCheck.failBytes. See Configuring via bugsee.properties.

CI runs that prefer not to mutate the Gradle DSL can configure the check from either source.

Found an issue, typo, or wrong statement on this page? Report it now →