🚀 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:

image.png

1️⃣ Docker Desktop

  • Enable WSL2 backend
  • Docker must show: Docker Desktop is running

2️⃣ Git

git --version

3️⃣ ngrok

image.png

image.png

  • Login once:
ngrok config add-authtoken <YOUR_TOKEN>

🧱 STEP 1 — CREATE FIREBASE PROJECT (ONCE)

image.png

Firebase Console

  1. Create project
  2. Add Android app
  3. Note:
    • Application ID (package name)

    • Firebase App ID

      (looks like 1:xxxx:android:xxxx)


🧱 STEP 2 — FIREBASE SERVICE ACCOUNT (CRITICAL)

image.png

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)

image.png

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)

image.png

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

image.png

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

image.png

image.png

docker compose up -d

Open:

<https://abcd-xyz.ngrok-free.app>

✔ Login with GitHub

✔ Activate repository


🧱 STEP 8 — ADD DRONE SECRET

image.png

Drone UI → Organization → Secrets

Name Value
FIREBASE_SERVICE_ACCOUNT_B64 (Base64 string)

⚠️ NO quotes

⚠️ ONE line only


🧱 STEP 9 — CREATE TESTER GROUP (ONCE)

image.png

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:

  1. Clone repo
  2. Build APK
  3. Upload to Firebase
  4. 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

Popular posts from this blog

Generate Signing Release keystore

Camera Application