Skip to content

chore: release v0.80.0 #13

chore: release v0.80.0

chore: release v0.80.0 #13

Workflow file for this run

name: Mobile Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
platform:
description: 'Platform to build'
required: true
default: 'both'
type: choice
options: [ios, android, both]
env:
# 3.24 predates Color.withValues() / Color.toARGB32() and the wider
# Brightness re-exports the app now uses, so analysis failed with dozens of
# undefined-member errors that never appear locally. Matches the SDK the
# lockfile resolves against and the desktop release was built with.
FLUTTER_VERSION: '3.35.7'
jobs:
# ── iOS ──────────────────────────────────────────────────────────────────────
ios-build:
name: iOS Build
runs-on: macos-15
env:
# The `secrets` context cannot be referenced from a step-level `if:`,
# so presence is resolved here and tested as a plain env value.
HAS_APPSTORE_CREDENTIALS: ${{ secrets.APP_STORE_CONNECT_API_KEY != '' }}
defaults:
run:
working-directory: app
steps:
- uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim
- name: Cache Cargo registry
uses: actions/cache@v4
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Flutter pub get
run: flutter pub get
# The drift check shells out to flutter_rust_bridge_codegen, which is not
# preinstalled on the runner. Cached the same way as in ci.yml, since a
# cold `cargo install` costs several minutes.
- name: Cache flutter_rust_bridge_codegen binary
id: frb-codegen-cache
uses: actions/cache@v4
with:
path: ~/.cargo/bin/flutter_rust_bridge_codegen
key: frb-codegen-${{ runner.os }}-v2.12.0
- name: Install flutter_rust_bridge_codegen
if: steps.frb-codegen-cache.outputs.cache-hit != 'true'
run: cargo install flutter_rust_bridge_codegen --version '^2.12' --locked
working-directory: .
- name: Verify FRB bindings
# The `../` here was relative to the job's default working-directory
# (app/), but this step overrides it to the repo root, so the path
# pointed outside the checkout: "../scripts/frb-codegen.sh: No such
# file or directory". The script must run from the root — it resolves
# crates/ and app/ from there.
run: ./scripts/frb-codegen.sh --check
working-directory: .
- name: Flutter analyze
run: flutter analyze --no-fatal-infos
- name: Flutter test
run: flutter test
- name: Build iOS (no codesign)
run: flutter build ios --release --no-codesign
# Skipped until the App Store Connect credentials exist as repo secrets.
# Without this guard a tag build fails here even though the app compiled
# cleanly, which reports the whole iOS job as broken.
- name: Archive & upload to TestFlight
if: >-
startsWith(github.ref, 'refs/tags/') &&
env.HAS_APPSTORE_CREDENTIALS == 'true'
env:
FASTLANE_APPLE_ID: ${{ secrets.FASTLANE_APPLE_ID }}
FASTLANE_ITC_TEAM_ID: ${{ secrets.FASTLANE_ITC_TEAM_ID }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
MATCH_GIT_URL: ${{ secrets.MATCH_GIT_URL }}
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
APP_STORE_CONNECT_API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
run: bundle exec fastlane ios release
working-directory: app/fastlane/ios
# ── Android ──────────────────────────────────────────────────────────────────
android-build:
name: Android Build
runs-on: ubuntu-latest
env:
HAS_PLAY_CREDENTIALS: ${{ secrets.PLAY_STORE_JSON_KEY != '' }}
defaults:
run:
working-directory: app
steps:
- uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-linux-android,x86_64-linux-android,armv7-linux-androideabi
- name: Install Android NDK
run: |
echo "y" | $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager "ndk;26.3.11579264"
- name: Cache Cargo registry
uses: actions/cache@v4
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Flutter pub get
run: flutter pub get
- name: Flutter analyze
run: flutter analyze --no-fatal-infos
- name: Flutter test
run: flutter test
- name: Build APK (split ABI)
run: flutter build apk --release --split-per-abi
- name: Build AAB
run: flutter build appbundle --release
- name: Upload APK artifact
uses: actions/upload-artifact@v4
with:
name: android-apk-${{ github.sha }}
path: app/build/app/outputs/flutter-apk/*.apk
# Skipped until PLAY_STORE_JSON_KEY exists. Note that the release build
# currently signs with the debug config from the default Flutter
# template (android/app/build.gradle.kts), so the AAB it produces would
# be rejected by Play anyway — a real upload keystore has to be wired in
# before enabling this.
- name: Deploy to Play Store
if: >-
startsWith(github.ref, 'refs/tags/') &&
env.HAS_PLAY_CREDENTIALS == 'true'
env:
PLAY_STORE_JSON_KEY: ${{ secrets.PLAY_STORE_JSON_KEY }}
run: bundle exec fastlane android deploy
working-directory: app/fastlane/android