← ~/work

Case study2025Sole author and maintainer

Firebase App Distribution Action

Open-source GitHub Action wrapping Firebase App Distribution for drop-in CI delivery

Role
Sole author and maintainer
Stack
TypeScript · GitHub Actions · Firebase App Distribution · Node.js
Status
Shipped
Reading
1 min
Firebase App Distribution Action · CI deliveryuses: logickoder/firebase-distribution@v1
triggerpush to main
GitHub Actionsbuild release APK
the action · TypeScriptfirebase-distribution@v1app-id · service-credentials-file · file · groups · release-notes
FirebaseApp Distribution
qainternal
Service-account file, not an API key · release notes from the commit message · reused across engagements.

A reusable GitHub Action that delivers Android builds to Firebase App Distribution without per-project CLI plumbing. Built originally for one engagement, reused at every Android job I've held since.

Problem

Every Android team I joined had a hand-rolled Firebase distribution step in their CI: wget the Firebase CLI, juggle service-account credentials, parse changelog from the commit, retry on flaky uploads. Each implementation slightly different. Each broken in slightly different ways. Each owned by no one.

Approach

Standard GitHub Action contract: pass the APK path, service-account JSON, app ID, tester groups. The Action does the CLI dance, surfaces clear errors, retries on transient network failures, supports optional release notes from a file or inline string.

yaml
- uses: logickoder/firebase-distribution@v1
  with:
    app-id: ${{ secrets.FIREBASE_APP_ID }}
    service-credentials-file: ${{ secrets.FIREBASE_SA }}
    file: app/build/outputs/apk/release/app-release.apk
    groups: qa, internal
    release-notes: ${{ github.event.head_commit.message }}

Design decisions

TypeScript over composite Action

Composite Actions stitching shell commands work until they need to handle errors or branch on Firebase CLI output. TypeScript with @actions/core + @actions/exec is the lower-friction long-term choice: proper logging, masked secrets, clean retry logic.

Service-account file, not API key

Firebase App Distribution accepts both an API key flow and a service-account flow. Service-account is the only sane choice for CI: scoped permissions, revocable, auditable.

Outcome

  • Replaced the hand-rolled Firebase distribution step at multiple engagements
  • Single source of truth for the upload flow: fix once, ship everywhere
  • No more "the CI broke and only Adam knows why". The implementation is in one repo, owned.

Tell me what breaks. Issues at github.com/logickoder/firebase-distribution, PRs welcome.