Status: v2 spec, deferred. v1 is live via Obtainium + GitHub Releases — see #178 for the shipped approach. This ticket tracks the upgrade path for when self-managed Obtainium subscriptions become a coordination bottleneck.
When to pick this up (triggers)
- Scale — more than ~20 active testers where manual Obtainium subscription management becomes a tax.
- External testers — paid or client-side testing programs that need a branded experience, not a generic 3rd-party Obtainium UI.
- Product metrics — need install counts per channel, version distribution, or crash reports pinned to a tester's device, which GitHub Releases doesn't surface cleanly.
Until one of the above is a real pain point, v1 (Obtainium) is the steady state.
v2 architecture
Cloud (labelle.games)
- API server — receives APK uploads, stores versions, manages testers/channels.
- Storage — S3-compatible blob store for APKs.
- Auth — GitHub OAuth for developers, email/link for testers.
- Web dashboard — project overview, tester management, version history.
- Endpoints:
POST /api/deploy — upload APK (from CLI).
GET /api/update/<project>/<channel> — companion app polls this.
GET /t/<project>/<channel> — tester onboarding web page.
CLI (labelle deploy upgrade)
- Reuses the existing
labelle android deploy from v1 but swaps the upload target from GitHub Releases to labelle.games.
- Manages testers and channels server-side.
Companion app (Android) — #142
- Lightweight native app (~2MB), Kotlin or Flutter.
- Registers device with labelle.games.
- Polls for updates (or push via FCM).
- Silent install via Android
PackageInstaller (one-time user opt-in).
- No game-specific code — works for any labelle project.
Child tickets
Channels (v2)
internal — default, immediate, no review.
staging — pre-release testing.
production — stable builds.
v2 roadmap
v2.0 — Cloud OTA
v2.1 — Crash reporting
v3 — Platform expansion
Tech-stack decisions deferred until implementation starts
- API: Go / Rust / Node.
- Storage: S3 / R2 (Cloudflare) / GCS.
- Database: Postgres.
- Hosting: Fly.io / Railway / self-hosted.
- Companion app: Kotlin (minimal) or Flutter.
Prior art (examined during v1 pivot)
Non-goals even at v2
- Play Store publishing (different workflow).
- A/B testing.
- Analytics beyond crash reporting + install counts.
Tracks #7 (Android support, closed).
When to pick this up (triggers)
Until one of the above is a real pain point, v1 (Obtainium) is the steady state.
v2 architecture
Cloud (labelle.games)
POST /api/deploy— upload APK (from CLI).GET /api/update/<project>/<channel>— companion app polls this.GET /t/<project>/<channel>— tester onboarding web page.CLI (
labelle deployupgrade)labelle android deployfrom v1 but swaps the upload target from GitHub Releases to labelle.games.Companion app (Android) — #142
PackageInstaller(one-time user opt-in).Child tickets
Channels (v2)
internal— default, immediate, no review.staging— pre-release testing.production— stable builds.v2 roadmap
v2.0 — Cloud OTA
labelle deployswitches to labelle.games backend (keeps GitHub Releases as a fallback).v2.1 — Crash reporting
v3 — Platform expansion
Tech-stack decisions deferred until implementation starts
Prior art (examined during v1 pivot)
Non-goals even at v2
Tracks #7 (Android support, closed).