<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/medium-sntfm8mrk" -->

---
title: Medium | daily.dev
description: Step-by-step guide to automating Android APK builds and distribution using GitHub Actions and Firebase App Distribution. Covers setting up Firebase App...
canonical: https://daily.dev/posts/medium-sntfm8mrk
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Medium | daily.dev
og:description: Step-by-step guide to automating Android APK builds and distribution using GitHub Actions and Firebase App Distribution. Covers setting up Firebase App...
og:url: https://daily.dev/posts/medium-sntfm8mrk
og:image: https://api.daily.dev/og/posts/snTFM8mrk.png
og:image:alt: Medium
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Medium

**[Medium](https://daily.dev/sources/medium_js)** · 17 min read · 1 upvotes · 0 comments

## Summary

Step-by-step guide to automating Android APK builds and distribution using GitHub Actions and Firebase App Distribution. Covers setting up Firebase App Distribution with tester groups, configuring Gradle for release signing with keystore.properties, securely storing sensitive files (keystore, google-services.json) as Base64-encoded GitHub Secrets, and creating a manually-triggered workflow YAML that builds a signed release APK and uploads it to Firebase. Also includes common troubleshooting tips, security best practices, and suggestions for extending the pipeline.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://medium.com/@jrevanth101/ship-your-android-app-to-testers-automatically-a-complete-github-actions-firebase-app-02def952a492>

## Questions this post answers

### How do I securely pass my Android keystore file to a GitHub Actions workflow without committing it to the repository?

Convert the keystore (.jks) file to Base64 text using a command like base64 -i /path/to/your-release.jks, then store that text as a GitHub Secret named KEYSTORE_BASE64. During the workflow, decode it back into a file using echo "$KEYSTORE_BASE64" | base64 --decode > app/release.jks before building, keeping the raw file out of version control entirely.

_daily.dev surfaces workflows like this for developers automating Android release signing and CI/CD pipelines._

### Why does my Firebase App Distribution upload fail with a Group not found error?

The workflow is likely using the tester group's display name instead of its alias. Firebase App Distribution requires the machine-readable alias (for example, qa-testers) set when creating the tester group, which can differ from the human-readable display name shown in the console, so double-check the alias value in the Testers & Groups tab.

_Developers debugging Firebase App Distribution errors can track fixes like this through daily.dev._

### What GitHub Action can automatically upload a signed Android APK to Firebase App Distribution?

The wzieba/Firebase-Distribution-Github-Action@v1 action handles this, taking inputs for appId, serviceCredentialsFileContent (the Firebase service account JSON), groups (tester group alias), file (path to the built APK), and releaseNotes. It runs after a signed release APK is built with Gradle inside a GitHub Actions workflow triggered by workflow_dispatch.

_daily.dev helps developers building Android CI/CD pipelines find action-level details like this quickly._

## Similar posts on daily.dev

- [How to Automate Flutter Releases with Fastlane and GitHub Actions for Firebase App Distribution, Google Play, TestFlight, and App Store Connect](https://daily.dev/posts/how-to-automate-flutter-releases-with-fastlane-and-github-actions-for-firebase-app-distribution-goo-cy1jtlc29) · freeCodeCamp · 0 upvotes · 0 comments
- [Medium](https://daily.dev/posts/medium-v3kyhtbnl) · Medium · 0 upvotes · 0 comments
- [From Hobbyist to Pro: Automating Release Confidence with CalVer & Fastlane](https://daily.dev/posts/from-hobbyist-to-pro-automating-release-confidence-with-calver-fastlane-noflv3w4z) · ProAndroidDev · 0 upvotes · 0 comments
- [How to Build a Production-Ready Flutter CI/CD Pipeline with GitHub Actions: Quality Gates, Environments, and Store Deployment](https://daily.dev/posts/how-to-build-a-production-ready-flutter-ci-cd-pipeline-with-github-actions-quality-gates-environme-rpmoo0tv7) · freeCodeCamp · 1 upvotes · 0 comments

---

Tags: [#android](https://daily.dev/tags/android), [#cicd](https://daily.dev/tags/cicd), [#github-actions](https://daily.dev/tags/github-actions), [#gradle](https://daily.dev/tags/gradle)

[View this post on daily.dev](https://daily.dev/posts/medium-sntfm8mrk)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Medium","url":"https://daily.dev/posts/medium-sntfm8mrk","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/medium-sntfm8mrk"},"datePublished":"2026-07-18T19:32:59.340Z","dateModified":"2026-09-14T08:52:55.441Z","description":"Step-by-step guide to automating Android APK builds and distribution using GitHub Actions and Firebase App Distribution. Covers setting up Firebase App...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d88192e475e7a3f1cbf902ec0da3efa7?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/d88192e475e7a3f1cbf902ec0da3efa7?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Medium","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Medium","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/medium","url":"https://daily.dev/sources/medium_js"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/medium-sntfm8mrk","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"android,cicd,github-actions,gradle","timeRequired":"PT17M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Medium","item":"https://daily.dev/sources/medium_js"},{"@type":"ListItem","position":3,"name":"Medium"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/medium-sntfm8mrk#faq","mainEntity":[{"@type":"Question","name":"How do I securely pass my Android keystore file to a GitHub Actions workflow without committing it to the repository?","acceptedAnswer":{"@type":"Answer","text":"Convert the keystore (.jks) file to Base64 text using a command like base64 -i /path/to/your-release.jks, then store that text as a GitHub Secret named KEYSTORE_BASE64. During the workflow, decode it back into a file using echo \"$KEYSTORE_BASE64\" | base64 --decode > app/release.jks before building, keeping the raw file out of version control entirely. daily.dev surfaces workflows like this for developers automating Android release signing and CI/CD pipelines."}},{"@type":"Question","name":"Why does my Firebase App Distribution upload fail with a Group not found error?","acceptedAnswer":{"@type":"Answer","text":"The workflow is likely using the tester group's display name instead of its alias. Firebase App Distribution requires the machine-readable alias (for example, qa-testers) set when creating the tester group, which can differ from the human-readable display name shown in the console, so double-check the alias value in the Testers & Groups tab. Developers debugging Firebase App Distribution errors can track fixes like this through daily.dev."}},{"@type":"Question","name":"What GitHub Action can automatically upload a signed Android APK to Firebase App Distribution?","acceptedAnswer":{"@type":"Answer","text":"The wzieba/Firebase-Distribution-Github-Action@v1 action handles this, taking inputs for appId, serviceCredentialsFileContent (the Firebase service account JSON), groups (tester group alias), file (path to the built APK), and releaseNotes. It runs after a signed release APK is built with Gradle inside a GitHub Actions workflow triggered by workflow_dispatch. daily.dev helps developers building Android CI/CD pipelines find action-level details like this quickly."}}]}
```

