Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
03f18b0
feat: Added cleanup runs on a different isolate for unlinked media
austin047 Feb 5, 2026
d0ec08e
feat: Remove phone number from registration
austin047 Feb 8, 2026
4e14a0e
Add iOS build workflow
austin047 Feb 8, 2026
125953d
feat: Add flavors and pod runner config
austin047 Feb 8, 2026
58aa715
feat: Added flutter fire to cli
austin047 Feb 9, 2026
b28205d
feat(ci): Update fastlane and flavor support
austin047 Feb 10, 2026
4cd8959
feat: Update the pipeline to send out to testers tmp
austin047 Feb 11, 2026
7e8fdba
feat: Update the pipeline to send out to testers tmp
austin047 Feb 11, 2026
fcb4215
fix: Resolve deprication warnings for radio switch and dropdown buttons
austin047 Feb 11, 2026
168f778
chore: Update firebase config staging setup and build entries
austin047 Feb 11, 2026
1b51cf8
feat: Increase flutter version of project to the latest
austin047 Feb 11, 2026
9311f0f
feat: Correct firebase testers group
austin047 Feb 11, 2026
8df9358
feat: Added neccessary gems
austin047 Feb 12, 2026
dab5825
feat: Added step to run bundle install in ci
austin047 Feb 12, 2026
7ef56d7
chore(ios): Update gemfile lock to match gemfile
austin047 Feb 12, 2026
4f41132
chore(ios): Remove dev from cert profile
austin047 Feb 12, 2026
2160387
chore: Update podfile.lock
kofimokome Feb 12, 2026
8d23baa
chore: IOS deployment fixes
kofimokome Mar 4, 2026
0c89874
fix: Update ios icons
osong256 Mar 4, 2026
cffee6a
fix: Asset icons xcassets
austin047 Mar 4, 2026
5f3a61a
feat: Setup flutter fire
austin047 Mar 4, 2026
ea654a4
fix: Update profile identfier mapping
austin047 Mar 5, 2026
a273316
fix: Syntax error in Fastfile
austin047 Mar 5, 2026
5debba1
fix: Correct crashlytics path
austin047 Mar 5, 2026
12b8997
fix: Include Usage description for info plist
austin047 Mar 5, 2026
d25326d
ci: Update the xcode-version
austin047 Mar 5, 2026
c07b963
fix: Specify apple not using encryption
austin047 Mar 5, 2026
f2c00a5
feat: Added icons for different flavours
austin047 Mar 5, 2026
44ed1b7
fix: Remove env passing for application'
austin047 Mar 5, 2026
b541a45
ci: Update cli
austin047 Mar 6, 2026
2ed0f8d
ci: Pass flavour in the cli and remove dart env
austin047 Mar 6, 2026
e630221
ci: Fix github action issues
austin047 Mar 6, 2026
0dfe3db
ci: Set up the keystore
austin047 Mar 6, 2026
70d4f00
ci: Fix production release path
austin047 Mar 6, 2026
0358e8e
fix: Ai bot issues
austin047 Mar 6, 2026
7ec61af
refactor: Remove unusead listerner
austin047 Mar 6, 2026
c73f751
refactor: Remove un used file
austin047 Mar 6, 2026
5591c89
ci: Optimize build workflow
austin047 Mar 6, 2026
e021e4e
ci: Add flutter fire to ios build
austin047 Mar 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .fvmrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"flutter": "3.32.8"
"flutter": "3.38.9"
}
65 changes: 65 additions & 0 deletions .github/ENV_AND_SECRETS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# GitHub Actions: Secrets and Variables neccessary for faslane deployment

Configure these in your repo: **Settings → Secrets and variables → Actions**.

Use **Secrets** for sensitive values; use **Variables** for non-sensitive identifiers.

---

## iOS (Match + App Store Connect)

| Name | Type | Used by | Description |
|------|------|---------|-------------|
| `MATCH_DEPLOY_KEY` | Secret | deploy-with-fastlane, ios-setup, ios-release | Private SSH key that has read (and for setup, write) access to the certificates repo. Used by `webfactory/ssh-agent`. |
| `MATCH_PASSWORD` | Secret | deploy-with-fastlane, ios-setup, ios-release | Password for the Match-encrypted certs/profiles in the repo. |
| `ASC_KEY_ID` | Secret | deploy-with-fastlane, ios-setup, ios-release | App Store Connect API key ID. |
| `ASC_ISSUER_ID` | Secret | deploy-with-fastlane, ios-setup, ios-release | App Store Connect issuer ID. |
| `ASC_KEY_P8_BASE64` | Secret | deploy-with-fastlane, ios-setup, ios-release | App Store Connect API private key (.p8) content, **base64-encoded**. |
| `APP_BUNDLE_ID` | Variable | deploy-with-fastlane, ios-release (prod) | Production iOS bundle ID, e.g. `com.whilesmart.trakli`. |
| `CREDENTIAL_FILE_CONTENT` | Secret | ios-setup, ios-release | Same as Android: Firebase/service account JSON **raw string**. Written to `service_credentials_content.json` for iOS lanes (e.g. release_firebase, Crashlytics). |
| `FIREBASE_APP_ID` | Secret | ios-release (firebase track), android-release (firebase) | Firebase app ID. For iOS dev distribution use this, or set `FIREBASE_APP_ID_IOS_DEV` for the iOS dev app. |
| `FIREBASE_APP_ID_IOS_DEV` | Secret | ios-release (firebase track) | Optional. iOS dev Firebase app ID for App Distribution. If unset, `release_firebase` falls back to `FIREBASE_APP_ID`. |

**Optional (only if you use a different cert repo):**

| Name | Type | Description |
|------|------|-------------|
| `MATCH_GIT_URL` | Secret or Variable | Git URL for the Match repo, e.g. `git@github.com:whilesmart/certificates.git`. Default in Matchfile is `git@github.com:whilesmart/certificates.git`. |

---

## Android

| Name | Type | Used by | Description |
|------|------|---------|-------------|
| `GOOGLE_SERVICES_ACCOUNT_BASE64` | Secret | deploy-with-fastlane, android-release | Google Play service account JSON, **base64-encoded**. Decoded to `google_service_account.json` in repo root. |
| `CREDENTIAL_FILE_CONTENT` | Secret | deploy-with-fastlane, android-release, ios-setup, ios-release | Firebase / Google service account JSON **raw string** for distribution. Written to `service_credentials_content.json`. |
| `ANDROID_KEYSTORE_FILE_BASE64` | Secret | deploy-with-fastlane | Release keystore (.jks) file content, **base64-encoded**. |
| `ANDROID_KEYSTORE_PASSWORD` | Secret | deploy-with-fastlane | Keystore and key password. |
| `APP_PACKAGE_NAME` | Variable | deploy-with-fastlane, android-release | Android applicationId, e.g. `com.whilesmart.trakli`. |
| `FIREBASE_APP_ID` | Secret | android-release (firebase track) | Firebase Android app ID (for App Distribution). |

---

## Summary checklist

**Secrets (Actions → Secrets):**

- `MATCH_DEPLOY_KEY`
- `MATCH_PASSWORD`
- `ASC_KEY_ID`
- `ASC_ISSUER_ID`
- `ASC_KEY_P8_BASE64`
- `GOOGLE_SERVICES_ACCOUNT_BASE64`
- `CREDENTIAL_FILE_CONTENT`
- `ANDROID_KEYSTORE_FILE_BASE64`
- `ANDROID_KEYSTORE_PASSWORD`
- `FIREBASE_APP_ID` (if using Android or iOS Firebase App Distribution)
- `FIREBASE_APP_ID_IOS_DEV` (optional; for iOS dev Firebase track; falls back to `FIREBASE_APP_ID`)

**Variables (Actions → Variables):**

- `APP_BUNDLE_ID` (e.g. `com.whilesmart.trakli`)
- `APP_PACKAGE_NAME` (e.g. `com.whilesmart.trakli`)

**Certificates repo:** Ensure the repo used by Match (default: `git@github.com:whilesmart/certificates.git`) exists and that the deploy key has access. Run **iOS Certificate Setup** (ios-setup.yml) once via workflow_dispatch to generate/update certs and profiles for `com.whilesmart.trakli`, `com.whilesmart.trakli.dev`, and `com.whilesmart.trakli.stg`. Staging uses bundle ID `com.whilesmart.trakli.stg`; no extra secrets beyond MATCH/ASC_*.
38 changes: 38 additions & 0 deletions .github/workflows/README-FASTLANE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Fastlane in GitHub Actions – verification summary

## Gemfile layout (aligned with mindpad)

- **iOS**: `ios/fastlane/Gemfile` (fastlane + cocoapods + plugins). `ios/Gemfile` evals it so workflows using `working-directory: ios` still work.
- **Android**: `android/fastlane/Gemfile` (fastlane + plugins). `android/Gemfile` at repo root is still used by deploy-with-fastlane.

## Workflows and lanes

| Workflow | Job / step | Working dir | Lanes used | Status |
|----------|------------|-------------|------------|--------|
| **ios-release.yml** | Setup Ruby | `ios/fastlane` | — | ✓ Uses `ios/fastlane/Gemfile` |
| **ios-release.yml** | Release to TestFlight (Dev/Staging/Prod) | `ios/fastlane` | `release_testflight_dev`, `release_testflight_staging`, `release_app_store` | ✓ |
| **ios-release.yml** | Release to Firebase | `ios/fastlane` | `release_firebase` | ✓ |
| **android-release.yml** | Setup Ruby | `android/fastlane` | — | ✓ Uses `android/fastlane/Gemfile` |
| **android-release.yml** | Release to Firebase / Play Store | `android/fastlane` | `release_play_store_using_firebase`, `release_play_store` | ✓ |
| **deploy-with-fastlane.yaml** | iOS: Set up Ruby, pod install, fastlane | `ios` | `release_app_store` | ✓ `ios/Gemfile` evals `fastlane/Gemfile` |
| **deploy-with-fastlane.yaml** | Android: Set up Ruby, fastlane | `android` | `release_play_store` | ✓ Uses `android/Gemfile` |
| **ios-setup.yml** | Setup Ruby, fastlane | `ios` | `setup_certificates` | ✓ `ios/Gemfile` evals `fastlane/Gemfile` |

## Build number and version

- **Root `Fastfile`**: `get_build_number(store, app_identifier)` uses `get_new_build_number` (from `fastlane-plugin-get_new_build_number`) to fetch the next build from App Store Connect / Play Store.
- **Root `Fastfile`**: `get_version_from_pubspec` reads `pubspec.yaml` for the version.
- **Plugins**: `fastlane-plugin-versioning` (iOS) and `fastlane-plugin-versioning_android` (Android) are available for reading/incrementing version in native projects; the main lanes still rely on the root Fastfile helpers above.

## After adding or changing gems

From repo root:

```bash
cd ios/fastlane && bundle install && cd ../..
cd android/fastlane && bundle install && cd ../..
# If you use working-directory: ios in CI, also:
cd ios && bundle install && cd ..
```

Commit any updated `Gemfile.lock` files.
83 changes: 83 additions & 0 deletions .github/workflows/android-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Android Release (Main + Manual)

on:
push:
branches:
- dev
workflow_dispatch:
inputs:
track:
description: 'Release track'
required: true
default: 'firebase'
type: choice
options:
- firebase
- playstore

jobs:
build-and-release:
name: Android Release Pipeline
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'

- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: "3.38.9"
channel: 'stable'
cache: true

- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
working-directory: android/fastlane

- name: Install Fastlane gems
working-directory: android/fastlane
run: bundle install

- name: Setup Service Accounts
env:
GOOGLE_SERVICES_ACCOUNT_BASE64: ${{ secrets.GOOGLE_SERVICES_ACCOUNT_BASE64 }}
CREDENTIAL_FILE_CONTENT: ${{ secrets.CREDENTIAL_FILE_CONTENT }}
run: |
printf '%s' "$GOOGLE_SERVICES_ACCOUNT_BASE64" | base64 --decode > google_service_account.json
printf '%s' "$CREDENTIAL_FILE_CONTENT" > service_credentials_content.json

- name: Setup Android signing keystore
run: |
printf '%s' "${{ secrets.ANDROID_KEYSTORE_FILE_BASE64 }}" | base64 --decode > android/key.jks

- name: Setup Android key.properties
run: |
cat <<EOF > android/key.properties
storePassword=${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
keyPassword=${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
keyAlias=release
storeFile=../key.jks
EOF

- name: Release to Firebase
if: ${{ github.event_name == 'push' || github.event.inputs.track == 'firebase' }}
working-directory: android/fastlane
run: bundle exec fastlane release_play_store_using_firebase
env:
APP_PACKAGE_NAME: ${{ vars.APP_PACKAGE_NAME }}
FIREBASE_APP_ID: ${{ secrets.FIREBASE_APP_ID }}

- name: Release to Play Store
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.track == 'playstore' }}
working-directory: android/fastlane
run: bundle exec fastlane release_play_store
env:
APP_PACKAGE_NAME: ${{ vars.APP_PACKAGE_NAME }}
151 changes: 117 additions & 34 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,49 @@
name: Check, Test and Build

on:
push:
branches:
- main
- dev
# push:
# branches:
# - dev
Comment on lines +4 to +6
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

pull_request:

concurrency:
group: check-test-build-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
FLUTTER_CHANNEL: "stable"
FLUTTER_VERSION: "3.32.8"
FLUTTER_VERSION: "3.38.9"
RUBY_VERSION: "3.2.2"
XCODE_VERSION: "26"

jobs:
changes:
name: Detect changed platforms
runs-on: ubuntu-latest
outputs:
android: ${{ steps.filter.outputs.android }}
ios: ${{ steps.filter.outputs.ios }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Detect changes
id: filter
uses: dorny/paths-filter@v3
with:
filters: |
android:
- 'lib/**'
- 'android/**'
- 'pubspec.yaml'
- 'pubspec.lock'
- '.github/workflows/build.yml'
ios:
- 'lib/**'
- 'ios/**'
- 'pubspec.yaml'
- 'pubspec.lock'
- '.github/workflows/build.yml'

analyze:
name: Analyze code (SAST)
runs-on: ubuntu-latest
Expand Down Expand Up @@ -51,7 +82,8 @@ jobs:
build-android:
name: Build APK
runs-on: ubuntu-latest
needs: test
needs: [changes, test]
if: needs.changes.outputs.android == 'true'
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand Down Expand Up @@ -79,38 +111,89 @@ jobs:
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}

- name: Build APK
run: flutter build apk --dart-define=ENV=dev

- name: Upload APK
uses: actions/upload-artifact@v4
with:
name: apk
path: build/app/outputs/flutter-apk/

distribute:
name: Upload artifact to Firebase App Distribution
runs-on: ubuntu-latest
needs: build-android
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev')
run: flutter build apk --flavor staging --target lib/main_staging.dart

# - name: Upload APK
# uses: actions/upload-artifact@v4
# with:
# name: apk
# path: build/app/outputs/flutter-apk/

build-ios:
name: Build iOS
runs-on: macos-latest
needs: [changes, test]
if: needs.changes.outputs.ios == 'true'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download app APK
uses: actions/download-artifact@v4

- name: Setup Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
name: apk
- name: Upload artifact to Firebase App Distribution
id: uploadArtifact
env:
INPUT_APPID: ${{secrets.FIREBASE_APP_ID}}
INPUT_SERVICECREDENTIALSFILECONTENT: ${{ secrets.CREDENTIAL_FILE_CONTENT }}
GOOGLE_APPLICATION_CREDENTIALS: service_credentials_content.json
INPUT_GROUPS: testers
INPUT_FILE: app-release.apk
run: |
cat <<< "${INPUT_SERVICECREDENTIALSFILECONTENT}" > service_credentials_content.json
sudo npm install -g firebase-tools
firebase appdistribution:distribute "$INPUT_FILE" --app "$INPUT_APPID" --groups "$INPUT_GROUPS" --testers "$INPUT_TESTERS" --release-notes "$(git log -1 --pretty=short)"
xcode-version: ${{ env.XCODE_VERSION }}

- name: Restore DerivedData cache
uses: actions/cache/restore@v4
id: cache-deriveddata
with:
path: DerivedData
key: deriveddata-${{ github.run_id }}
restore-keys: |
deriveddata-

- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
channel: ${{ env.FLUTTER_CHANNEL }}
cache: true

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

- name: Add pub cache bin to PATH
run: echo "$HOME/.pub-cache/bin" >> $GITHUB_PATH

- name: Verify FlutterFire CLI
run: flutterfire --version

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

- name: Build iOS
run: flutter build ipa --flavor staging --target lib/main_staging.dart --no-codesign

# - name: Upload IPA
# uses: actions/upload-artifact@v4
# with:
# name: ipa
# path: build/ios/ipa/

# distribute:
# name: Upload artifact to Firebase App Distribution
# runs-on: ubuntu-latest
# needs: build-android
# if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev')
# steps:
# - name: Checkout repository
# uses: actions/checkout@v4
# - name: Download app APK
# uses: actions/download-artifact@v4
# with:
# name: apk
# - name: Upload artifact to Firebase App Distribution
# id: uploadArtifact
# env:
# INPUT_APPID: ${{secrets.FIREBASE_APP_ID}}
# INPUT_SERVICECREDENTIALSFILECONTENT: ${{ secrets.CREDENTIAL_FILE_CONTENT }}
# GOOGLE_APPLICATION_CREDENTIALS: service_credentials_content.json
# INPUT_GROUPS: testers
# INPUT_FILE: app-staging-release.apk
# run: |
# cat <<< "${INPUT_SERVICECREDENTIALSFILECONTENT}" > service_credentials_content.json
# sudo npm install -g firebase-tools
# firebase appdistribution:distribute "$INPUT_FILE" --app "$INPUT_APPID" --groups "$INPUT_GROUPS" --testers "$INPUT_TESTERS" --release-notes "$(git log -1 --pretty=short)"

# deploy-firebase:
# name: Deploy to Firebase
Expand Down
Loading