A GitHub Action to distribute your Android and iOS apps to testers using Firebase App Distribution. Supports wildcard file patterns for easy distribution of multiple builds (e.g., APK splits).
Note: This action bundles Firebase CLI automatically - no manual installation required!
For versioning and release information, see RELEASE.md.
- π¦ Distribute Android (APK, AAB) and iOS (IPA) apps to Firebase App Distribution
- π― Support for wildcard patterns to upload multiple files (perfect for APK splits)
- π Service account authentication (file or content)
- π Automatic release notes from git history or custom notes
- π₯ Target specific tester groups or individual testers
- π Get distribution URLs as action outputs
- Firebase project set up
- Firebase App Distribution enabled for your app
- Service account credentials configured
This action uses Firebase service account authentication for secure, long-term access.
- Go to the Firebase Console
- Select your project
- Go to Project Settings > Service Accounts
- Click "Generate New Private Key"
- Download the JSON key file
- Add the content as a GitHub secret
- name: Distribute to Firebase App Distribution
uses: logickoder/firebase-distribution@v1
with:
serviceCredentialsFileContent: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
file: app/build/outputs/apk/release/app-release.apk
appId: ${{ secrets.FIREBASE_APP_ID }}
groups: testersPerfect for distributing APK splits or multiple variants. See the Wildcard Pattern Guide for more pattern examples.
- name: Distribute APK Splits
uses: logickoder/firebase-distribution@v1
with:
serviceCredentialsFileContent: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
file: 'app/build/outputs/apk/release/*.apk'
appId: ${{ secrets.FIREBASE_APP_ID }}
groups: internal-testers
releaseNotes: 'New build with split APKs for different architectures'
# Each file will have its name appended to release notes by default
# Set to 'false' to disable: includeFileNameInReleaseNotes: falsename: Distribute App
on:
push:
branches: [main]
jobs:
distribute:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Build APK
run: ./gradlew assembleRelease
- name: Distribute to Firebase
uses: logickoder/firebase-distribution@v1
with:
serviceCredentialsFileContent: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
file: 'app/build/outputs/apk/**/*.apk'
appId: ${{ secrets.FIREBASE_APP_ID }}
groups: 'qa-team, beta-testers'
releaseNotes: |
π New features:
- Feature A
- Feature B
π Bug fixes:
- Fixed issue X- name: Distribute with Release Notes File
uses: logickoder/firebase-distribution@v1
with:
serviceCredentialsFileContent: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
file: app/build/outputs/apk/release/app-release.apk
appId: ${{ secrets.FIREBASE_APP_ID }}
testers: 'tester1@example.com, tester2@example.com'
releaseNotesFile: RELEASE_NOTES.txt- name: Distribute with Service Account File
uses: logickoder/firebase-distribution@v1
with:
serviceCredentialsFile: ./firebase-service-account.json
file: '**/*.apk'
appId: ${{ secrets.FIREBASE_APP_ID }}
groups: testersWhen you have multiple repositories checked out in your workflow:
- name: Checkout main app
uses: actions/checkout@v4
with:
path: main-app
- name: Checkout library
uses: actions/checkout@v4
with:
repository: org/library
path: library
- name: Build main app
run: ./gradlew assembleRelease
working-directory: main-app
- name: Distribute from main-app directory
uses: logickoder/firebase-distribution@v1
with:
workingDirectory: main-app
serviceCredentialsFileContent: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
file: 'app/build/outputs/apk/release/*.apk'
appId: ${{ secrets.FIREBASE_APP_ID }}
groups: testers| Name | Description | Required | Default |
|---|---|---|---|
file |
Path to binary file(s) to upload. Supports wildcards (e.g., *.apk, **/*.aab) |
Yes | |
workingDirectory |
Working directory to run the action in (for multi-repo workflows) | No | . |
appId |
Firebase App ID (found in Firebase console) | Yes | |
serviceCredentialsFile |
Path to service account JSON file | No* | |
serviceCredentialsFileContent |
Content of service account JSON file | No* | |
groups |
Comma-separated list of tester group names | No | |
testers |
Comma-separated list of tester email addresses | No | |
releaseNotes |
Release notes text | No | Latest git commit |
releaseNotesFile |
Path to file containing release notes | No | |
includeFileNameInReleaseNotes |
Include filename in release notes when distributing multiple files | No | true |
debug |
Enable debug mode for detailed logging | No | false |
*Either serviceCredentialsFile or serviceCredentialsFileContent must be
provided
| Name | Description |
|---|---|
firebase-console-uri |
URL to view the release in Firebase Console |
testing-uri |
URL to share with testers for downloading the app |
binary-download-uri |
Direct download URL for the binary |
- name: Distribute to Firebase
id: firebase
uses: logickoder/firebase-distribution@v1
with:
serviceCredentialsFileContent: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
file: app/build/outputs/apk/release/app-release.apk
appId: ${{ secrets.FIREBASE_APP_ID }}
groups: testers
- name: Send notification
run: |
echo "Console: ${{ steps.firebase.outputs.firebase-console-uri }}"
echo "Testing: ${{ steps.firebase.outputs.testing-uri }}"
echo "Download: ${{ steps.firebase.outputs.binary-download-uri }}"The action uses glob patterns. Here are some examples:
*.apk- All APK files in current directory**/*.apk- All APK files in current directory and subdirectoriesapp/build/outputs/apk/**/*.apk- All APKs in specific path*.{apk,aab}- All APK and AAB filesapp-*-release.apk- Files matching the pattern
See WILDCARD_GUIDE.md for comprehensive pattern examples.
Add these secrets to your GitHub repository (Settings > Secrets and variables > Actions):
FIREBASE_SERVICE_ACCOUNT- Your service account JSON contentFIREBASE_APP_ID- Your Firebase App ID (e.g.,1:1234567890:android:abcdef)
- Go to Firebase Console
- Select your project
- Go to Project Settings
- Scroll to "Your apps" section
- Copy the App ID
-
No files found matching pattern
- Check that your build artifacts exist before running this action
- Verify the file path is correct
- Use
lsorfindcommands to debug file locations
-
Authentication failed
- Ensure your service account has the "Firebase App Distribution Admin" role
- Verify the JSON content is properly formatted
- Check that the service account JSON is for the correct Firebase project
-
App ID not found
- Verify the App ID format (should be like
1:1234567890:android:abcdef) - Ensure App Distribution is enabled for your app in Firebase Console
- Verify the App ID format (should be like
-
No testers or groups specified
- At least one of
groupsortestersshould be specified - Group names are case-sensitive
- At least one of
Enable debug mode for detailed logging:
- uses: logickoder/firebase-distribution@v1
with:
serviceCredentialsFileContent: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
file: app.apk
appId: ${{ secrets.FIREBASE_APP_ID }}
groups: testers
debug: trueThis action follows semantic versioning. You can reference it in three ways:
@v1(Recommended) - Automatically uses the latest v1.x.x release@v1.2.3(Stable) - Pins to an exact version for maximum stability@main(Not recommended) - Uses the latest commit (may be unstable)
For most use cases, using @v1 is recommended as it provides automatic updates
while maintaining compatibility.
π For maintainers: See RELEASE.md for detailed information about the release process, creating new versions, and how the distribution system works.
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.