name: ci on: push: tags: ["**"] pull_request: jobs: rust: name: cargo check + cargo test runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: System deps (cpal / Opus / SQLite / SDL2) run: | sudo apt-get update sudo apt-get install -y \ libasound2-dev libpulse-dev pkg-config \ libdbus-1-dev \ libsdl2-dev \ libopus-dev - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: cargo check --workspace run: cargo check --workspace --locked - name: cargo test --workspace env: CHANORA_DISABLE_KEYRING: "1" run: cargo test --workspace --locked --no-fail-fast - name: cargo clippy run: cargo clippy --workspace --all-targets -- -D warnings supply-chain: name: cargo deny (licenses + advisories + bans + sources) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: EmbarkStudios/cargo-deny-action@v2 with: command: check arguments: --workspace --all-features license-inventory: name: cargo about (license inventory) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: Install cargo-about run: cargo install --locked --features cli cargo-about - name: Regenerate inventory and compare run: | cargo about generate --output-file /tmp/license-inventory.md about-md.hbs diff docs/security/license-inventory.md /tmp/license-inventory.md \ || { echo "::error::docs/security/license-inventory.md is stale; regenerate with 'cargo about generate --output-file docs/security/license-inventory.md about-md.hbs'"; exit 1; } flutter-license-inventory: name: flutter license inventory runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: channel: stable - name: flutter pub get working-directory: apps/chanora_flutter run: flutter pub get - name: Regenerate Flutter license inventory and compare env: FLUTTER_ROOT: ${{ env.FLUTTER_ROOT }} run: | ./tools/dump_flutter_licenses.sh if ! git diff --quiet docs/security/flutter-license-inventory.md; then echo "::error::docs/security/flutter-license-inventory.md is stale; regenerate with 'tools/dump_flutter_licenses.sh'" git --no-pager diff docs/security/flutter-license-inventory.md | head -40 exit 1 fi flutter: name: flutter analyze runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: channel: stable - name: flutter pub get working-directory: apps/chanora_flutter run: flutter pub get - name: flutter analyze working-directory: apps/chanora_flutter run: flutter analyze - name: flutter test (unit only) working-directory: apps/chanora_flutter run: flutter test --exclude-tags e2e flutter-ios-release-build: name: flutter iOS unsigned release build runs-on: macos-latest steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: channel: stable - name: Try to fetch local SileroCoreML package run: git submodule update --init --depth=1 silero-coreml || true - name: flutter pub get working-directory: apps/chanora_flutter run: flutter pub get - name: Check local SileroCoreML package id: silero-coreml run: | if [ -f silero-coreml/Package.swift ]; then echo "available=true" >> "$GITHUB_OUTPUT" else echo "::notice::Skipping iOS build because silero-coreml submodule is not available" echo "available=false" >> "$GITHUB_OUTPUT" fi - name: flutter build ios --no-codesign if: steps.silero-coreml.outputs.available == 'true' working-directory: apps/chanora_flutter run: flutter build ios --release --no-codesign - name: xcodebuild archive verification if: steps.silero-coreml.outputs.available == 'true' working-directory: apps/chanora_flutter run: | xcodebuild archive \ -workspace ios/Runner.xcworkspace \ -scheme Runner \ -archive build/Runner.xcarchive \ CODE_SIGNING_ALLOWED=NO \ | xcpretty || { echo "::error::xcodebuild archive failed — see issue-history-analysis.md §4 'Xcode Archive vs build divergence'"; exit 1; } android-build: name: Android build (${{ matrix.target }}) runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - target: aarch64-linux-android abi: arm64-v8a - target: armv7-linux-androideabi abi: armeabi-v7a - target: x86_64-linux-android abi: x86_64 steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.target }} - uses: Swatinem/rust-cache@v2 - name: Install cargo-ndk run: cargo install --locked cargo-ndk - name: Setup NDK run: | ANDROID_ROOT="/usr/local/lib/android/sdk" SDKMANAGER="$ANDROID_ROOT/cmdline-tools/latest/bin/sdkmanager" echo "y" | $SDKMANAGER "ndk;27.0.12077973" echo "ANDROID_NDK_HOME=$ANDROID_ROOT/ndk/27.0.12077973" >> "$GITHUB_ENV" - name: cargo ndk build run: cargo ndk -t ${{ matrix.abi }} build --workspace --locked windows-build: name: Windows build runs-on: windows-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: cargo check --workspace run: cargo check --workspace --locked macos-build: name: macOS build runs-on: macos-latest steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: cargo check --workspace run: cargo check --workspace --locked linux-multi-distro: name: Linux build (${{ matrix.distro }}) runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - distro: ubuntu image: ubuntu:24.04 install: | apt-get update apt-get install -y curl build-essential pkg-config \ libasound2-dev libpulse-dev libdbus-1-dev libsdl2-dev libopus-dev - distro: fedora image: fedora:latest install: | dnf install -y curl gcc pkg-config \ alsa-lib-devel pulseaudio-libs-devel dbus-devel SDL2-devel opus-devel - distro: arch image: archlinux:latest install: | pacman -Syu --noconfirm pacman -S --noconfirm curl base-devel pkg-config \ alsa-lib pulseaudio dbus sdl2 opus container: image: ${{ matrix.image }} steps: - uses: actions/checkout@v4 - name: Install system dependencies run: ${{ matrix.install }} - name: Install Rust run: | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - name: cargo check --workspace run: cargo check --workspace coverage: name: cargo llvm-cov runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: System deps run: | sudo apt-get update sudo apt-get install -y \ libasound2-dev libpulse-dev pkg-config \ libdbus-1-dev libsdl2-dev libopus-dev - uses: dtolnay/rust-toolchain@stable with: components: llvm-tools-preview - uses: Swatinem/rust-cache@v2 - name: Install cargo-llvm-cov run: cargo install --locked cargo-llvm-cov - name: Generate coverage env: CHANORA_DISABLE_KEYRING: "1" run: cargo llvm-cov --workspace --lcov --output-path lcov.info - name: Upload coverage artifact uses: actions/upload-artifact@v4 with: name: lcov-report path: lcov.info