mobile-music/codemagic.yaml
2026-07-30 10:06:36 -04:00

155 lines
6.3 KiB
YAML

# 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_m1 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_m1
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_m1
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
# NOTE: intentionally NO `ios_signing` block. That block triggers
# Codemagic's *automatic* signing during build initialization, which only
# FETCHES existing certs/profiles and fails the build up front ("No
# matching profiles found") on a fresh account that has none yet. Instead
# we sign fully manually in the scripts below, where we can create the
# cert + profile on first run. The `integrations.app_store_connect` above
# still injects the ASC API-key env vars the app-store-connect CLI uses.
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: Initialize keychain
# Manual signing: create the build keychain ourselves (the removed
# ios_signing block used to do this automatically).
script: keychain initialize
- name: Fetch signing files
# fetch-signing-files --create mints the Apple Distribution cert + the
# App Store provisioning profile via the ASC API key and downloads them.
# --create also registers the Bundle ID if it isn't already. On the
# first build this creates everything; later builds reuse it.
script: |
app-store-connect fetch-signing-files "com.troglodyte.timbre" \
--type IOS_APP_STORE \
--create
- name: Add certificates to keychain
# Load the freshly fetched distribution cert into the build keychain.
script: keychain add-certificates
- name: Set up code signing
# 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