feat: Add Codemagic environment variables and update Firebase configurations for multi-environment support

This commit is contained in:
Achintha Isuru
2025-11-18 12:16:42 -05:00
parent fbb33d025a
commit 9eacb8639e
6 changed files with 214 additions and 10 deletions

101
codemagic-env-vars.md Normal file
View File

@@ -0,0 +1,101 @@
# Codemagic Environment Variables
This document outlines the environment variables required for the Codemagic CI/CD pipelines defined in `codemagic.yaml`. These variables should be configured in your Codemagic project under **Environment variables**.
## Client App (`client-app`)
---
### Group: `client_app_dev_credentials`
| Variable Name | Example Value | Secure | Description |
| :--- | :--- | :--- | :--- |
| `FLAVOR` | `dev` | No | The Flutter flavor to use for the build. |
| `FIREBASE_APP_ID_ANDROID` | `1:DEV_ANDROID_APP_ID` | No | The Firebase App ID for the Android app (Dev). |
| `FIREBASE_APP_ID_IOS` | `1:DEV_IOS_APP_ID` | No | The Firebase App ID for the iOS app (Dev). |
| `FIREBASE_TESTER_GROUPS` | `developers` | No | Comma-separated list of Firebase tester groups. |
| `FIREBASE_TOKEN` | `(your_firebase_token)` | Yes | Your Firebase CLI token. |
| `GOOGLE_SERVICES_JSON` | `(contents of google-services.json)` | Yes | Contents of your `google-services.json` file for Android (Dev). |
| `GOOGLE_SERVICE_INFO_PLIST` | `(contents of GoogleService-Info.plist)` | Yes | Contents of your `GoogleService-Info.plist` file for iOS (Dev). |
| `KEYSTORE_PASSWORD` | `(your_keystore_password)` | Yes | Password for the Android keystore. |
| `KEY_ALIAS` | `(your_key_alias)` | Yes | Alias for the key in the Android keystore. |
| `KEY_PASSWORD` | `(your_key_password)` | Yes | Password for the key in the Android keystore. |
### Group: `client_app_staging_credentials`
| Variable Name | Example Value | Secure | Description |
| :--- | :--- | :--- | :--- |
| `FLAVOR` | `staging` | No | The Flutter flavor to use for the build. |
| `FIREBASE_APP_ID_ANDROID` | `1:STAGING_ANDROID_APP_ID` | No | The Firebase App ID for the Android app (Staging). |
| `FIREBASE_APP_ID_IOS` | `1:STAGING_IOS_APP_ID` | No | The Firebase App ID for the iOS app (Staging). |
| `FIREBASE_TESTER_GROUPS` | `qa-team, stakeholders` | No | Comma-separated list of Firebase tester groups. |
| `FIREBASE_TOKEN` | `(your_firebase_token)` | Yes | Your Firebase CLI token. |
| `GOOGLE_SERVICES_JSON` | `(contents of google-services.json)` | Yes | Contents of your `google-services.json` file for Android (Staging). |
| `GOOGLE_SERVICE_INFO_PLIST` | `(contents of GoogleService-Info.plist)` | Yes | Contents of your `GoogleService-Info.plist` file for iOS (Staging). |
| `KEYSTORE_PASSWORD` | `(your_keystore_password)` | Yes | Password for the Android keystore. |
| `KEY_ALIAS` | `(your_key_alias)` | Yes | Alias for the key in the Android keystore. |
| `KEY_PASSWORD` | `(your_key_password)` | Yes | Password for the key in the Android keystore. |
### Group: `client_app_prod_credentials`
| Variable Name | Example Value | Secure | Description |
| :--- | :--- | :--- | :--- |
| `FLAVOR` | `prod` | No | The Flutter flavor to use for the build. |
| `FIREBASE_APP_ID_ANDROID` | `1:PROD_ANDROID_APP_ID` | No | The Firebase App ID for the Android app (Prod). |
| `FIREBASE_APP_ID_IOS` | `1:PROD_IOS_APP_ID` | No | The Firebase App ID for the iOS app (Prod). |
| `FIREBASE_TESTER_GROUPS` | `(empty or specific group)` | No | Comma-separated list of Firebase tester groups. |
| `FIREBASE_TOKEN` | `(your_firebase_token)` | Yes | Your Firebase CLI token. |
| `GOOGLE_SERVICES_JSON` | `(contents of google-services.json)` | Yes | Contents of your `google-services.json` file for Android (Prod). |
| `GOOGLE_SERVICE_INFO_PLIST` | `(contents of GoogleService-Info.plist)` | Yes | Contents of your `GoogleService-Info.plist` file for iOS (Prod). |
| `KEYSTORE_PASSWORD` | `(your_keystore_password)` | Yes | Password for the Android keystore. |
| `KEY_ALIAS` | `(your_key_alias)` | Yes | Alias for the key in the Android keystore. |
| `KEY_PASSWORD` | `(your_key_password)` | Yes | Password for the key in the Android keystore. |
## Staff App (`staff-app`)
---
### Group: `staff_app_dev_credentials`
| Variable Name | Example Value | Secure | Description |
| :--- | :--- | :--- | :--- |
| `FLAVOR` | `dev` | No | The Flutter flavor to use for the build. |
| `FIREBASE_APP_ID_ANDROID` | `1:DEV_ANDROID_APP_ID` | No | The Firebase App ID for the Android app (Dev). |
| `FIREBASE_APP_ID_IOS` | `1:DEV_IOS_APP_ID` | No | The Firebase App ID for the iOS app (Dev). |
| `FIREBASE_TESTER_GROUPS` | `developers` | No | Comma-separated list of Firebase tester groups. |
| `FIREBASE_TOKEN` | `(your_firebase_token)` | Yes | Your Firebase CLI token. |
| `GOOGLE_SERVICES_JSON` | `(contents of google-services.json)` | Yes | Contents of your `google-services.json` file for Android (Dev). |
| `GOOGLE_SERVICE_INFO_PLIST` | `(contents of GoogleService-Info.plist)` | Yes | Contents of your `GoogleService-Info.plist` file for iOS (Dev). |
| `KEYSTORE_PASSWORD` | `(your_keystore_password)` | Yes | Password for the Android keystore. |
| `KEY_ALIAS` | `(your_key_alias)` | Yes | Alias for the key in the Android keystore. |
| `KEY_PASSWORD` | `(your_key_password)` | Yes | Password for the key in the Android keystore. |
### Group: `staff_app_staging_credentials`
| Variable Name | Example Value | Secure | Description |
| :--- | :--- | :--- | :--- |
| `FLAVOR` | `staging` | No | The Flutter flavor to use for the build. |
| `FIREBASE_APP_ID_ANDROID` | `1:STAGING_ANDROID_APP_ID` | No | The Firebase App ID for the Android app (Staging). |
| `FIREBASE_APP_ID_IOS` | `1:STAGING_IOS_APP_ID` | No | The Firebase App ID for the iOS app (Staging). |
| `FIREBASE_TESTER_GROUPS` | `qa-team, stakeholders` | No | Comma-separated list of Firebase tester groups. |
| `FIREBASE_TOKEN` | `(your_firebase_token)` | Yes | Your Firebase CLI token. |
| `GOOGLE_SERVICES_JSON` | `(contents of google-services.json)` | Yes | Contents of your `google-services.json` file for Android (Staging). |
| `GOOGLE_SERVICE_INFO_PLIST` | `(contents of GoogleService-Info.plist)` | Yes | Contents of your `GoogleService-Info.plist` file for iOS (Staging). |
| `KEYSTORE_PASSWORD` | `(your_keystore_password)` | Yes | Password for the Android keystore. |
| `KEY_ALIAS` | `(your_key_alias)` | Yes | Alias for the key in the Android keystore. |
| `KEY_PASSWORD` | `(your_key_password)` | Yes | Password for the key in the Android keystore. |
### Group: `staff_app_prod_credentials`
| Variable Name | Example Value | Secure | Description |
| :--- | :--- | :--- | :--- |
| `FLAVOR` | `prod` | No | The Flutter flavor to use for the build. |
| `FIREBASE_APP_ID_ANDROID` | `1:PROD_ANDROID_APP_ID` | No | The Firebase App ID for the Android app (Prod). |
| `FIREBASE_APP_ID_IOS` | `1:PROD_IOS_APP_ID` | No | The Firebase App ID for the iOS app (Prod). |
| `FIREBASE_TESTER_GROUPS` | `(empty or specific group)` | No | Comma-separated list of Firebase tester groups. |
| `FIREBASE_TOKEN` | `(your_firebase_token)` | Yes | Your Firebase CLI token. |
| `GOOGLE_SERVICES_JSON` | `(contents of google-services.json)` | Yes | Contents of your `google-services.json` file for Android (Prod). |
| `GOOGLE_SERVICE_INFO_PLIST` | `(contents of GoogleService-Info.plist)` | Yes | Contents of your `GoogleService-Info.plist` file for iOS (Prod). |
| `KEYSTORE_PASSWORD` | `(your_keystore_password)` | Yes | Password for the Android keystore. |
| `KEY_ALIAS` | `(your_key_alias)` | Yes | Alias for the key in the Android keystore. |
| `KEY_PASSWORD` | `(your_key_password)` | Yes | Password for the key in the Android keystore. |

View File

@@ -3,14 +3,13 @@ build-script: &build-script
name: Build Flutter App name: Build Flutter App
script: | script: |
flutter pub get flutter pub get
# Uncomment the line below if you use build_runner flutter pub run build_runner build --delete-conflicting-outputs
# flutter pub run build_runner build --delete-conflicting-outputs
# Build Android # Build Android
flutter build appbundle --flavor $FLAVOR flutter build appbundle --flavor $FLAVOR
# Build iOS # Build iOS
flutter build ipa --flavor $FLAVOR --export-options-plist=$FCI_BUILD_DIR/mobile-apps/client-app/ios/exportOptions.plist flutter build ipa --flavor $FLAVOR --export-options-plist=$FCI_WORKING_DIRECTORY/ios/exportOptions.plist
# Reusable script for distributing to Firebase # Reusable script for distributing to Firebase
distribute-script: &distribute-script distribute-script: &distribute-script

View File

@@ -5,6 +5,42 @@
"storage_bucket": "krow-workforce-dev.firebasestorage.app" "storage_bucket": "krow-workforce-dev.firebasestorage.app"
}, },
"client": [ "client": [
{
"client_info": {
"mobilesdk_app_id": "1:933560802882:android:edcddb83ea4bbb517757db",
"android_client_info": {
"package_name": "com.krow.app.business.dev"
}
},
"oauth_client": [
{
"client_id": "933560802882-grp98a1v7amflnnup68vh01tj06eaem1.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDBYhflhK6DThKnS7RM-9raKdvyKzLUjY4"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "933560802882-grp98a1v7amflnnup68vh01tj06eaem1.apps.googleusercontent.com",
"client_type": 3
},
{
"client_id": "933560802882-ml2526jqnnsteent4i9li50c00hisoge.apps.googleusercontent.com",
"client_type": 2,
"ios_info": {
"bundle_id": "com.krow.app.business.dev"
}
}
]
}
}
},
{ {
"client_info": { "client_info": {
"mobilesdk_app_id": "1:933560802882:android:f4587798877cbb917757db", "mobilesdk_app_id": "1:933560802882:android:f4587798877cbb917757db",
@@ -31,10 +67,10 @@
"client_type": 3 "client_type": 3
}, },
{ {
"client_id": "933560802882-qgbq6m04moicvkff2b3i6p9agu7i4gou.apps.googleusercontent.com", "client_id": "933560802882-ml2526jqnnsteent4i9li50c00hisoge.apps.googleusercontent.com",
"client_type": 2, "client_type": 2,
"ios_info": { "ios_info": {
"bundle_id": "com.krow.app.dev" "bundle_id": "com.krow.app.business.dev"
} }
} }
] ]

View File

@@ -5,6 +5,25 @@
"storage_bucket": "krow-workforce-staging.firebasestorage.app" "storage_bucket": "krow-workforce-staging.firebasestorage.app"
}, },
"client": [ "client": [
{
"client_info": {
"mobilesdk_app_id": "1:1032971403708:android:d35f6d13a9e03bcb356bb9",
"android_client_info": {
"package_name": "com.krow.app.business.staging"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyAZ4dOatvf3ZBt4qnbSlIvJ51bblHaRsRw"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
},
{ {
"client_info": { "client_info": {
"mobilesdk_app_id": "1:1032971403708:android:87edb39679f806ab356bb9", "mobilesdk_app_id": "1:1032971403708:android:87edb39679f806ab356bb9",

View File

@@ -32,12 +32,42 @@
"uploadDebugSymbols": false, "uploadDebugSymbols": false,
"fileOutput": "ios/Runner/GoogleService-Info.plist" "fileOutput": "ios/Runner/GoogleService-Info.plist"
}, },
"targets": { "buildConfigurations": {
"Runner": { "Debug-dev": {
"projectId": "krow-workforce-dev", "projectId": "krow-workforce-dev",
"appId": "1:1032971403708:ios:1d9b09307e6f3983356bb9", "appId": "1:933560802882:ios:07becdd41ac6ca627757db",
"uploadDebugSymbols": false, "uploadDebugSymbols": false,
"fileOutput": "ios/flavors/dev/GoogleService-Info.plist" "fileOutput": "ios/flavors/dev/GoogleService-Info.plist"
},
"Profile-dev": {
"projectId": "krow-workforce-dev",
"appId": "1:933560802882:ios:07becdd41ac6ca627757db",
"uploadDebugSymbols": false,
"fileOutput": "ios/flavors/dev/GoogleService-Info.plist"
},
"Release-dev": {
"projectId": "krow-workforce-dev",
"appId": "1:933560802882:ios:07becdd41ac6ca627757db",
"uploadDebugSymbols": false,
"fileOutput": "ios/flavors/dev/GoogleService-Info.plist"
},
"Debug-staging": {
"projectId": "krow-workforce-staging",
"appId": "1:1032971403708:ios:1d9b09307e6f3983356bb9",
"uploadDebugSymbols": false,
"fileOutput": "ios/flavors/staging/GoogleService-Info.plist"
},
"Profile-staging": {
"projectId": "krow-workforce-staging",
"appId": "1:1032971403708:ios:1d9b09307e6f3983356bb9",
"uploadDebugSymbols": false,
"fileOutput": "ios/flavors/staging/GoogleService-Info.plist"
},
"Release-staging": {
"projectId": "krow-workforce-staging",
"appId": "1:1032971403708:ios:1d9b09307e6f3983356bb9",
"uploadDebugSymbols": false,
"fileOutput": "ios/flavors/staging/GoogleService-Info.plist"
} }
} }
}, },

View File

@@ -249,6 +249,7 @@
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
924B93AB74D97EF4B42824EC /* [CP] Embed Pods Frameworks */, 924B93AB74D97EF4B42824EC /* [CP] Embed Pods Frameworks */,
8A3E049698DB74713226DAC2 /* [CP] Copy Pods Resources */, 8A3E049698DB74713226DAC2 /* [CP] Copy Pods Resources */,
CA84EF6F10FA3C39D36D57BC /* FlutterFire: "flutterfire bundle-service-file" */,
); );
buildRules = ( buildRules = (
); );
@@ -456,6 +457,24 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
}; };
CA84EF6F10FA3C39D36D57BC /* FlutterFire: "flutterfire bundle-service-file" */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "FlutterFire: \"flutterfire bundle-service-file\"";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\n#!/bin/bash\nPATH=\"${PATH}:$FLUTTER_ROOT/bin:${PUB_CACHE}/bin:$HOME/.pub-cache/bin\"\nflutterfire bundle-service-file --plist-destination=\"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app\" --build-configuration=${CONFIGURATION} --platform=ios --apple-project-path=\"${SRCROOT}\"\n";
};
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */