Add the Android SDK

Takes about 15 minutes

The SDK puts a report button in your QA build and talks to the Hub. Your release build links bugoro-noop instead: the same API, doing nothing, so none of Bugoro ships to the store.

The SDK isn't published to a Maven repository yet. Include its two Gradle modules from the Bugoro repository, as Bugoro's sample app does.

Include the SDK modules

  1. Add the Bugoro repository's sdk-android/bugoro and sdk-android/bugoro-noop to your build, at the same paths (for example as a Git submodule). They resolve their plugins and libraries through Bugoro's gradle/libs.versions.toml, so add the entries they use to your version catalog.

  2. In settings.gradle.kts:

    include(":sdk-android:bugoro")
    include(":sdk-android:bugoro-noop")

Add a qa build type

In your app module's build.gradle.kts. The QA build installs next to the store app because it has its own application id.

android {
    buildTypes {
        // The build testers install: its own application id, debuggable.
        create("qa") {
            initWith(getByName("debug"))
            applicationIdSuffix = ".qa"
            versionNameSuffix = "-qa"
            isDebuggable = true
            // Library modules only have debug/release; qa consumes their debug variant.
            matchingFallbacks += listOf("debug")
        }
    }
}

Sign every QA build with the same key, or a tester can't install the fix over the build they have. The CI components page shows how.

Pass the Hub URL from Gradle

The qa-build CI component runs Gradle with -Pbugoro.hubUrl=<hub_url>. Turn that property into a BuildConfig field for debug and qa builds:

import com.android.build.api.variant.BuildConfigField

val bugoroHubUrl = providers.gradleProperty("bugoro.hubUrl").orElse("")

android {
    buildFeatures {
        buildConfig = true
    }
    buildTypes {
        release {
            // Release links the no-op, which never reads it.
            buildConfigField("String", "BUGORO_HUB_URL", "\"\"")
        }
    }
}

androidComponents {
    onVariants { variant ->
        if (variant.buildType == "release") return@onVariants
        // Checked when the BuildConfig is generated, since Bugoro.install rejects a non-http(s) URL
        // when the app starts.
        variant.buildConfigFields?.put(
            "BUGORO_HUB_URL",
            bugoroHubUrl.map { url ->
                require(Regex("""https?://[^\s"\\]+""").matches(url)) {
                    "Gradle property bugoro.hubUrl must be an http(s) URL without spaces or quotes, got \"$url\""
                }
                BuildConfigField("String", "\"$url\"", "The Bugoro Hub (Gradle property bugoro.hubUrl)")
            },
        )
    }
}

For local builds, set bugoro.hubUrl in gradle.properties.

Install it with BugoroConfig

Call Bugoro.install from your Application.onCreate. In release builds it does nothing.

import android.app.Application
import com.bugoro.sdk.Bugoro
import com.bugoro.sdk.BugoroConfig

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        Bugoro.install(this, BugoroConfig(BuildConfig.BUGORO_HUB_URL, "<app-key>"))
    }
}
FieldWhat it is
hubUrlThe Hub's public URL, https://<hub-host>.
appKeyYour app's key on the Hub: the APP_KEY you connected the project with.
deepLinkBaseOptional. Your app's deep link prefix, for example myapp://app, so the farm can open the reported screen.
enableShakeOptional. Also open the reporter when the tester shakes the phone.

Check the release build is clean

This script fails unless a release APK carries bugoro-noop and nothing else of Bugoro's: no SDK code, no pairing screen.

sdk-android/check-release-clean.sh [--allow-absent] <apk>
  • Exit 0 prints release clean; exit 1 lists what it found; exit 2 means it couldn't run.
  • It needs apkanalyzer from the Android SDK command line tools.
  • The store-check CI component runs it with --allow-absent on the release bundle, so an app without Bugoro passes too.