đ§ What is CI/CD?
āϧāϰ⧠āϤā§āĻŽāĻŋ āĻĒā§āϰāϤāĻŋāĻĻāĻŋāύ āϏā§āĻā§āϞ⧠āĻāĻŋā§ā§ āĻāĻŦāĻŋ āĻāĻāĻā§āĨ¤ āϤā§āĻŽāĻžāϰ āĻāĻŋāĻāĻžāϰ āĻāĻžā§, āϤā§āĻŽāĻŋ āĻāĻāĻāĻž āĻļā§āώ āĻāϰāϞā§āĻ āϏā§āĻāĻž āϤāĻžāĻā§ āĻĻā§āĻāĻžāĻ â āϝāĻžāϤ⧠āϏ⧠āĻĻā§āĻā§ āĻ āĻŋāĻ āĻāĻā§ āĻāĻŋāύāĻžāĨ¤ āĻāĻāĻžāĻ CI/CD-āĻāϰ āĻŽāϤā§āĨ¤
āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āϤā§āĻŽāĻŋ āĻāĻŦāĻŋ āĻāĻāĻā§ (code āϞā§āĻā§), āϏāĻā§āĻā§ āϏāĻā§āĻā§ āĻāĻāĻāύ āĻāĻŋāĻāĻžāϰ āϏā§āĻāĻž āĻĻā§āĻā§ (test āĻāϰā§)āĨ¤ -> CI (Continuous Integration)
āϝāĻĻāĻŋ āĻāĻŦāĻŋ āĻ āĻŋāĻ āĻšā§ (test āĻĒāĻžāϏ āĻāϰā§), āϤāĻāύ āϏā§āĻāĻž āĻ āĻā§āĻŽā§āĻāĻŋāĻāĻāĻžāĻŦā§ āϤā§āĻŽāĻžāϰ āĻŦāύā§āϧā§āĻĻā§āϰ āĻĻā§āĻāĻžāύā§āϰ āĻāύā§āϝ āĻĒāĻžāĻ āĻŋā§ā§ āĻĻā§āĻā§āĻž āĻšā§ (release āĻŦāĻž deploy āĻāϰāĻž āĻšā§)āĨ¤ -> CD (Continuous Delivery)
CI = Continuous Integration
⤠Code push āĻāϰāϞā§āĻ āϏāĻŋāϏā§āĻā§āĻŽ āĻ āĻā§ āĻŦāĻŋāϞā§āĻĄ āĻāϰ⧠āĻĻā§āĻā§ bug āĻāĻā§ āĻāĻŋāύāĻž
⤠Automatically build & test code after every commit/pull requestCD = Continuous Delivery or Deployment
⤠āϏāĻŦ āĻāĻŋāĻā§ āĻ āĻŋāĻ āĻĨāĻžāĻāϞ⧠apk/build/upload āĻāϰ⧠āĻĻā§ā§ â human āĻāĻžāĻĄāĻŧāĻžāĻ
⤠Automatically prepare artifacts (APK/AAB) for release
⤠Automatically push to Play Store/internal track (optional, risky for prod)
āĻāĻŽāϰāĻž Android Studio āĻĻāĻŋā§ā§ āĻ ā§āϝāĻžāĻĒ āĻŦāĻžāύāĻžāĻ, Gradle āĻĻāĻŋā§ā§ build āĻāϰāĻŋ, test āĻāĻžāϞāĻžāĻ, APK āϤā§āϰāĻŋ āĻāϰāĻŋāĻ QA āĻŦāĻž Client āĻā§ āĻĒāĻžāĻ āĻžāĻāĨ¤ āĻāĻāϏāĻŦ āĻāĻžāĻ āĻāĻŽāϰāĻž āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āύāĻŋāĻā§ āύāĻŋāĻā§ āĻāϰāϤ⧠āĻšā§āĨ¤
CI/CD āĻšāϞ āĻāĻŽāύ āĻāĻāĻāĻž āĻ āĻā§ āϏāĻŋāϏā§āĻā§āĻŽ, āϝā§āĻāĻž āĻāĻŽāĻžāĻĻā§āϰ āĻšā§ā§ āĻāĻāϏāĻŦ āĻāĻžāĻ āύāĻŋāĻā§ āύāĻŋāĻā§āĻ āĻāϰ⧠āĻĢā§āϞ⧠â āĻāĻŽāĻžāĻĻā§āϰ āĻāĻŋāĻā§āĻ āĻāϰāϤ⧠āĻšā§ āύāĻž!
đ§° CI/CD Tools
Benefits
- Faster release cycle
- fewer bugs
- consistent builds
đī¸ GitHub Actions
â GitHub Actions āĻšāϞ āĻāĻāĻāĻž āĻā§āĻā§āĻ Robot āϝā§āĻāĻž Code Push āĻšāϞā§āĻ āĻāĻžāĻ āĻļā§āϰ⧠āĻāϰā§!
āĻāĻŽāϰāĻž āĻāĻāύ āĻā§ āĻāϰāϤ⧠āĻāĻžāĻ, āϏā§āĻāĻž YAML āĻ āĻŦāϞ⧠āĻĻā§āĻ(Think of GitHub Actions YAML file as a āϰā§āĻŦāĻāĻā§ āύāĻŋāϰā§āĻĻā§āĻļāύāĻž āĻĻā§ā§āĻžāϰ āĻāĻžāϤāĻž, āĻāĻāĻāĻž Text āĻĢāĻžāĻāϞ, āϝā§āĻāĻž āϤā§āĻŽāĻŋ GitHub Actions āĻŦāĻž āĻ āύā§āϝ configuration-āĻ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻāϰ⧠āϰā§āĻŦāĻāĻā§ āύāĻŋāϰā§āĻĻā§āĻļāύāĻž āĻĻāĻŋāϤā§āĨ¤)
āĻāĻŽāϰāĻž .github/workflows/ āĻĢā§āϞā§āĻĄāĻžāϰ⧠āĻāĻāĻāĻž YAML āĻĢāĻžāĻāϞ āĻĻā§āĻ, āϝā§āĻŽāύ:
your-project/
âââ .github/
âââ workflows/
âââ firebase-ci.yml
āĻāĻ GitHub Actions āϰā§āĻŦāĻ â
- Code āĻĄāĻžāĻāύāϞā§āĻĄ āĻāϰ⧠āύā§ā§ (checkout)
- Gradle āĻĻāĻŋā§ā§ build āĻāϰā§
- JUnit/Mockito āĻĻāĻŋā§ā§ test āĻāĻžāϞāĻžā§
- āϏāĻŦ āĻ āĻŋāĻ āĻĨāĻžāĻāĻ˛ā§ â¤ APK āĻĢāĻžāĻāϞ āĻŦāĻžāύāĻžā§
- āϤāĻžāϰāĻĒāϰ ⤠Firebase App Distribution āĻŦāĻž Google Drive-āĻ upload āĻāϰā§
- āĻāĻžāĻāĻ˛ā§ â¤ Slack, Email āĻŦāĻž Telegram-āĻ notify āĻāϰ⧠āĻĻā§ā§
āϝāĻāύāĻ āϤā§āĻŽāĻŋ main āĻŦā§āϰāĻžāĻā§āĻā§ āĻā§āĻĄ push āĻāϰā§, āϤāĻāύ āύāĻŋāĻā§āϰ āϧāĻžāĻĒāĻā§āϞ⧠āĻāϞāĻŦā§:
Android Lint Check: Code clean āĻāĻā§ āĻāĻŋāύāĻž, Android guideline āĻŽā§āύ⧠āϞā§āĻāĻž āĻšā§ā§āĻā§ āĻāĻŋāύāĻž â āϏā§āĻāĻž āĻĻā§āĻā§āĨ¤
Unit Test: āĻā§āĻ āĻā§āĻ function āĻ āĻŋāĻāĻŽāϤ⧠āĻāĻžāĻ āĻāϰāĻā§ āĻāĻŋāύāĻž āϏā§āĻāĻž āĻĒāϰā§āĻā§āώāĻž āĻāϰā§āĨ¤
Instrumentation Test: āĻĒā§āϰ⧠UI/Activity āϏāĻ āĻŋāĻāĻāĻžāĻŦā§ āĻāĻžāĻ āĻāϰāĻā§ āĻāĻŋāύāĻž āĻĻā§āĻā§āĨ¤
Static Code Analysis: Code-āĻ āĻā§āϞ āϧāϰāĻŖ āĻŦāĻž āϏāĻŽāϏā§āϝāĻž āĻāĻā§ āĻāĻŋāύāĻž āĻĻā§āĻā§ (āϝā§āĻŽāύ SonarQube āĻĻāĻŋā§ā§)āĨ¤
APK Build (Packaging): .apk āĻĢāĻžāĻāϞ āĻŦāĻžāύāĻžā§āĨ¤
Functional Test: UI āĻŦāĻžāĻāύ, āϏā§āĻā§āϰāĻŋāύ āĻ āĻŋāĻāĻŽāϤ⧠āϰā§āϏāĻĒāύā§āĻĄ āĻāϰ⧠āĻāĻŋāύāĻž āĻĻā§āĻā§āĨ¤
Deploy: āϝāĻĻāĻŋ āϏāĻŦ āĻ āĻŋāĻ āĻĨāĻžāĻā§, āϤāĻāύ Firebase App Distribution āĻŦāĻž Google Drive āĻ āĻāĻĒāϞā§āĻĄ āĻāϰ⧠āĻĻā§ā§ â āϝāĻžāϤ⧠QA āĻāĻŋāĻŽ āĻā§āϏā§āĻ āĻāϰāϤ⧠āĻĒāĻžāϰā§āĨ¤
Pipeline Building Blocks
These are the stages of a typical Android CI/CD pipeline:
đ§ą YAML-āĻāϰ āĻŽā§āϞ āĻāĻžāĻ āĻžāĻŽā§ (Structure)
āĻāĻāĻāĻž YAML āĻĢāĻžāĻāϞ āϏāĻžāϧāĻžāϰāĻŖāϤ ā§ŠāĻāĻŋ āĻ āĻāĻļā§ āĻāĻžāĻ āĻāϰāĻž āϝāĻžā§:
name: āĻāĻ āĻĒā§āϰ⧠Workflow-āĻāϰ āύāĻžāĻŽ (Just āĻāĻāĻāĻž āĻāĻžāĻāĻā§āϞ).
on: āĻāĻŦā§ āĻāĻ āĻāĻžāĻāĻā§āϞ⧠āĻāϞāĻŦā§? (Trigger condition)
jobs: āĻāϏāϞ āĻāĻžāĻāĻā§āϞā§, Step by Step, āĻā§ āĻā§ āĻšāĻŦā§?
āĻŦāĻžāϏā§āϤāĻŦā§ YAML āĻĢāĻžāĻāϞ āĻāϰ āĻŽāĻžāϧā§āϝāĻŽā§ āϰā§āĻŦāĻāĻā§ āĻŦāϞāĻŋ:
name: Android Build
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: āĻā§āĻĄ āύāĻžāĻ
uses: actions/checkout@v4
- name: JDK āϏā§āĻ āĻāϰā§
uses: actions/setup-java@v4
with:
java-version: '17'
- name: gradlew āĻāĻžāϞāĻžāĻ
run: chmod +x ./gradlew
- name: APK āĻŦāĻžāύāĻžāĻ
run: ./gradlew assembleDebug
- name: APK Upload āĻāϰā§
uses: actions/upload-artifact@v4
with:
name: app-debug.apk
path: app/build/outputs/apk/debug/app-debug.apk
đ¯ āĻāĻĻāĻžāĻšāϰāĻŖ:
on: push ⤠push āĻāϰāϞ⧠āĻāϞāĻŦā§
on: pull_request ⤠PR āĻāϰāϞ⧠āĻāϞāĻŦā§
on: schedule ⤠āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ āϏāĻŽā§ āĻ
āύā§āϝāĻžā§ā§ āĻāϞāĻŦā§
build: āĻšāϞ āĻāĻ āĻāĻžāĻā§āϰ āύāĻžāĻŽ â āϤā§āĻŽāĻŋ āĻāĻā§āĻā§āĻŽāϤ⧠āĻ āύā§āϝ āĻāĻŋāĻā§ āĻĻāĻŋāϤ⧠āĻĒāĻžāϰ⧠āϝā§āĻŽāύ test:, deploy: āĻāϤā§āϝāĻžāĻĻāĻŋāĨ¤
runs-on, GitHub āϤā§āĻŽāĻžāϰ āĻāĻžāĻ āĻāĻžāϞāĻžāύā§āϰ āĻāύā§āϝ āĻāĻāĻāĻž āĻāĻžāϰā§āĻā§ā§āĻžāϞ āĻāĻŽā§āĻĒāĻŋāĻāĻāĻžāϰ (server) āĻāĻžāϞ⧠āĻāϰāĻŦā§āĨ¤
runs-on: ubuntu-latest # Linux machine
runs-on: windows-latest # Windows machine
runs-on: macos-latest # Mac machine (iOS dev-āĻāϰ āĻāύā§āϝ āĻĻāϰāĻāĻžāϰ)
GitHub Marketplace: https://github.com/marketplace
đ CI/CD Flow (GitHub Actions ⤠Firebase App Distribution)
āĻāĻ āĻĢā§āϞā§āĻāĻŋ Android āĻ ā§āϝāĻžāĻĒā§āϰ āĻāύā§āϝ APK build āĻāϰ⧠Firebase-āĻ āĻāĻĒāϞā§āĻĄ āĻāϰ⧠â āĻ āĻā§āĻŽā§āĻāĻŋāĻāĻāĻžāĻŦā§, āϝāĻāύāĻ main branch-āĻ āĻā§āĻĄ push āĻāϰāĻŦā§āĨ¤
01: GitHub Repo āϤā§āϰāĻŋ āĻāϰā§
02: āĻāĻ .yml āĻĢāĻžāĻāϞāĻāĻž āϰāĻžāĻā§ your-project/.github/workflows/firebase-ci.yml
āĻĢāĻžāĻāϞ.
mkdir -p .github/workflows
touch .github/workflows/firebase-ci.yml
your-project/
âââ .github/
âââ workflows/
âââ firebase-ci.yml
03: Gradle wrapper (./gradlew) āĻĢāĻžāĻāϞ āϝā§āύ executable āĻĨāĻžāĻā§.
04: Firebase App ID āϏāĻāĻā§āϰāĻš āĻāϰā§: ⤠Firebase Console ⤠Project Settings ⤠General ⤠Android App ⤠App ID
05: Firebase Token āĻā§āύāĻžāϰā§āĻ āĻāϰā§āĨ¤ CLI āĻĻāĻŋā§ā§ āϞāĻāĻāύ āĻāϰ⧠token āĻŦāĻžāύāĻžāĻāĨ¤ āĻāĻŽāĻžāύā§āĻĄ āĻĻāĻŋā§ā§ : firebase login:ciāĨ¤ āĻāĻāĻāĻž āϞāĻŽā§āĻŦāĻž āĻā§āĻā§āύ āĻāϏāĻŦā§āĨ¤ Copy āĻāϰ⧠āϰāĻžāĻā§āĨ¤
brew install node
node -v
npm -v
npm install -g firebase-tools
firebase login:ci
firebase --version
06: GitHub Secrets āϏā§āĻ āĻāϰā§: GitHub Repo ⤠Settings ⤠Secrets and variables ⤠Actions ⤠âNew repository secretâ āĻ āĻāĻŋā§ā§ āĻāĻ āĻĻā§āĻāĻāĻž key add āĻāϰā§
|Secret Name | Value |
|----------------|-----------------------------------|
|FIREBASE_APP_ID | Firebase Console āĻĨā§āĻā§ āύā§ā§āĻž App ID. |
|FIREBASE_TOKEN | Firebase CLI āĻĻāĻŋā§ā§ generate āĻāϰāĻž token|
â Important Warnings:
- FIREBASE_TOKEN is deprecated
- You are using FIREBASE_TOKEN to authenticate.
- Firebase CLI will remove this method in a future release.
â
Recommended: Use Service Account JSON instead.
đ Create Service Account & Get JSON Key:
- Go to Firebase Console â Project Settings â Service Accounts
- Click âGenerate new private keyâ â Download the .json file
- Add the file to GitHub Secrets (name it SERVICE_ACCOUNT_JSON)
Update your GitHub Actions .yml like:
- name: Upload to Firebase App Distribution
uses: wzieba/Firebase-Distribution-Github-Action@v1
with:
appId: ${{ secrets.FIREBASE_APP_ID }}
serviceCredentialsFileContent: ${{ secrets.SERVICE_ACCOUNT_JSON }}
file: app/build/outputs/apk/release/app-release.apk
testers: your_email@example.com
releaseNotes: "Automated build from GitHub Actions"
07: Firebase Console-āĻ āĻāĻŋā§ā§ testers āĻŦāĻž group āϤā§āϰāĻŋ:
Firebase Console â App Distribution â Testers & Groups
- Add testers â āϤā§āĻŽāĻžāϰ āĻāĻŽā§āĻāϞ āĻ ā§āϝāĻžāĻĄā§āϰā§āϏ āĻ āĻĨāĻŦāĻž āĻā§āϏā§āĻāĻžāϰāĻĻā§āϰ āĻāĻŽā§āĻāϞ āϝā§āĻ āĻāϰā§
āĻāĻžāĻāϞ⧠Group āϤā§āϰāĻŋ āĻāϰ⧠āϤāĻžāϰ āύāĻžāĻŽ āϰāĻžāĻā§, āϝā§āĻŽāύ: internal-testers
08: āĻāĻāύ main branch-āĻ āĻā§āĻĄ push āĻāϰāϞā§āĻ:
â
APK build āĻšāĻŦā§
â
Firebase App Distribution āĻ testers group-āĻ āĻĒāĻžāĻ āĻžāύ⧠āĻšāĻŦā§
â
QA āĻāĻŋāĻŽ āĻĢā§āύ⧠Firebase āĻĨā§āĻā§ install āĻāϰāϤ⧠āĻĒāĻžāϰāĻŦā§
đ firebase-ci.yml āĻĢāĻžāĻāϞ
name: Android CI/CD - Build and Firebase Upload
on:
push:
branches: [ main ] # main branch āĻ push āĻšāϞ⧠trigger āĻšāĻŦā§
jobs:
build:
runs-on: ubuntu-latest
steps:
# 1. āĻā§āĻĄ āĻā§āĻāĻāĻāĻ
- name: Checkout project code
uses: actions/checkout@v4
# 2. JDK āϏā§āĻāĻāĻĒ (Java 17)
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
# 3. gradlew āĻĒāĻžāϰāĻŽāĻŋāĻļāύ āĻĻāĻŋāύ (Linux āĻāϰ āĻāύā§āϝ āĻĒā§āϰā§ā§āĻāύ)
- name: Make gradlew executable
run: chmod +x ./gradlew
# 4. Debug APK build āĻāϰā§āύ
- name: Build Debug APK
run: ./gradlew assembleDebug
# 5. Firebase App Distribution āĻ āĻāĻĒāϞā§āĻĄ āĻāϰā§āύ
- name: Upload to Firebase App Distribution
uses: wzieba/Firebase-Distribution-Github-Action@v1
with:
appId: ${{ secrets.FIREBASE_APP_ID }}
token: ${{ secrets.FIREBASE_TOKEN }}
groups: "internal-testers"
file: app/build/outputs/apk/debug/app-debug.apk
releaseNotes: "Bug fixes and improvements"
notifyTesters: true
https://singhajit.com/android-ci-cd-using-github-actions/
CI/CD Tools: GitHub Actions, GitLab CI, Jenkins, Bitrise, CircleCI, Fastlane
DevOps Skills: Automated build/test/deploy pipelines, Gradle optimization, Firebase App Distribution
Start with: GitHub Actions â Lint â Test â Build
Next: Add Firebase Upload + Slack Notification
Advanced: Code Quality + Play Store Automation
Use Secrets for safety (Firebase Token, API keys)
Recommended
- Start with GitHub Actions
- Learn Fastlane: Even if you use GitHub Actions, Fastlane handles signing, Play Store / App Store uploads, screenshots, and versioning
- Explore at least one alternative
- Bitrise â for mobile apps
- GitLab CI â if you work with GitLab repos
- Understand CI/CD fundamentals
- Workflow triggers: push, PR, schedule
- Environment variables and secrets
- Caching, parallel jobs
- Deploy strategies: canary, staged rollout
Tracks in Google Play
- Internal Track--> Internal testing track â āĻā§āĻ āĻāĻŋāĻŽ āĻŦāĻž āύāĻŋāϰā§āĻĻāĻŋāώā§āĻ testers-āĻāϰ āĻāύā§āϝ, āĻā§āĻŦ āĻĻā§āϰā§āϤ āĻāĻĒāϞā§āĻĄ āĻšā§āĨ¤
- Alpha Track (Closed Testing)--> Closed testing track â select group of testers, release before beta/production.
- Beta Track (Open Testing) --> Open testing track â larger tester group, pre-release before production.
- Production Track --> Public release â āϏāĻāϞ Play Store user-āĻāϰ āĻāύā§āϝāĨ¤
Status Parameter
- completed - Build immediately published to track (not draft).
- draft - Build saved as draft, manual publish needed.
whatsNew/
ââ internal/
â ââ en-US.txt
ââ beta/
â ââ en-US.txt
ââ production/
ââ en-US.txt
SkinBD app production release
- New features
- Bug fixes
GitFlow
1. Main Branch (Production ready code)
- āĻāĻāĻžāύ⧠āϏāĻŦāϏāĻŽā§ stable production code āĻĨāĻžāĻā§āĨ¤
- Example: v1.0 app live āĻāĻā§āĨ¤
2. Develop Branch (Ongoing development)
- āϏāĻŦ developer āĻāĻāĻžāύ⧠merge āĻāϰā§āĨ¤ āĻāĻāĻž future release āĻāϰ āĻāύā§āϝāĨ¤
3. Feature Branch āϤā§āϰāĻŋ
- Rakib āύāϤā§āύ feature āĻŦāĻžāύāĻžāϤ⧠āĻļā§āϰ⧠āĻāϰāϞā§:
git checkout develop &
git checkout -b feature/login-api & git commit -m "feat: add login API with JWT authentication" &
git push origin feature/login-api
- Sara UI āĻŦāĻžāύāĻžāϤ⧠āĻļā§āϰ⧠āĻāϰāϞā§:
git checkout develop &
git checkout -b feature/login-ui
git commit -m "feat: add login screen with username/password fields"
git push origin feature/login-ui
4. Pull Request (PR)
- Rakib GitHub/GitLab āĻ PR āϤā§āϰāĻŋ āĻāϰāϞ⧠â feature/login-api â develop
- CI/CD pipeline run āĻšāϞ⧠â test & build pass
- Teammates review āĻāϰāϞā§, comments āĻĻāĻŋāϞ⧠â Rakib fix āĻāϰāϞā§
- āϤāĻžāϰāĻĒāϰ merge approved
- Sara āĻ āĻāĻāĻāĻāĻžāĻŦā§ feature/login-ui â develop PR āĻĻāĻŋāϞ⧠â merge approved
5. Release Branch
- Release āĻāϰ āϏāĻŽā§:
- git checkout develop
- git checkout -b release/v1.1
- QA āĻāĻŋāĻŽ āĻāĻ branch āĻā§āϏā§āĻ āĻāϰāĻŦā§āĨ¤
- Bug fix āĻĻāϰāĻāĻžāϰ āĻšāϞ⧠āϏāϰāĻžāϏāϰāĻŋ āĻāĻ branch āĻ āĻāϰāĻž āĻšāĻŦā§āĨ¤
6. Production Release
git checkout main
git merge release/v1.1
git tag -a v1.1 -m "Release 1.1"
git push origin main --tags
7. Hotfix Example
- Production āĻ login bug āϧāϰāĻž āĻĒā§āϞ⧠â hotfix branch:
git checkout main
git checkout -b hotfix/login-bug
# fix bug
git commit -m "fix: login null pointer exception"
git push origin hotfix/login-bug
- PR â review â merge into main and develop.
Real-life Output:
- main â v1.0 (old release), later updated to v1.1
- develop â āĻāϞāĻŽāĻžāύ development branch
- feature/login-api â Rakib āĻāϰ āĻāĻžāĻ
- feature/login-ui â Sara āĻāϰ āĻāĻžāĻ
- release/v1.1 â staging QA tested branch
- hotfix/login-bug â production bugfix
Top comments (0)