diff --git a/.github/workflows/android_build.yml b/.github/workflows/android_build.yml index df3294375..489166a9f 100644 --- a/.github/workflows/android_build.yml +++ b/.github/workflows/android_build.yml @@ -15,6 +15,7 @@ on: env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 + SQLX_OFFLINE: true jobs: android-build: @@ -26,26 +27,21 @@ jobs: with: lfs: true - - name: Set up Just - uses: extractions/setup-just@v2 + - uses: cargo-bins/cargo-binstall@main - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: '3.3' + ruby-version: "3.3" bundler-cache: true - - name: Set up Flutter FVM - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 - with: - path: 'app/.fvmrc' - cache: false + - run: curl -fsSL https://fvm.app/install.sh | bash - name: Install required Java version uses: actions/setup-java@v4 with: - distribution: 'temurin' - java-version: '17' + distribution: "temurin" + java-version: "17" - name: Cache Gradle dependencies uses: actions/cache@v4 @@ -66,10 +62,11 @@ jobs: with: cache-directories: app/build/airapplogic/build + - run: cargo binstall cargo-ndk --no-confirm - name: Set up Android CI env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: just setup-android-ci + run: cd app/fastlane && bundle install - name: Build Android app run: | @@ -82,5 +79,5 @@ jobs: - name: Upload Android app APK uses: actions/upload-artifact@v4 with: - name: air-${{ steps.vars.outputs.sha_short }} + name: air-android-${{ steps.vars.outputs.sha_short }} path: app/build/app/outputs/flutter-apk/app-release.apk diff --git a/.github/workflows/android_publish.yml b/.github/workflows/android_publish.yml index 3cba0e361..9a751592d 100644 --- a/.github/workflows/android_publish.yml +++ b/.github/workflows/android_publish.yml @@ -13,17 +13,18 @@ on: branches: - main paths: - - 'coreclient/**' - - 'apiclient/**' - - 'applogic/**' - - 'common/**' - - 'app/**' - - 'Cargo.toml' + - "coreclient/**" + - "apiclient/**" + - "applogic/**" + - "common/**" + - "app/**" + - "Cargo.toml" workflow_dispatch: env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 + SQLX_OFFLINE: true jobs: android-publish: @@ -35,33 +36,27 @@ jobs: with: lfs: true - - name: Set up Just - uses: extractions/setup-just@v2 - - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: '3.3' + ruby-version: "3.3" - - name: Set up Flutter FVM - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 - with: - path: 'app/.fvmrc' - cache: false + - run: curl -fsSL https://fvm.app/install.sh | bash - name: Install required Java version uses: actions/setup-java@v4 with: - distribution: 'temurin' - java-version: '17' + distribution: "temurin" + java-version: "17" - name: Set up Rust toolchain uses: dtolnay/rust-toolchain@1.90.0 + - run: cargo binstall cargo-ndk --no-confirm - name: Set up Android CI env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: just setup-android-ci + run: cd app/fastlane && bundle install - name: Build and upload to Play Store env: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 024f6cb7e..000000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,98 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Phoenix R&D GmbH -# -# SPDX-License-Identifier: AGPL-3.0-or-later - -name: Build and test Rust code - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -on: - pull_request: - branches: ["main"] - -env: - SQLX_OFFLINE: true - CARGO_INCREMENTAL: 0 - -jobs: - rust-check-dependencies: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install cargo-machete - uses: taiki-e/install-action@cargo-machete - - run: cargo machete - - rust-check-lock: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Rust toolchain - uses: dtolnay/rust-toolchain@1.90.0 - - run: cargo metadata --locked - - rust-check-fmt: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Rust toolchain - uses: dtolnay/rust-toolchain@1.90.0 - with: - components: rustfmt - - run: cargo fmt -- --check - - rust-check-cargo-deny: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Rust toolchain - uses: dtolnay/rust-toolchain@1.90.0 - - name: Set up Just - uses: extractions/setup-just@v2 - - run: just install-cargo-binstall - - run: cargo binstall cargo-deny - - run: cargo deny check - - rust-clippy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Rust toolchain - uses: dtolnay/rust-toolchain@1.90.0 - with: - components: clippy - - uses: Swatinem/rust-cache@v2 - - run: cargo clippy --locked --all-targets -- -D warnings - - rust-build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Rust toolchain - uses: dtolnay/rust-toolchain@1.90.0 - - uses: Swatinem/rust-cache@v2 - - run: cargo build --verbose - - rust-test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install Podman Compose - run: pip3 install --user podman-compose - - - name: Set up Just - uses: extractions/setup-just@v2 - - - name: Start Compose services - run: just run-services - - - name: Set up Rust toolchain - uses: dtolnay/rust-toolchain@1.90.0 - - - uses: Swatinem/rust-cache@v2 - - - name: Run tests - run: just test-rust --verbose diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..3b31092d5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,77 @@ +# SPDX-FileCopyrightText: 2025 Phoenix R&D GmbH +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +name: CI + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + branches: ["main"] + +env: + CARGO_TERM_COLOR: always + CARGO_INCREMENTAL: 0 + SQLX_OFFLINE: true + +jobs: + frb: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + + ## CHECK FRB + - uses: dtolnay/rust-toolchain@1.90.0 + - run: curl -fsSL https://fvm.app/install.sh | bash + - run: (cd app && fvm install) + - uses: actions/cache@v4 + with: + path: ~/.cargo/bin/flutter_rust_bridge_codegen + key: cargo-install-${{ runner.os }}-frb-2.11.1 + - run: if ! command -v flutter_rust_bridge_codegen; then cargo install flutter_rust_bridge_codegen@2.11.1; fi + - uses: extractions/setup-just@v2 + - run: just check-frb + + flutter: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + lfs: true + + # CHECK FLUTTER + - run: curl -fsSL https://fvm.app/install.sh | bash + - run: (cd app && fvm install) + - uses: extractions/setup-just@v2 + - run: just check-flutter + + # TEST FLUTTER + - run: just test-flutter + - uses: actions/upload-artifact@v4 + if: failure() + with: + name: golden-failures + path: app/test/**/failures/* + + rust: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + + # CHECK RUST + - uses: taiki-e/install-action@cargo-machete + - uses: dtolnay/rust-toolchain@1.90.0 + - uses: cargo-bins/cargo-binstall@main + - run: cargo binstall cargo-deny@0.18.5 --no-confirm + - uses: Swatinem/rust-cache@v2 + - run: pip3 install --user reuse + - run: pip3 install --user podman-compose + - uses: extractions/setup-just@v2 + - run: just check-rust + + # TEST RUST + - run: just start-docker-compose + - run: just test-rust diff --git a/.github/workflows/flutter_test.yml b/.github/workflows/flutter_test.yml deleted file mode 100644 index 4a342693f..000000000 --- a/.github/workflows/flutter_test.yml +++ /dev/null @@ -1,59 +0,0 @@ -# SPDX-FileCopyrightText: 2024 Phoenix R&D GmbH -# -# SPDX-License-Identifier: AGPL-3.0-or-later - -name: Flutter tests - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -on: - pull_request: - branches: ["main"] - -env: - CARGO_TERM_COLOR: always - -jobs: - flutter-test: - runs-on: ubuntu-latest - - steps: - - name: Clone repository - uses: actions/checkout@v4 - with: - lfs: true - - - name: Set up Just - uses: extractions/setup-just@v2 - - - name: Set up Flutter FVM - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 - with: - path: 'app/.fvmrc' - cache: false - - - name: Check Flutter lockfile - run: just check-flutter-lockfile - - # Note: for formatting to use the correct style, we need to run `flutter - # pub get` first. This is done in the `check-dart-format` step. - - name: Check dart format - run: just check-dart-format - - - name: Check localization - run: just check-l10n - - - name: Analyze dart code - run: just analyze-dart - - - name: Run Flutter tests - run: just test-flutter - - - name: Upload golden failures - if: failure() - uses: actions/upload-artifact@v4 - with: - name: golden-failures - path: app/test/**/failures/* diff --git a/.github/workflows/frb.yml b/.github/workflows/frb.yml deleted file mode 100644 index b4aeb450a..000000000 --- a/.github/workflows/frb.yml +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-FileCopyrightText: 2025 Phoenix R&D GmbH -# -# SPDX-License-Identifier: AGPL-3.0-or-later - -name: Flutter Rust Bridge - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -on: - pull_request: - branches: ["main"] - -env: - CARGO_TERM_COLOR: always - CARGO_INCREMENTAL: 0 - -jobs: - check-frb: - runs-on: ubuntu-latest - - steps: - - name: Clone repository - uses: actions/checkout@v4 - - - name: Set up Just - uses: extractions/setup-just@v2 - - - name: Set up Flutter FVM - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 - with: - path: 'app/.fvmrc' - cache: false - - - name: Set up Rust toolchain - uses: dtolnay/rust-toolchain@1.90.0 - with: - components: rustfmt - - - run: just check-frb-ci diff --git a/.github/workflows/ios_build.yml b/.github/workflows/ios_build.yml index fac76cc5c..5bc2b1bca 100644 --- a/.github/workflows/ios_build.yml +++ b/.github/workflows/ios_build.yml @@ -15,6 +15,7 @@ on: env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 + SQLX_OFFLINE: true jobs: ios-build: @@ -26,19 +27,12 @@ jobs: with: lfs: true - - name: Set up Just - uses: extractions/setup-just@v2 - - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: '3.3' + ruby-version: "3.3" - - name: Set up Flutter FVM - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 - with: - path: 'app/.fvmrc' - cache: false + - run: curl -fsSL https://fvm.app/install.sh | bash - name: Set up Rust toolchain uses: dtolnay/rust-toolchain@1.90.0 @@ -46,17 +40,7 @@ jobs: - name: Set up iOS CI env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: just setup-ios-ci - - - name: Test flutter - run: just test-flutter - - - name: Upload golden failures - if: failure() - uses: actions/upload-artifact@v4 - with: - name: golden-failures - path: app/test/**/failures/* + run: cd app/fastlane && bundle install - name: Setup Xcode uses: maxim-lobanov/setup-xcode@v1 @@ -76,7 +60,7 @@ jobs: - name: Build iOS app if: ${{ steps.detect_fork.outputs.is_fork == 'true' }} run: | - cd app && fastlane ios build_ios + cd app && fastlane ios build_ios --verbose - name: Build and sign iOS app if: ${{ steps.detect_fork.outputs.is_fork == 'false' }} @@ -98,4 +82,3 @@ jobs: with: name: build-logs path: ~/Library/Logs/gym/Runner-Runner.log - diff --git a/.github/workflows/ios_publish.yml b/.github/workflows/ios_publish.yml index 437ad42c9..c195ee26a 100644 --- a/.github/workflows/ios_publish.yml +++ b/.github/workflows/ios_publish.yml @@ -7,19 +7,20 @@ name: Publish iOS app on: push: branches: - - main + - main paths: - - 'coreclient/**' - - 'apiclient/**' - - 'applogic/**' - - 'common/**' - - 'app/**' - - 'Cargo.toml' + - "coreclient/**" + - "apiclient/**" + - "applogic/**" + - "common/**" + - "app/**" + - "Cargo.toml" workflow_dispatch: env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 + SQLX_OFFLINE: true jobs: ios-publish: @@ -29,19 +30,12 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Set up Just - uses: extractions/setup-just@v2 - - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: '3.3' + ruby-version: "3.3" - - name: Set up Flutter FVM - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 - with: - path: 'app/.fvmrc' - cache: false + - run: curl -fsSL https://fvm.app/install.sh | bash - name: Set up Rust toolchain uses: dtolnay/rust-toolchain@1.90.0 @@ -49,7 +43,7 @@ jobs: - name: Set up iOS CI env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: just setup-ios-ci + run: cd app/fastlane && bundle install - name: Setup Xcode uses: maxim-lobanov/setup-xcode@v1 diff --git a/.github/workflows/license.yml b/.github/workflows/license.yml deleted file mode 100644 index cb26d19fa..000000000 --- a/.github/workflows/license.yml +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Phoenix R&D GmbH -# -# SPDX-License-Identifier: AGPL-3.0-or-later - -name: REUSE Compliance Check - -on: [push, pull_request] - -jobs: - reuse-check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: REUSE Compliance Check - uses: fsfe/reuse-action@v5 diff --git a/.github/workflows/linux_build.yml b/.github/workflows/linux_build.yml index b0a6ec821..4e74b7e6e 100644 --- a/.github/workflows/linux_build.yml +++ b/.github/workflows/linux_build.yml @@ -15,6 +15,7 @@ on: env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 + SQLX_OFFLINE: true jobs: linux-build: @@ -24,14 +25,7 @@ jobs: - name: Clone repository uses: actions/checkout@v4 - - name: Set up Just - uses: extractions/setup-just@v2 - - - name: Set up Flutter FVM - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 - with: - path: 'app/.fvmrc' - cache: false + - run: curl -fsSL https://fvm.app/install.sh | bash - name: Set up Rust toolchain uses: dtolnay/rust-toolchain@1.90.0 @@ -44,7 +38,7 @@ jobs: run: sudo apt-get update && sudo apt-get install -y ninja-build gtk+-3.0 gtk+-3.0-dev glib-2.0-dev gio-2.0-dev - name: Build Linux app - run: just build-linux + run: cd app && fvm flutter build linux -v - name: Upload Linux app uses: actions/upload-artifact@v4 diff --git a/.github/workflows/macos_build.yml b/.github/workflows/macos_build.yml index c92207a7b..5e32d5270 100644 --- a/.github/workflows/macos_build.yml +++ b/.github/workflows/macos_build.yml @@ -15,6 +15,7 @@ on: env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 + SQLX_OFFLINE: true jobs: macos-build: @@ -26,19 +27,12 @@ jobs: with: lfs: true - - name: Set up Just - uses: extractions/setup-just@v2 - - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: "3.3" - - name: Set up Flutter FVM - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 - with: - path: "app/.fvmrc" - cache: false + - run: curl -fsSL https://fvm.app/install.sh | bash - name: Set up Rust toolchain uses: dtolnay/rust-toolchain@1.90.0 @@ -46,17 +40,7 @@ jobs: - name: Set up macOS CI env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: just setup-macos-ci - - - name: Test flutter - run: just test-flutter - - - name: Upload golden failures - if: failure() - uses: actions/upload-artifact@v4 - with: - name: golden-failures - path: app/test/**/failures/* + run: cd app/fastlane && bundle install - name: Setup Xcode uses: maxim-lobanov/setup-xcode@v1 @@ -76,7 +60,7 @@ jobs: - name: Build macOS app if: ${{ steps.detect_fork.outputs.is_fork == 'true' }} run: | - cd app && fastlane mac build_macos + cd app && fastlane mac build_macos --verbose - name: Build and sign macOS app if: ${{ steps.detect_fork.outputs.is_fork == 'false' }} diff --git a/.github/workflows/macos_publish.yml b/.github/workflows/macos_publish.yml index 190d878c2..585639373 100644 --- a/.github/workflows/macos_publish.yml +++ b/.github/workflows/macos_publish.yml @@ -19,6 +19,7 @@ on: env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 + SQLX_OFFLINE: true jobs: mac-publish: @@ -28,19 +29,12 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Set up Just - uses: extractions/setup-just@v2 - - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: "3.3" - - name: Set up Flutter FVM - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 - with: - path: "app/.fvmrc" - cache: false + - run: curl -fsSL https://fvm.app/install.sh | bash - name: Set up Rust toolchain uses: dtolnay/rust-toolchain@1.90.0 @@ -48,7 +42,7 @@ jobs: - name: Set up macOS CI env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: just setup-macos-ci + run: cd app/fastlane && bundle install - name: Setup Xcode uses: maxim-lobanov/setup-xcode@v1 diff --git a/.github/workflows/windows_build.yml b/.github/workflows/windows_build.yml index 55b1223f2..2f9e06edf 100644 --- a/.github/workflows/windows_build.yml +++ b/.github/workflows/windows_build.yml @@ -15,6 +15,7 @@ on: env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 + SQLX_OFFLINE: true jobs: windows-build: @@ -24,14 +25,8 @@ jobs: - name: Clone repository uses: actions/checkout@v4 - - name: Set up Just - uses: extractions/setup-just@v2 - - - name: Set up Flutter FVM - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 - with: - path: 'app/.fvmrc' - cache: false + - run: choco install fvm + - run: cd app && fvm install - name: Set up Rust toolchain uses: dtolnay/rust-toolchain@1.90.0 @@ -41,7 +36,7 @@ jobs: cache-directories: app/build/windows/x64/plugins/airapplogic/cargokit_build - name: Build Windows app - run: just build-windows + run: cd app && fvm flutter build windows -v - name: Upload Windows app uses: actions/upload-artifact@v4 diff --git a/app/fastlane/android.rb b/app/fastlane/android.rb index 9730a2cb1..5a0f1cba6 100644 --- a/app/fastlane/android.rb +++ b/app/fastlane/android.rb @@ -60,9 +60,9 @@ # allow manual installation build_target = upload_to_play_store ? "appbundle" : "apk" - sh "flutter precache --android" - sh "flutter pub get" - sh "flutter build #{build_target} --release --target-platform android-arm64" + sh "fvm flutter precache --android" + sh "fvm flutter pub get" + sh "fvm flutter build #{build_target} --release --target-platform android-arm64" if upload_to_play_store # Upload to Google Play Store diff --git a/app/fastlane/ios.rb b/app/fastlane/ios.rb index 855acf499..aa114a8dd 100644 --- a/app/fastlane/ios.rb +++ b/app/fastlane/ios.rb @@ -17,7 +17,7 @@ matchType = "appstore" app_identifier = "ms.air" app_identifier_nse = "ms.air.nse" - + # Load the app store connect API key api_key = app_store_connect_api_key( key_id: key_id, @@ -26,7 +26,7 @@ is_key_content_base64: true, in_house: false ) - + # Read app version from pubspec.yaml pubspec = YAML.load_file("../pubspec.yaml") app_version = (pubspec['version'] || '').to_s.split('+').first @@ -41,12 +41,12 @@ app_identifier: app_identifier ) + 1 end - + increment_build_number( xcodeproj: "ios/Runner.xcodeproj", build_number: build_number, ) - + # Use match for code signing ["development", "appstore"].each do |i| match( @@ -60,7 +60,7 @@ readonly: is_ci, ) end - + # Build the app with signing build_ios(with_signing: upload_to_test_flight) @@ -74,30 +74,30 @@ ) end end - + desc "Build app" lane :build_ios do |options| # The following is false when "with_signing" is not provided in the option # and true otherwise skip_signing = !options[:with_signing] - + # Set up CI setup_ci() - + # Install flutter dependencies - sh "flutter pub get" + sh "fvm flutter pub get" # Build the app with flutter first to create the necessary ephemeral files - sh "flutter build ios --config-only #{skip_signing ? '--debug' : '--release'}" - + sh "fvm flutter build ios --config-only #{skip_signing ? '--debug' : '--release'}" + # Install CocoaPods dependencies cocoapods( podfile: "ios/Podfile" ) - + # Build the app build_app( - workspace: "ios/Runner.xcworkspace", + workspace: "ios/Runner.xcworkspace", scheme: "Runner", configuration: skip_signing ? "Debug" : "Release", skip_codesigning: skip_signing, diff --git a/app/fastlane/macos.rb b/app/fastlane/macos.rb index 5f48930a8..48c5827e5 100644 --- a/app/fastlane/macos.rb +++ b/app/fastlane/macos.rb @@ -16,7 +16,7 @@ team_id = ENV['TEAM_ID'] matchType = "appstore" app_identifier = "ms.air" - + # Load the app store connect API key api_key = app_store_connect_api_key( key_id: key_id, @@ -29,7 +29,7 @@ # Read app version from pubspec.yaml pubspec = YAML.load_file("../pubspec.yaml") app_version = (pubspec['version'] || '').to_s.split('+').first - + # Determine build number build_number = if options[:build_number] options[:build_number].to_i @@ -41,12 +41,12 @@ app_identifier: app_identifier ) + 1 end - + increment_build_number( xcodeproj: "macos/Runner.xcodeproj", build_number: build_number, ) - + # Use match for code signing ["development", "appstore"].each do |i| match( @@ -62,7 +62,7 @@ additional_cert_types: ["mac_installer_distribution"] ) end - + # Build the app with signing build_macos(with_signing: upload_to_test_flight) @@ -70,35 +70,35 @@ if upload_to_test_flight upload_to_testflight( api_key: api_key, - app_platform: "osx", + app_platform: "osx", skip_waiting_for_build_processing: true, distribute_external: false, ) end end - + desc "Build macOS app" lane :build_macos do |options| # The following is false when "with_signing" is not provided in the oprion and true otherwise skip_signing = !options[:with_signing] - + # Set up CI setup_ci() - + # Install flutter dependencies - sh "flutter pub get" + sh "fvm flutter pub get" # Build the app with flutter first to create the necessary ephemeral files - sh "flutter build macos --config-only #{skip_signing ? '--debug' : '--release'}" - + sh "fvm flutter build macos --config-only #{skip_signing ? '--debug' : '--release'}" + # Install CocoaPods dependencies cocoapods( podfile: "macos/Podfile" ) - + # Build the app build_mac_app( - workspace: "macos/Runner.xcworkspace", + workspace: "macos/Runner.xcworkspace", scheme: "Runner", configuration: skip_signing ? "Debug" : "Release", skip_codesigning: skip_signing, diff --git a/app/macos/Runner.xcodeproj/project.pbxproj b/app/macos/Runner.xcodeproj/project.pbxproj index 4d2d75709..796db5439 100644 --- a/app/macos/Runner.xcodeproj/project.pbxproj +++ b/app/macos/Runner.xcodeproj/project.pbxproj @@ -710,10 +710,10 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = 7QXP938FNA; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/applogic/src/util/background.rs b/applogic/src/util/background.rs index 6ed17e7b6..10eb34615 100644 --- a/applogic/src/util/background.rs +++ b/applogic/src/util/background.rs @@ -2,15 +2,10 @@ // // SPDX-License-Identifier: AGPL-3.0-or-later -use std::{ - fmt, - marker::PhantomData, - pin::Pin, - sync::Arc, - time::{Duration, Instant}, -}; +use std::{fmt, marker::PhantomData, pin::Pin, sync::Arc}; use tokio::time; +use tokio::time::{Duration, Instant}; use tokio_stream::{Stream, StreamExt}; use tokio_util::sync::CancellationToken; use tracing::{debug, error, info}; diff --git a/backend/.env b/backend/.env new file mode 100644 index 000000000..63bd4699f --- /dev/null +++ b/backend/.env @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2025 Phoenix R&D GmbH +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +DATABASE_URL=postgres://postgres:password@localhost:5432/phnx_db diff --git a/coreclient/.env b/coreclient/.env new file mode 100644 index 000000000..3c303ec0a --- /dev/null +++ b/coreclient/.env @@ -0,0 +1,5 @@ +# SPDX-FileCopyrightText: 2025 Phoenix R&D GmbH +# +# SPDX-License-Identifier: AGPL-3.0-or-later + +DATABASE_URL=sqlite:coreclient/client.db diff --git a/justfile b/justfile index 77c06c3cf..4be416edd 100644 --- a/justfile +++ b/justfile @@ -2,194 +2,148 @@ # # SPDX-License-Identifier: AGPL-3.0-or-later -set windows-shell := ["C:\\Program Files\\Git\\bin\\sh.exe","-c"] - -# === Backend === - -POSTGRES_DATABASE_URL := "postgres://postgres:password@localhost:5432/phnx_db" - -docker-is-podman := if `command -v podman || true` =~ ".*podman$" { "true" } else { "false" } - -# run docker compose services in the background -run-services: generate-db-certs - if {{docker-is-podman}} == "true"; then \ - podman rm infra_minio-setup_1 -i 2>&1 /dev/null; \ - podman-compose --podman-run-args=--replace up -d; \ - podman-compose ps; \ - podman logs infra_postgres_1; \ - else \ - docker compose up --wait --wait-timeout=300; \ - docker compose ps; \ +export RUST_LOG := "info" +export RUST_BACKTRACE := "1" +export RUSTFLAGS := "-D warnings" + +_default: + just --list + +# Reset and migrate databases. +reset-dev: + cd coreclient && cargo sqlx database reset -y --database-url sqlite:$PWD/client.db + cd backend && cargo sqlx database reset -y + +# Run fast and simple Rust lints. +@check-rust: + just _check-status "cargo machete" + just _check-status "reuse lint -l" + just _check-status "cargo metadata --format-version 1 --locked > /dev/null" + just _check-status "cargo fmt -- --check" + just _check-status "cargo deny check" + just _check-unstaged-changes "git diff" + just _check-unstaged-changes "just regenerate-sqlx || echo 'Database not configured?'" + echo "{{BOLD}}check-rust done{{NORMAL}}" + +# Run fast and simple Flutter lints. +@check-flutter: + just _check-status "git lfs --version" + just _check-unstaged-changes "git diff" + just _check-unstaged-changes "cd app && fvm flutter pub get" + just _check-unstaged-changes "cd app/rust_builder/cargokit/build_tool && fvm flutter pub get" + just _check-unstaged-changes "cd app && fvm dart format ." + just _check-status "cd app && fvm flutter analyze --no-pub" + just _check-unstaged-changes "just regenerate-l10n" + echo "{{BOLD}}check-flutter done{{NORMAL}}" + +# Run Flutter-Rust bridge lint. +@check-frb: + just _check-unstaged-changes "just regenerate-frb" + +# Run all fast and simple lints. +@check: check-rust check-flutter check-frb + +# This task will run the command and hide stdout and stderr. If the command fails, it prints the logs and the task fails. +_check-status command: + #!/usr/bin/env -S bash -eu + echo "{{BOLD}}Running {{command}}{{NORMAL}}" + if ! log=$({{command}} 2>&1); then + echo "{{RED}}$log{{NORMAL}}" >&2 + just _log-error "{{command}}" fi -# initialize the backend database and apply migrations -init-backend-db $DATABASE_URL=(POSTGRES_DATABASE_URL): - cd backend && sqlx database create - cd backend && sqlx database setup - -[working-directory: 'backend'] -prepare-db-statements $DATABASE_URL=(POSTGRES_DATABASE_URL): - cargo sqlx prepare --database-url $DATABASE_URL -- --tests - -# generate postgres TLS certificates -generate-db-certs: - cd backend && TEST_CERT_DIR_NAME=test_certs scripts/generate_test_certs.sh - -# === Client === - -[working-directory: 'coreclient'] -init-client-db: - sqlx database create --database-url sqlite://{{justfile_directory()}}/coreclient/client.db - sqlx database setup --database-url sqlite://{{justfile_directory()}}/coreclient/client.db - -[working-directory: 'coreclient'] -prepare-client-db-statements: init-client-db - cargo sqlx prepare --database-url sqlite://{{justfile_directory()}}/coreclient/client.db - +# This task will run the command and hide stdout. If git diff then reports unstaged changes, the task will fail. +_check-unstaged-changes command: + #!/usr/bin/env -S bash -eu + echo "{{BOLD}}Running {{command}}{{NORMAL}}" + {{command}} >/dev/null + if ! git diff --quiet; then + echo -e "{{RED}}Found unstaged changes.{{NORMAL}}" + just _log-error "{{command}}" + fi -# === App === +# This task will print the error and call exit 1. If this is running in GitHub CI, it will add the error to the GitHub summary as an annotation. +_log-error msg: + #!/usr/bin/env -S bash -eu + if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then + echo -e "::error::{{msg}}" + else + msg="\x1b[1;31mERROR: {{msg}}\x1b[0m" + echo -e "$msg" + fi + exit 1 -app_lib_name := "applogic" -app_rust_base_dir := "../applogic" -# generate Dart files e.g. the data classes a.k.a freezed classes -[working-directory: 'app'] -generate-dart-files: - dart run build_runner build --delete-conflicting-outputs +# Regenerate frb and l10n. +regenerate: regenerate-frb regenerate-l10n regenerate-sqlx -# generate Rust and Dart flutter bridge files +# Regenerate Flutter-Rust bridge files. [working-directory: 'app'] -frb-generate $CARGO_TARGET_DIR=(justfile_directory() + "/target/frb_codegen"): - rm -f {{app_rust_base_dir}}/src/frb_*.rs - touch {{app_rust_base_dir}}/src/frb_generated.rs +regenerate-frb: + rm -f ../applogic/src/frb_*.rs + touch ../applogic/src/frb_generated.rs rm -Rf lib/core/api lib/core/frb_*.dart lib/core/lib.dart - flutter_rust_bridge_codegen generate - cd .. && cargo fmt - -# Generate Rust and Dart flutter bridge files and check that they are committed -# -# Note: As a side effect, this recipe also checks whether the generated Dart -# files and the `app/pubspec.lock` file are up to date. This occurs because -# `flutter_rust_bridge_codegen` runs the `dart run build_runner build` command, -# which updates the generated files. -check-frb: frb-generate - just check-clean-repo "just frb-generate" - -# same as check-generated-frb (with all prerequisite steps for running in CI) -check-frb-ci: install-cargo-binstall - cargo binstall flutter_rust_bridge_codegen@2.11.1 cargo-expand - just check-frb - -check-clean-repo command: - #!/usr/bin/env -S bash -eu - if [ -n "$(git status --porcelain)" ]; then - git add -N . - git --no-pager diff - echo -e "\x1b[1;31mFound uncommitted changes. Did you forget to run '{{command}}'?" - exit 1 - fi -# update the Flutter dependencies -[working-directory: 'app'] -flutter-pub-get: - flutter pub get + CARGO_TARGET_DIR="{{justfile_directory()}}/target/frb_codegen" \ + flutter_rust_bridge_codegen generate -# check that the Flutter lockfile is up to date -[working-directory: 'app'] -check-flutter-lockfile: flutter-pub-get - # getting the Flutter dependencies may change the formatting - just dart-format - just check-clean-repo "just flutter-pub-get" - -# format dart code -[working-directory: 'app'] -dart-format: - dart format . + cd .. && cargo fmt -# check that dart code is formatted -[working-directory: 'app'] -check-dart-format: dart-format - just check-clean-repo "just dart-format" +# Regenerate localization files. +regenerate-l10n: + cd app && fvm flutter gen-l10n -# generate localization files -[working-directory: 'app'] -gen-l10n: - flutter gen-l10n +regenerate-sqlx: + cd coreclient && cargo sqlx prepare --database-url sqlite:$PWD/client.db + cd backend && cargo sqlx prepare -# check that the localization files are up to date -[working-directory: 'app'] -check-l10n: gen-l10n - just check-clean-repo "just gen-l10n" - -# set up the CI environment for the app -install-cargo-binstall: - curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash - -# set up the CI environment for Android builds -[working-directory: 'app/fastlane'] -setup-android-ci: install-cargo-binstall - cargo binstall -y cargo-ndk - bundle install - -# set up the CI environment for iOS builds -[working-directory: 'app/fastlane'] -setup-ios-ci: install-cargo-binstall - bundle install - -# set up the CI environment for macOS builds -[working-directory: 'app/fastlane'] -setup-macos-ci: install-cargo-binstall - bundle install - -test-rust *args='': - env DATABASE_URL={{POSTGRES_DATABASE_URL}} SQLX_OFFLINE=true cargo test {{args}} - -# build Android -# we limit it to android-arm64 to speed up the build process -[working-directory: 'app'] -build-android: - flutter build appbundle --target-platform android-arm64 +# Run cargo build, clippy and test. +@test-rust: start-docker-compose + just _check-status "cargo clippy --locked --all-targets" + just _check-status "cargo test --locked -q" + echo "{{BOLD}}test-rust done{{NORMAL}}" -# build iOS -[working-directory: 'app'] -build-ios: - flutter build ios --no-codesign +# Run flutter test. +test-flutter: + cd app && fvm flutter test + @echo "{{BOLD}}test-flutter done{{NORMAL}}" -# Build Linux app -[working-directory: 'app'] -build-linux: - flutter build linux -v +# Run all lints and tests. +ci: check test -# analyze Dart code -[working-directory: 'app'] -analyze-dart: - cd rust_builder/cargokit/build_tool && flutter pub get - flutter analyze +# Run all tests. +test: test-rust test-flutter -# run Flutter tests -[working-directory: 'app'] -test-flutter *args='': - flutter test {{args}} +docker-is-podman := if `command -v podman || true` =~ ".*podman$" { "true" } else { "false" } +# Run docker compose services in the background. +@start-docker-compose: _generate-db-certs + if {{docker-is-podman}} == "true"; then \ + podman rm air_minio-setup_1 -i 2>&1 /dev/null; \ + podman-compose --podman-run-args=--replace up -d; \ + podman-compose ps; \ + podman logs air_postgres_1; \ + else \ + docker compose up --wait --wait-timeout=300; \ + docker compose ps; \ + fi -# run backend server (at localhost) -run-backend: init-backend-db - cargo run --bin airserver +# Generate postgres TLS certificates. +_generate-db-certs: + cd backend && TEST_CERT_DIR_NAME=test_certs scripts/generate_test_certs.sh -# Build Windows app -[working-directory: 'app'] -build-windows: - flutter build windows -v +# Use the current test results as new reference images. +update-flutter-goldens: + fvm flutter test --update-goldens -# Run app -[working-directory: 'app'] -run-app *args='': - flutter run {{args}} +# Start the client in debug mode. +run-client *args='': + cd app && fvm flutter run {{args}} -# Run app on Linux -run-app-linux *args='': - just run-app -d linux {{args}} +# Start the client from the last debug build. +run-client-cached device="macos": + #!/usr/bin/env -S bash -eu + app/build/{{device}}/Build/Products/Debug/Air.app/Contents/*/Air -# Add client migration -[working-directory: 'coreclient'] -add-client-migration migration_name: - sqlx migrate add {{migration_name}} +# Start the server. +run-server: + cargo run --bin airserver | bunyan