Hands-On Android CI/CD: Build, Test, and Deploy with GitHub Actions
As a developer, you know the familiar pain: manual builds are slow, testing often gets skipped in the sprint rush, signing takes too much time, and inconsistent release cycles hurt team velocity. This is not just frustrating — it’s a major bottleneck that prevents you from shipping your app faster and more confidently.
Stop Drowning in Manual Builds: The Power of Android CI/CD
The solution is clear: Continuous Integration and Continuous Deployment (CI/CD). This automated pipeline handles everything between your last line of code and the app hitting the Play Store. What is CI/CD, and Why GitHub Actions?
CI/CD is a two-part process:
- Continuous Integration (CI): Every time a change is committed, the system automatically builds and tests the project. This ensures instant feedback on code quality.
- Continuous Deployment/Delivery (CD): The process of automatically packaging, signing, and deploying your application, often to internal testing tracks or production.
For mobile development, GitHub Actions is an ideal choice. It’s seamlessly integrated into GitHub, free for public repositories, and provides robust support for the Android ecosystem, making it a perfect tool to automate your mobile workflows. Building Your Production-Ready Android Workflow
A complete CI/CD pipeline is built on a few core concepts, typically defined in a YAML workflow file:
- Workflows, Jobs, and Runners: Workflows contain one or more jobs, and each job runs on a dedicated virtual machine called a runner. We use YAML to define these steps.
- CI Workflow Overview: This pipeline is usually triggered on a pull request, commit, or tag. It focuses on the core tasks of building your app, running unit tests, and checking code quality to provide instant feedback to the team.
- CD Workflow Overview: Once testing is successful, the CD part takes over. It manages secrets, handles the app signing process, and automates the upload to the Play Store.
Key technical steps in a robust workflow include:
- Setup: Checking out the repository and setting up the correct Java and Gradle environment.
- Testing: Granting execution permissions to the Gradle wrapper and running unit tests using
./gradlew test. - Dependency Management: Utilizing the official GitHub Actions to cache Gradle dependencies, which dramatically speeds up subsequent build times.
Secure Secrets and Automated Deployment
Security and automation are two sides of the same coin in CD.
- Secrets Management: Never commit sensitive files like your keystore or API keys to your repository. GitHub Actions allows you to securely encrypt secrets within your repository settings. The CD workflow then decodes the encrypted keystore and passwords only during execution for app signing.
- Deployment: To fully automate your releases, you can use community actions to push builds directly to the Internal Testing track via the Play Developer API. This allows your QA team to get new versions instantly, bypassing manual uploads entirely and ensuring a safe, automated release process. The workflow can also be configured to generate the app version code and name based on workflow run counts and the trigger tag.
Release Workflow Example
name: Deploy To Google Play
run-name: Deploy To Google Play - ${{ github.ref_name }}
permissions:
contents: write
concurrency:
group: deploy-to-play-${{ github.ref }}
cancel-in-progress: true
on:
push:
tags:
- 'v*'
jobs:
test:
name: Unit Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup JDK 21
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 21
- name: Cache Gradle files
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Grant execution permission for gradlew
run: chmod +x gradlew
- name: Run Unit Tests
run: ./gradlew test
distribute:
name: Distribute bundle to Google Play
needs: test
runs-on: ubuntu-latest
env:
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup JDK 21
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 21
- name: Cache Gradle files
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Version Bump
uses: chkfung/android-version-actions@v1.2.3
with:
gradlePath: app/build.gradle.kts
versionCode: ${{ github.run_number }}
versionName: ${{ github.ref_name }}
- name: Export Release Key
run: echo "${{ secrets.ANDROID_KEYSTORE }}" | base64 --decode > release-key.jks
- name: Assemble Release Bundle
run: ./gradlew bundleRelease
- name: Setup Authorization with Google Play Store
run: echo '${{ secrets.GOOGLE_PLAY_AUTH_JSON }}' > service_account.json
- name: Deploy Bundle to Google Play
uses: r0adkll/upload-google-play@v1.1.3
with:
serviceAccountJson: service_account.json
packageName: dev.alimansour.mytasks
releaseFiles: app/build/outputs/bundle/release/app-release.aab
track: internal
inAppUpdatePriority: 5
status: completed
Advanced Tips for a Faster Pipeline
- Caching: Caching Gradle dependencies can reduce build times from minutes to seconds, providing significant time savings.
- Parallel Jobs: Run independent tasks like linting, unit tests, and integration tests simultaneously to reduce the total pipeline time.
- Matrix Builds: Test your application across multiple versions of Android, different Java versions, or various build types in parallel using a build matrix.
- Self-Hosted Runners: For very large projects or specific hardware requirements, self-hosted runners allow you to run your own machines to execute workflows, offering greater flexibility and helping to overcome GitHub’s limits for private repositories.
By implementing this complete CI/CD pipeline, you replace stress-inducing manual work with a reliable, automated system. Automate together and ship your Android apps faster, more securely, and with far greater confidence.
Note: This article is adapted from my talk “Ship It Faster: Your Complete Guide to Android CI/CD with GitHub Actions”, which I recently presented at Devfest Helwan 2025, and Devfest On Discord 2025.
Wrap-Up
✅ Full CI/CD pipeline built
✅ Automated build, test, deploy
✅ Secrets managed securely
Resources & Repo
Android Docs: https://developer.android.com/develop
GitHub Actions Docs: https://docs.github.com/en/actions