🚀 COMPLETE CI/CD FROM SCRATCH
🚀 COMPLETE CI/CD FROM SCRATCH
Drone + Android + Firebase + ngrok (LOCAL SETUP)
🧠 BIG PICTURE (UNDERSTAND FIRST)
Your setup looks like this:
GitHub Repo
↓ webhook (via ngrok)
Drone Server (localhost)
↓
Drone Docker Runner
↓
Android Build (Docker)
↓
Firebase App Distribution
Why ngrok?
- GitHub cannot reach localhost
- ngrok gives temporary public HTTPS URL
- GitHub sends webhook → ngrok → Drone
🧱 STEP 0 — REQUIREMENTS (ONCE)
Install these on Windows:

1️⃣ Docker Desktop
- Enable WSL2 backend
- Docker must show:
Docker Desktop is running
2️⃣ Git
git --version
3️⃣ ngrok
- Download from https://ngrok.com/download


- Login once:
ngrok config add-authtoken <YOUR_TOKEN>
🧱 STEP 1 — CREATE FIREBASE PROJECT (ONCE)

Firebase Console
- Create project
- Add Android app
- Note:
-
Application ID (package name)
-
Firebase App ID
(looks like
1:xxxx:android:xxxx)
-
🧱 STEP 2 — FIREBASE SERVICE ACCOUNT (CRITICAL)

Why?
CI cannot run firebase login
Steps
Firebase Console → Project Settings → Service Accounts
1️⃣ Click Generate new private key
2️⃣ Download JSON
3️⃣ Save safely (never commit)
✅ REQUIRED IAM ROLES
Add these roles to the service account:
- Firebase App Distribution Admin
- Firebase Admin SDK Administrator
- Service Account Token Creator
(You already did this correctly)
🧱 STEP 3 — BASE64 THE SERVICE ACCOUNT (MANDATORY)

Why?
- JSON = multiline → breaks CI shell
- Base64 = single line → safe
PowerShell (Windows)
[Convert]::ToBase64String(
[System.IO.File]::ReadAllBytes("C:\\path\\to\\firebase-adminsdk.json")
)
Copy the entire output.
🧱 STEP 4 — START NGROK (EVERY TIME YOU RESTART)

ngrok http 8080
You’ll see:
Forwarding <https://abcd-xyz.ngrok-free.app> -> <http://localhost:8080>
📌 Copy this HTTPS URL
(ngrok URL changes every restart)
🧱 STEP 5 — GITHUB OAUTH APP (ONCE)
GitHub → Settings → Developer Settings → OAuth Apps

Create new app:
| Field | Value |
|---|---|
| Homepage URL | https://abcd-xyz.ngrok-free.app |
| Authorization callback URL | https://abcd-xyz.ngrok-free.app/login |
Save:
- Client ID
- Client Secret
🧱 STEP 6 — DRONE SETUP (docker-compose)
Create folder:
D:\\drone-ci
docker-compose.yml
services:
drone-server:
image:drone/drone:2
container_name:drone-server
ports:
-"8080:80"
volumes:
-drone-data:/data
environment:
DRONE_SERVER_HOST:abcd-xyz.ngrok-free.app
DRONE_SERVER_PROTO:https
DRONE_RPC_SECRET:supersecret
DRONE_OPEN:"true"
DRONE_GITHUB_SERVER:<https://github.com>
DRONE_GITHUB_CLIENT_ID:<GITHUB_CLIENT_ID>
DRONE_GITHUB_CLIENT_SECRET:<GITHUB_CLIENT_SECRET>
drone-runner:
image:drone/drone-runner-docker:latest
container_name:drone-runner
depends_on:
-drone-server
environment:
DRONE_RPC_HOST:drone-server
DRONE_RPC_PROTO:http
DRONE_RPC_SECRET:supersecret
volumes:
-/var/run/docker.sock:/var/run/docker.sock
volumes:
drone-data:
🧱 STEP 7 — START DRONE


docker compose up -d
Open:
<https://abcd-xyz.ngrok-free.app>
✔ Login with GitHub
✔ Activate repository
🧱 STEP 8 — ADD DRONE SECRET

Drone UI → Organization → Secrets
| Name | Value |
|---|---|
| FIREBASE_SERVICE_ACCOUNT_B64 | (Base64 string) |
⚠️ NO quotes
⚠️ ONE line only
🧱 STEP 9 — CREATE TESTER GROUP (ONCE)

Firebase Console → App Distribution → Testers & Groups
Create group:
testers
Add at least one email.
🧱 STEP 10 — ANDROID CI PIPELINE (FINAL)
.drone.yml (in GitHub repo root)
kind:pipeline
type:docker
name:android-ci
steps:
-name:build-android
image:ghcr.io/cirruslabs/android-sdk:34
environment:
ANDROID_HOME:/opt/android-sdk-linux
commands:
-chmod+x./gradlew
-./gradlewassembleDebug--no-daemon
-name:firebase-distribute
image:node:20
environment:
FIREBASE_SERVICE_ACCOUNT_B64:
from_secret:FIREBASE_SERVICE_ACCOUNT_B64
commands:
-npminstall-gfirebase-tools
-printf'%s'"$FIREBASE_SERVICE_ACCOUNT_B64"|base64-d>/tmp/firebase-key.json
-exportGOOGLE_APPLICATION_CREDENTIALS=/tmp/firebase-key.json
-firebaseappdistribution:distributeapp/build/outputs/apk/debug/app-debug.apk--app<FIREBASE_APP_ID>--groupstesters--release-notes'Drone CI build'
🧱 STEP 11 — TRIGGER CI
git add .
git commit -m"Enable Drone CI"
git push
Drone will:
- Clone repo
- Build APK
- Upload to Firebase
- Notify testers
🧠 MOST IMPORTANT RULES (REMEMBER FOREVER)
CI RULES
- ❌ Never use
firebase login - ❌ Never store raw JSON in secrets
- ❌ Never multiline shell commands
- ✅ Always base64 secrets
- ✅ Use SDK-included Docker images
- ✅ Use single quotes in shell
Comments
Post a Comment