# Codemagic CI/CD for Timbre (Flutter). # The repo root IS the Flutter project, so scripts run from the app directory # with no `working_directory` override. Two workflows: Android (Linux) and # iOS (mac). Docs: https://docs.codemagic.io/yaml/yaml-getting-started/ definitions: # Shared quality gate — anchored per-step (YAML can't splice a list into a # list, only reference individual map items). Toolchain is pinned inline in # each workflow to Flutter 3.44.8 / Dart 3.12.2 (the local dev version); # change to `stable` for the latest, or bump when you upgrade. scripts: - &flutter_version name: Flutter version script: flutter --version - &get_deps name: Get dependencies script: flutter pub get - &analyze name: Analyze script: flutter analyze - &unit_tests name: Unit tests script: | mkdir -p test-results flutter test --machine --coverage > test-results/flutter.json test_report: test-results/flutter.json workflows: # --------------------------------------------------------------------------- android: name: Android (APK + AAB) # mac_mini_m2 is the free-tier / most widely available instance and builds # Android fine. If your plan includes Linux, `linux_x2` is cheaper/faster # for Android-only builds. instance_type: mac_mini_m2 max_build_duration: 60 environment: flutter: 3.44.8 java: 17 # Uncomment once you add a keystore to Codemagic (Teams → Code signing # identities → Android) and reference its group here to sign releases. # groups: # - android_keystore # CM_KEYSTORE, CM_KEYSTORE_PASSWORD, CM_KEY_ALIAS, CM_KEY_PASSWORD cache: cache_paths: - $HOME/.pub-cache - $HOME/.gradle/caches # triggering: # events: [push, tag] # branch_patterns: # - pattern: main # include: true scripts: - *flutter_version - *get_deps - *analyze - *unit_tests # NOTE: android/app/build.gradle.kts currently signs `release` with the # DEBUG key (Flutter template default), so these build & install but are # not upload-ready. To ship: add a real signingConfig backed by # key.properties / the CI env vars above — this step then needs no change. - name: Build APK (release) script: flutter build apk --release - name: Build App Bundle (release) script: flutter build appbundle --release artifacts: - build/app/outputs/flutter-apk/*.apk - build/app/outputs/bundle/**/*.aab - build/app/outputs/**/mapping.txt - flutter_drive.log # publishing: # email: # recipients: # - you@conversionpath.com # notify: # success: true # failure: true # # google_play: # # credentials: $GCLOUD_SERVICE_ACCOUNT_CREDENTIALS # # track: internal # --------------------------------------------------------------------------- ios: name: iOS (TestFlight) instance_type: mac_mini_m2 max_build_duration: 60 # Reference NAME of the App Store Connect API key integration you added in # Codemagic (Teams → Integrations → App Store Connect). Replace the value # below with whatever you named it there. integrations: app_store_connect: Troglodyte environment: flutter: 3.44.8 java: 17 # Reference the signing files you created in Codemagic (Teams → Code # signing identities). Codemagic fetches them by reference name at build # init and sets up the keychain automatically — no keychain/fetch scripts # and no App-ID auto-fetch (which fails when nothing exists yet). # certificates: the distribution cert you generated ("troglodyte-timbre") # provisioning_profiles: an App Store profile for com.troglodyte.timbre — # generate it in the same UI (Code signing identities → Profiles) and # put its reference name below. ios_signing: certificates: - Troglodyte--Timbre provisioning_profiles: - troglodyte-profile vars: # The app's numeric Apple ID (App Store Connect → your app → App # Information → General → Apple ID). Used to auto-bump the build number # so TestFlight never rejects a duplicate. Fill in after you create the # app record in App Store Connect. (Until then the build number falls # back to 1 — fine for the very first upload.) APP_STORE_APPLE_ID: 6796333279 cache: cache_paths: - $HOME/.pub-cache - $HOME/.gradle/caches scripts: - *flutter_version - *get_deps - *analyze - *unit_tests - name: Set up code signing # The cert + profile referenced in ios_signing above are already fetched # and in the keychain by now. This just applies the profile to the Xcode # project and writes ~/export_options.plist (= /Users/builder/ # export_options.plist) that the build step reads. script: xcode-project use-profiles - name: Build signed IPA script: | BUILD_NUMBER=$(app-store-connect get-latest-testflight-build-number "$APP_STORE_APPLE_ID" 2>/dev/null || echo 0) flutter build ipa --release \ --build-number=$(( BUILD_NUMBER + 1 )) \ --export-options-plist=/Users/builder/export_options.plist artifacts: - build/ios/ipa/*.ipa publishing: app_store_connect: auth: integration submit_to_testflight: true # Internal testers automatically receive every build once Apple finishes # processing (no Beta App Review). To also push to a named group, # uncomment and match the group name from App Store Connect → TestFlight: # beta_groups: # - Internal Testers