Skip to content
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
9618312
feat: add Firebase App Distribution and Google Services plugins
ElsayedMagdy122 Aug 22, 2025
194d5e7
feat: implement Firebase App Distribution CD pipeline
ElsayedMagdy122 Aug 22, 2025
b4c9103
feat: add Firebase App Distribution and Google Services plugins
ElsayedMagdy122 Aug 22, 2025
7f9da7d
chore: update path for google-services.json in Firebase CD workflow
ElsayedMagdy122 Aug 23, 2025
552cbdc
Update android-ci.yml
ElsayedMagdy122 Aug 23, 2025
beb17a0
Merge remote-tracking branch 'origin/feature/cd-firebase' into featur…
ElsayedMagdy122 Aug 23, 2025
fc02c19
Update android-ci.yml
ElsayedMagdy122 Aug 23, 2025
8ebdf0a
Merge remote-tracking branch 'origin/feature/cd-firebase' into featur…
ElsayedMagdy122 Aug 23, 2025
7ccea01
Merge branch 'develop' into feature/cd-firebase
YoussefmSaber Aug 23, 2025
7fe51f2
Merge branch 'develop' into feature/cd-firebase
Al-Qassim Aug 23, 2025
29d3149
test cd fire base
Al-Qassim Aug 23, 2025
bd0fac1
put json in right place
Al-Qassim Aug 23, 2025
7ad3836
3rd try
Al-Qassim Aug 23, 2025
fe14a72
Merge branch 'develop' into feature/cd-firebase
Al-Qassim Aug 23, 2025
bddd699
4th try
Al-Qassim Aug 23, 2025
42f1042
5th try
Al-Qassim Aug 23, 2025
45f33aa
6th try
Al-Qassim Aug 23, 2025
5cbe948
7th try
Al-Qassim Aug 23, 2025
94013f2
Merge remote-tracking branch 'origin/feature/cd-firebase' into featur…
ElsayedMagdy122 Aug 24, 2025
4611a8f
Refactor: update Firebase CD workflow
ElsayedMagdy122 Aug 24, 2025
06337f4
feat: add feature/cd-firebase branch to cd workflow
ElsayedMagdy122 Aug 28, 2025
ac3554c
8th
Al-Qassim Aug 28, 2025
157de37
Merge remote-tracking branch 'origin/feature/cd-firebase' into featur…
ElsayedMagdy122 Aug 28, 2025
7fcbb90
Merge remote-tracking branch 'origin/develop' into feature/cd-firebase
ElsayedMagdy122 Aug 28, 2025
2d2a649
Merge remote-tracking branch 'origin/develop' into feature/cd-firebase
ElsayedMagdy122 Aug 28, 2025
8f57dd9
Fix: Update path for google-services.json and keystore in CD workflow
ElsayedMagdy122 Aug 28, 2025
298d873
9th
Al-Qassim Aug 28, 2025
d5fccf9
Merge remote-tracking branch 'origin/develop' into feature/cd-firebase
Al-Qassim Aug 28, 2025
5b5d527
Merge remote-tracking branch 'origin/feature/cd-firebase' into featur…
ElsayedMagdy122 Aug 28, 2025
0213af8
Refactor: Remove unused Firebase plugin versions from TOML
ElsayedMagdy122 Aug 28, 2025
7d69248
Fix: Update APK path in CD workflow
ElsayedMagdy122 Aug 28, 2025
4a09a5c
feat: automate release notes for Firebase App Distribution
ElsayedMagdy122 Aug 28, 2025
cd629fb
Remove unused workflow permissions
ElsayedMagdy122 Aug 28, 2025
db43c0a
Fix: Update APK path in Firebase CD workflow
ElsayedMagdy122 Aug 28, 2025
cc950ee
10th
ElsayedMagdy122 Aug 28, 2025
e94b5b8
11th
ElsayedMagdy122 Aug 28, 2025
c5ec111
12th
ElsayedMagdy122 Aug 28, 2025
08971aa
refactor: Enable ProGuard and resource shrinking for release builds
ElsayedMagdy122 Aug 28, 2025
9e60473
Merge branch 'develop' into feature/cd-firebase
ElsayedMagdy122 Aug 28, 2025
3d43e2b
Refactor: Streamline Android CI workflow
ElsayedMagdy122 Aug 28, 2025
30689b2
Merge remote-tracking branch 'origin/feature/cd-firebase' into featur…
ElsayedMagdy122 Aug 28, 2025
6e23afc
Fix: Resolve CI/CD build failures
ElsayedMagdy122 Sep 3, 2025
7628284
Merge remote-tracking branch 'origin/develop' into feature/cd-firebase
ElsayedMagdy122 Sep 3, 2025
0dcf239
refactor: Enable ProGuard for release builds and update CD workflow
ElsayedMagdy122 Sep 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 73 additions & 23 deletions .github/workflows/android-ci.yml
Original file line number Diff line number Diff line change
@@ -1,41 +1,91 @@
name: Android CI
name: EvolveFit CD Pipeline

on:
push:
branches:
- main
- develop
pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
JAVA_VERSION: 21
- master

jobs:
android-build:
name: Android Build
deploy:
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Java
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: ${{ env.JAVA_VERSION }}

- name: Build Android App
run: ./gradlew :composeApp:assembleDebug
java-version: '21'

- name: Upload Android APK
if: github.event_name == 'push'
uses: actions/upload-artifact@v4
- name: Cache Gradle
uses: actions/cache@v4
with:
name: android-apk-debug
path: composeApp/build/outputs/apk/debug/*.apk
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
gradle-${{ runner.os }}-

- name: Make gradlew executable
run: chmod +x ./gradlew

- name: Create google-services.json
env:
GOOGLE_SERVICES_JSON_BASE64: ${{ secrets.GOOGLE_SERVICES_JSON_BASE64 }}
run: |
mkdir -p composeApp/ # Ensure the directory exists
echo "$GOOGLE_SERVICES_JSON_BASE64" | base64 --decode > composeApp/google-services.json
shell: bash

- name: Decode Keystore and Create local.properties
env:
KEYSTORE: ${{ secrets.KEYSTORE }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}

run: |
rm -f app/JKS.jks local.properties release_notes.txt
echo "$KEYSTORE" | base64 -d > app/JKS.jks
echo "KEYSTORE_PASSWORD = $KEYSTORE_PASSWORD" >> local.properties
echo "KEY_ALIAS = $KEY_ALIAS" >> local.properties
echo "KEY_PASSWORD = $KEY_PASSWORD" >> local.properties

- name: Generate Signed APK
env:
KEYSTORE: ${{ secrets.KEYSTORE }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}

run: |
./gradlew assembleRelease --build-cache -x test -x lint
ls -l app/build/outputs/apk/release/app-release.apk || { echo "apk not generated"; exit 1; }

- name: Extract Release Notes
id: release_notes
run: |
COMMIT_MSG=$(git log -1 --pretty=%B | sed 's/"/\\"/g' | tr -d '\n')
TRUNCATED_MSG="${COMMIT_MSG:0:500}"
echo "$TRUNCATED_MSG" > release_notes.txt
echo "notes=$TRUNCATED_MSG" >> $GITHUB_OUTPUT
echo "Release notes: $TRUNCATED_MSG"

- name: Upload APKs to Firebase App Distribution
env:
FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }}
FIREBASE_AUTH_TOKEN: ${{ secrets.FIREBASE_AUTH_TOKEN }}
run: |
npm install -g firebase-tools
firebase appdistribution:distribute \
app/build/outputs/apk/release/app-release.apk \
--app "$FIREBASE_APP_ID" \
--token "$FIREBASE_AUTH_TOKEN" \
--groups "cairo_squad" \
--release-notes-file release_notes.txt
83 changes: 83 additions & 0 deletions .github/workflows/cd-firebase.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: EvolveFit CD Pipeline

on:
push:
branches:
- develop
- master
- feature/cd-firebase

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '21'

- name: Cache Gradle
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
gradle-${{ runner.os }}-

- name: Make gradlew executable
run: chmod +x ./gradlew

- name: Create google-services.json
env:
GOOGLE_SERVICES_JSON_BASE64: ${{ secrets.GOOGLE_SERVICES_JSON_BASE64 }}
run: |
mkdir -p composeApp/ # Ensure the directory exists
echo "$GOOGLE_SERVICES_JSON_BASE64" | base64 --decode > composeApp/google-services.json
shell: bash

- name: Decode Keystore and Create local.properties
env:
KEYSTORE: ${{ secrets.KEYSTORE }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}

run: |
rm -f composeApp/JKS.jks local.properties release_notes.txt
echo "$KEYSTORE" | base64 -d > composeApp/JKS.jks
echo "KEYSTORE_PASSWORD = $KEYSTORE_PASSWORD" >> local.properties
echo "KEY_ALIAS = $KEY_ALIAS" >> local.properties
echo "KEY_PASSWORD = $KEY_PASSWORD" >> local.properties

- name: Generate Signed APK
env:
KEYSTORE: ${{ secrets.KEYSTORE }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}

run: |
./gradlew assembleRelease --build-cache -x test -x lint
ls -l composeApp/build/outputs/apk/release/composeApp-release.apk || { echo "apk not generated"; exit 1; }

- name: Upload APKs to Firebase App Distribution
env:
FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }}
FIREBASE_AUTH_TOKEN: ${{ secrets.FIREBASE_AUTH_TOKEN }}
run: |
npm install -g firebase-tools
firebase appdistribution:distribute \
composeApp/build/outputs/apk/release/composeApp-release.apk \
--app "$FIREBASE_APP_ID" \
--token "$FIREBASE_AUTH_TOKEN" \
--groups "cairo_squad" \
--release-notes-file release_notes.txt
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ plugins {
alias(libs.plugins.composeMultiplatform) apply false
alias(libs.plugins.composeCompiler) apply false
alias(libs.plugins.kotlinMultiplatform) apply false
alias(libs.plugins.googleFirebaseAppdistribution) apply false
alias(libs.plugins.googleGmsGoogleServices) apply false
}

repositories {
Expand Down
20 changes: 20 additions & 0 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import java.io.FileInputStream
import java.util.Properties
import kotlin.apply

plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidApplication)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
kotlin("plugin.serialization") version libs.versions.kotlin
alias(libs.plugins.googleFirebaseAppdistribution)
alias(libs.plugins.googleGmsGoogleServices)
alias(libs.plugins.ksp)
alias(libs.plugins.androidx.room)
}
Expand Down Expand Up @@ -113,6 +118,21 @@ android {
versionCode = 1
versionName = "1.0"
}
val localFile = file("${rootProject.projectDir}/local.properties")
val locals = Properties().apply {
if (localFile.exists()) {
load(FileInputStream(localFile))
}
}

signingConfigs {
create("release") {
storeFile = file("JKS")
storePassword = locals.getProperty("KEYSTORE_PASSWORD")
keyAlias = locals.getProperty("KEY_ALIAS")
keyPassword = locals.getProperty("KEY_PASSWORD")
}
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
Expand Down
7 changes: 7 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ lifecycleViewModel = "2.9.1"
filekit = "0.10.0"
ktor = "3.2.3"
core-splashscreen = "1.0.1"
googleFirebaseAppdistribution = "5.1.1"
googleGmsGoogleServices = "4.4.3"
room = "2.7.2"
sqlite = "2.5.2"
ksp = "2.2.0-2.0.2"
googleFirebaseAppdistribution = "5.1.1"
googleGmsGoogleServices = "4.4.3"

[libraries]
compose-shadow = { module = "com.adamglin:compose-shadow", version.ref = "composeShadow" }
Expand Down Expand Up @@ -88,6 +92,9 @@ composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "k
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
androidx-room = { id = "androidx.room", version.ref = "room" }
googleFirebaseAppdistribution = { id = "com.google.firebase.appdistribution", version.ref = "googleFirebaseAppdistribution" }
googleGmsGoogleServices = { id = "com.google.gms.google-services", version.ref = "googleGmsGoogleServices" }

[bundles]
ktor = [
"ktor-client-core",
Expand Down
Loading