Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
58d3e3e
feat: Integrate Firebase and configure release signing
mohamedshemees Feb 18, 2026
b35c992
Refactor: Separate dependency injection setup into multiple files
mohamedshemees Feb 18, 2026
eb18932
feat: Add Google client ID constants
mohamedshemees Feb 18, 2026
d19be78
feat: enhance CI/CD workflows for Android and iOS
mohamedshemees Feb 18, 2026
bbca852
feat: Integrate Firebase Remote Config for secrets management
mohamedshemees Feb 18, 2026
43d2e05
Refactor: add firebase config di and use the new secrets class in rep…
mohamedshemees Feb 18, 2026
c316e0e
feat: Remove old Flutter CI workflow
mohamedshemees Feb 18, 2026
ed81f28
refactor optimize unused code
mohamedshemees Feb 18, 2026
901fb19
Merge remote-tracking branch 'origin/dev' into feature/add-firebase-f…
mohamedshemees Feb 18, 2026
533575b
fix merge conflicts
mohamedshemees Feb 18, 2026
92020fc
fix: Update branch names in workflows
mohamedshemees Feb 19, 2026
ce7a702
Add Firebase token to flutterfire configuration command
mohamedshemees Feb 19, 2026
bea76da
Update Firebase options generation for Android
mohamedshemees Feb 19, 2026
7023005
feat: Integrate Firebase Performance Monitoring
mohamedshemees Feb 19, 2026
3d033f3
Update MinimumOSVersion to 15.0
mohamedshemees Feb 19, 2026
c5d4945
Update project.pbxproj
mohamedshemees Feb 19, 2026
abfba92
Update iOS deployment target to 15.0
mohamedshemees Feb 20, 2026
8a9a633
rollback iOS deployment target to 13.0
mohamedshemees Feb 20, 2026
611495d
refactor: update iOS deployment target to 15.0 and configure Podfile
yousef-osama11 Feb 23, 2026
a059d46
Merge remote-tracking branch 'origin/dev' into feature/add-firebase-f…
mohamedshemees Feb 25, 2026
db9ccad
fix merge conflicts
mohamedshemees Feb 25, 2026
01fde08
fix: update ios workflow to include dependency caching and firebase c…
mohamedshemees Feb 25, 2026
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
109 changes: 109 additions & 0 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
name: Flutter CI

on:
push:
branches: [ "dev" , "main" ]
pull_request:
branches: [ "dev" , "main" ]
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 45

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
channel: 'stable'
cache: true

- name: Cache Gradle packages
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Cache pub dependencies
uses: actions/cache@v3
with:
path: |
${{ env.PUB_CACHE }}
~/.pub-cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }}
restore-keys: |
${{ runner.os }}-pub-
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'

- name: Install Firebase CLI
run: npm install -g firebase-tools

- name: Install FlutterFire CLI
run: dart pub global activate flutterfire_cli
- name: Install dependencies
run: flutter pub get

- name: Generate local code
run: flutter pub run build_runner build --delete-conflicting-outputs

- name: Generate Firebase Options
env:
FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }}
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
run: flutterfire configure --project=$FIREBASE_PROJECT_ID -y --platforms=android --out=lib/firebase_options.dart --token=$FIREBASE_TOKEN --android-package-name=com.pennypilot.moneyplus

- name: Configure Gradle memory
run: |
mkdir -p ~/.gradle
cat > ~/.gradle/gradle.properties << EOF
org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError
org.gradle.daemon=false
org.gradle.parallel=true
org.gradle.caching=true
android.useAndroidX=true
android.enableJetifier=true
EOF
- name: Decode keystore
env:
ANDROID_KEYSTORE_BASE64: ${{ secrets.SIGNING_KEY_BASE64 }}
run: echo "$ANDROID_KEYSTORE_BASE64" | base64 --decode > android/app/upload-keystore.jks

- name: Create key.properties
env:
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEY_ALIAS_PASSWORD: ${{ secrets.ANDROID_KEY_ALIAS_PASSWORD }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
run: |
cat <<EOF > android/key.properties
storePassword=$ANDROID_KEYSTORE_PASSWORD
keyPassword=$ANDROID_KEY_ALIAS_PASSWORD
keyAlias=$ANDROID_KEY_ALIAS
storeFile=upload-keystore.jks
EOF
- name: Build release APK
timeout-minutes: 30
run: flutter build apk --release --obfuscate --split-debug-info=build/app/outputs/symbols

- name: Distribute to Firebase
env:
FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }}
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
run: |
firebase appdistribution:distribute build/app/outputs/flutter-apk/app-release.apk \
--app "$FIREBASE_APP_ID" \
--groups "closed-beta-testers" \
--release-notes "Build from ${{ github.ref_name }} - Commit: ${{ github.sha }}"
59 changes: 0 additions & 59 deletions .github/workflows/flutter_build.yml

This file was deleted.

66 changes: 66 additions & 0 deletions .github/workflows/ios.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Flutter CI iOS

on:
push:
branches: [ "dev", "main" ]
pull_request:
branches: [ "dev", "main" ]
workflow_dispatch:

jobs:
build-ios:
runs-on: macos-latest
timeout-minutes: 60

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
channel: 'stable'
cache: true

- name: Cache pub dependencies
uses: actions/cache@v3
with:
path: |
${{ env.PUB_CACHE }}
~/.pub-cache
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }}
restore-keys: |
${{ runner.os }}-pub-
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'

- name: Install Firebase CLI
run: npm install -g firebase-tools

- name: Install FlutterFire CLI
run: dart pub global activate flutterfire_cli

- name: Install dependencies
run: flutter pub get

- name: Generate local code
run: flutter pub run build_runner build --delete-conflicting-outputs

- name: Generate Firebase Options
env:
FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }}
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
run: |
flutterfire configure \
--project=$FIREBASE_PROJECT_ID \
-y \
--platforms=ios \
--out=lib/firebase_options.dart \
--token=$FIREBASE_TOKEN \
--ios-bundle-id=com.pennypilot.moneyplus
- name: Build iOS (simulator)
run: flutter build ios --simulator --no-codesign
54 changes: 40 additions & 14 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,15 +1,34 @@
import java.util.Properties
import java.io.FileInputStream
plugins {
id("com.android.application")
// START: FlutterFire Configuration
id("com.google.gms.google-services")
id("com.google.firebase.crashlytics")
// END: FlutterFire Configuration
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}

val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}

android {
namespace = "com.pennypilot.moneyplus"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion

defaultConfig {
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
Expand All @@ -19,26 +38,33 @@ android {
jvmTarget = JavaVersion.VERSION_17.toString()
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.pennypilot.moneyplus"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
signingConfigs {
create("release") {
keyAlias = keystoreProperties.getProperty("keyAlias")
keyPassword = keystoreProperties.getProperty("keyPassword")
storeFile = file(keystoreProperties.getProperty("storeFile"))
storePassword = keystoreProperties.getProperty("storePassword")
}
}

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")

getByName("release") {
signingConfig = signingConfigs.getByName("release")
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
ndk {
abiFilters.clear()
abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a"))
}

}
}
}

flutter {
source = "../.."
}
4 changes: 4 additions & 0 deletions android/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ pluginManagement {
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.11.1" apply false
// START: FlutterFire Configuration
id("com.google.gms.google-services") version("4.3.15") apply false
id("com.google.firebase.crashlytics") version("2.8.1") apply false
// END: FlutterFire Configuration
id("org.jetbrains.kotlin.android") version "2.2.20" apply false
}

Expand Down
2 changes: 1 addition & 1 deletion ios/Flutter/AppFrameworkInfo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>13.0</string>
<string>15.0</string>
</dict>
</plist>
46 changes: 46 additions & 0 deletions ios/Podfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Uncomment this line to define a global platform for your project
platform :ios, '15.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}

def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end

File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end

require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)

flutter_ios_podfile_setup

target 'Runner' do
use_frameworks!

flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end

post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.0'
end
end
end
2 changes: 1 addition & 1 deletion ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand Down
Loading