From 6ac7457d674f20cd69fc7d0dc63061a861709d92 Mon Sep 17 00:00:00 2001 From: zzstar101 Date: Fri, 5 Jun 2026 10:12:21 +0800 Subject: [PATCH] ci: add split ios validation workflows --- .github/workflows/ios-quality.yml | 67 +++++++ .github/workflows/ios-swift-packages.yml | 175 ++++++++++++++++++ .github/workflows/ios-xcode.yml | 224 +++++++++++++++++++++++ 3 files changed, 466 insertions(+) create mode 100644 .github/workflows/ios-quality.yml create mode 100644 .github/workflows/ios-swift-packages.yml create mode 100644 .github/workflows/ios-xcode.yml diff --git a/.github/workflows/ios-quality.yml b/.github/workflows/ios-quality.yml new file mode 100644 index 0000000..8a93549 --- /dev/null +++ b/.github/workflows/ios-quality.yml @@ -0,0 +1,67 @@ +name: iOS Quality + +on: + pull_request: + branches: [main] + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + repository-quality: + name: Repository quality checks + runs-on: macos-15 + + steps: + - name: Check out iOS repository + uses: actions/checkout@v4 + with: + path: ios + + - name: Check whitespace + working-directory: ios + run: git diff --check + + - name: Check merge conflict markers + working-directory: ios + run: | + set -euo pipefail + if git grep -nE '^(<<<<<<<|>>>>>>>)' -- .; then + echo "Merge conflict marker found." + exit 1 + fi + + - name: Lint property lists and entitlements + working-directory: ios + run: | + set -euo pipefail + find App Extensions -type f \( -name '*.plist' -o -name '*.entitlements' \) -print0 \ + | xargs -0 plutil -lint + + - name: Validate Swift package manifests + working-directory: ios + run: | + set -euo pipefail + for manifest in SwiftPackages/*/Package.swift; do + package_dir="$(dirname "$manifest")" + echo "::group::${package_dir}" + swift package --package-path "$package_dir" dump-package >/dev/null + echo "::endgroup::" + done + + - name: Check required local artifacts and scripts + working-directory: ios + run: | + set -euo pipefail + test -x Scripts/build-mdbx-xcframework.sh + test -x Scripts/generate-mdbx-swift-bindings.sh + test -d Artifacts/MSAL/MSAL.xcframework + test -f Monica.xcodeproj/xcshareddata/xcschemes/Monica.xcscheme diff --git a/.github/workflows/ios-swift-packages.yml b/.github/workflows/ios-swift-packages.yml new file mode 100644 index 0000000..044cd57 --- /dev/null +++ b/.github/workflows/ios-swift-packages.yml @@ -0,0 +1,175 @@ +name: iOS Swift Packages + +on: + pull_request: + branches: [main] + push: + branches: + - main + schedule: + - cron: "23 18 * * *" + workflow_dispatch: + inputs: + mdbx_ref: + description: Monica-Pass/Mdbx ref for MDBX-backed package checks + required: false + default: master + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event.inputs.mdbx_ref || 'master' }} + cancel-in-progress: true + +jobs: + pure-swift-packages: + name: SwiftPM test (${{ matrix.package }}) + runs-on: macos-15 + strategy: + fail-fast: false + matrix: + package: + - MonicaCore + - MonicaSecurity + - MonicaSync + - MonicaUI + + steps: + - name: Check out iOS repository + uses: actions/checkout@v4 + with: + path: ios + + - name: Cache SwiftPM build artifacts + uses: actions/cache@v4 + with: + path: ios/SwiftPackages/${{ matrix.package }}/.build + key: ${{ runner.os }}-spm-${{ matrix.package }}-${{ hashFiles('ios/SwiftPackages/**/Package.swift', 'ios/SwiftPackages/**/Package.resolved') }} + restore-keys: | + ${{ runner.os }}-spm-${{ matrix.package }}- + + - name: Run package tests + working-directory: ios + run: swift test --package-path "SwiftPackages/${{ matrix.package }}" + + - name: Build package in release + working-directory: ios + run: swift build --package-path "SwiftPackages/${{ matrix.package }}" -c release + + binary-package: + name: SwiftPM validate binary package + runs-on: macos-15 + + steps: + - name: Check out iOS repository + uses: actions/checkout@v4 + with: + path: ios + + - name: Validate MSAL binary package manifest + working-directory: ios + run: swift package --package-path SwiftPackages/MSAL dump-package >/dev/null + + mdbx-backed-packages: + name: SwiftPM test MDBX-backed packages (${{ github.event.inputs.mdbx_ref || 'master' }}) + runs-on: macos-15 + + steps: + - name: Check out iOS repository + uses: actions/checkout@v4 + with: + path: ios + + - name: Check out Monica MDBX + uses: actions/checkout@v4 + with: + repository: Monica-Pass/Mdbx + ref: ${{ github.event.inputs.mdbx_ref || 'master' }} + path: mdbx + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: aarch64-apple-ios,aarch64-apple-ios-sim,x86_64-apple-ios + + - name: Capture MDBX cache key inputs + id: mdbx-cache-key + run: | + set -euo pipefail + echo "sha=$(git -C mdbx rev-parse HEAD)" >> "$GITHUB_OUTPUT" + { + shasum ios/Scripts/build-mdbx-xcframework.sh + shasum ios/Scripts/generate-mdbx-swift-bindings.sh + shasum ios/SwiftPackages/MonicaMDBX/Package.swift + rustc -Vv + } | shasum | awk '{print "tooling="$1}' >> "$GITHUB_OUTPUT" + + - name: Cache Rust dependencies and MDBX targets + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + ~/.cargo/bin/uniffi-bindgen-swift + mdbx/target + key: ${{ runner.os }}-cargo-mdbx-${{ steps.mdbx-cache-key.outputs.sha }}-${{ steps.mdbx-cache-key.outputs.tooling }} + restore-keys: | + ${{ runner.os }}-cargo-mdbx-${{ steps.mdbx-cache-key.outputs.sha }}- + ${{ runner.os }}-cargo-mdbx- + + - name: Install UniFFI Swift bindgen + run: | + set -euo pipefail + if ! command -v uniffi-bindgen-swift >/dev/null 2>&1; then + cargo install uniffi --version 0.31.1 --locked --features cli + fi + + - name: Cache MDBX generated artifact + id: mdbx-artifact-cache + uses: actions/cache@v4 + with: + path: | + ios/Artifacts/MDBX/MonicaMDBXGenerated.xcframework + ios/SwiftPackages/MonicaMDBX/Sources/MonicaMDBX/Generated + key: ${{ runner.os }}-mdbx-ios-artifact-${{ steps.mdbx-cache-key.outputs.sha }}-${{ steps.mdbx-cache-key.outputs.tooling }} + + - name: Build MDBX XCFramework + if: steps.mdbx-artifact-cache.outputs.cache-hit != 'true' + working-directory: ios + run: Scripts/build-mdbx-xcframework.sh + + - name: Validate generated MDBX artifact + working-directory: ios + run: | + set -euo pipefail + test -d Artifacts/MDBX/MonicaMDBXGenerated.xcframework + test -f SwiftPackages/MonicaMDBX/Sources/MonicaMDBX/Generated/mdbx_ffi.swift + plutil -lint Artifacts/MDBX/MonicaMDBXGenerated.xcframework/Info.plist + + - name: Cache MDBX-backed SwiftPM artifacts + uses: actions/cache@v4 + with: + path: | + ios/SwiftPackages/MonicaMDBX/.build + ios/SwiftPackages/MonicaStorage/.build + key: ${{ runner.os }}-spm-mdbx-backed-${{ steps.mdbx-cache-key.outputs.sha }}-${{ hashFiles('ios/SwiftPackages/MonicaMDBX/Package.swift', 'ios/SwiftPackages/MonicaStorage/Package.swift', 'ios/SwiftPackages/MonicaStorage/Package.resolved') }} + restore-keys: | + ${{ runner.os }}-spm-mdbx-backed-${{ steps.mdbx-cache-key.outputs.sha }}- + ${{ runner.os }}-spm-mdbx-backed- + + - name: Run MonicaMDBX tests + working-directory: ios + run: swift test --package-path SwiftPackages/MonicaMDBX + + - name: Build MonicaMDBX in release + working-directory: ios + run: swift build --package-path SwiftPackages/MonicaMDBX -c release + + - name: Run MonicaStorage tests + working-directory: ios + run: swift test --package-path SwiftPackages/MonicaStorage + + - name: Build MonicaStorage in release + working-directory: ios + run: swift build --package-path SwiftPackages/MonicaStorage -c release diff --git a/.github/workflows/ios-xcode.yml b/.github/workflows/ios-xcode.yml new file mode 100644 index 0000000..b956730 --- /dev/null +++ b/.github/workflows/ios-xcode.yml @@ -0,0 +1,224 @@ +name: iOS Xcode + +on: + pull_request: + branches: [main] + push: + branches: + - main + workflow_dispatch: + inputs: + mdbx_ref: + description: Monica-Pass/Mdbx ref for Xcode build and test + required: false + default: master + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event.inputs.mdbx_ref || 'master' }} + cancel-in-progress: true + +jobs: + mdbx-artifact: + name: Prepare MDBX artifact (${{ github.event.inputs.mdbx_ref || 'master' }}) + runs-on: macos-15 + outputs: + mdbx-sha: ${{ steps.mdbx-cache-key.outputs.sha }} + mdbx-tooling: ${{ steps.mdbx-cache-key.outputs.tooling }} + + steps: + - name: Check out iOS repository + uses: actions/checkout@v4 + with: + path: ios + + - name: Check out Monica MDBX + uses: actions/checkout@v4 + with: + repository: Monica-Pass/Mdbx + ref: ${{ github.event.inputs.mdbx_ref || 'master' }} + path: mdbx + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: aarch64-apple-ios,aarch64-apple-ios-sim,x86_64-apple-ios + + - name: Capture MDBX cache key inputs + id: mdbx-cache-key + run: | + set -euo pipefail + echo "sha=$(git -C mdbx rev-parse HEAD)" >> "$GITHUB_OUTPUT" + { + shasum ios/Scripts/build-mdbx-xcframework.sh + shasum ios/Scripts/generate-mdbx-swift-bindings.sh + shasum ios/SwiftPackages/MonicaMDBX/Package.swift + rustc -Vv + } | shasum | awk '{print "tooling="$1}' >> "$GITHUB_OUTPUT" + + - name: Cache Rust dependencies and MDBX targets + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + ~/.cargo/bin/uniffi-bindgen-swift + mdbx/target + key: ${{ runner.os }}-cargo-mdbx-${{ steps.mdbx-cache-key.outputs.sha }}-${{ steps.mdbx-cache-key.outputs.tooling }} + restore-keys: | + ${{ runner.os }}-cargo-mdbx-${{ steps.mdbx-cache-key.outputs.sha }}- + ${{ runner.os }}-cargo-mdbx- + + - name: Install UniFFI Swift bindgen + run: | + set -euo pipefail + if ! command -v uniffi-bindgen-swift >/dev/null 2>&1; then + cargo install uniffi --version 0.31.1 --locked --features cli + fi + + - name: Cache MDBX generated artifact + id: mdbx-artifact-cache + uses: actions/cache@v4 + with: + path: | + ios/Artifacts/MDBX/MonicaMDBXGenerated.xcframework + ios/SwiftPackages/MonicaMDBX/Sources/MonicaMDBX/Generated + key: ${{ runner.os }}-mdbx-ios-artifact-${{ steps.mdbx-cache-key.outputs.sha }}-${{ steps.mdbx-cache-key.outputs.tooling }} + + - name: Build MDBX XCFramework + if: steps.mdbx-artifact-cache.outputs.cache-hit != 'true' + working-directory: ios + run: Scripts/build-mdbx-xcframework.sh + + - name: Validate generated MDBX artifact + working-directory: ios + run: | + set -euo pipefail + test -d Artifacts/MDBX/MonicaMDBXGenerated.xcframework + test -f SwiftPackages/MonicaMDBX/Sources/MonicaMDBX/Generated/mdbx_ffi.swift + plutil -lint Artifacts/MDBX/MonicaMDBXGenerated.xcframework/Info.plist + + - name: Pack MDBX artifact + working-directory: ios + run: | + set -euo pipefail + tar -czf mdbx-ios-artifacts.tgz \ + Artifacts/MDBX/MonicaMDBXGenerated.xcframework \ + SwiftPackages/MonicaMDBX/Sources/MonicaMDBX/Generated + + - name: Upload MDBX artifact + uses: actions/upload-artifact@v4 + with: + name: mdbx-ios-artifacts + path: ios/mdbx-ios-artifacts.tgz + if-no-files-found: error + + build: + name: Build ${{ matrix.scheme }} (${{ matrix.configuration }}) + runs-on: macos-15 + needs: mdbx-artifact + strategy: + fail-fast: false + matrix: + scheme: + - Monica + - MonicaAutoFillExtension + - MonicaShareExtension + - MonicaWidgetExtension + configuration: + - Debug + - Release + + steps: + - name: Check out iOS repository + uses: actions/checkout@v4 + with: + path: ios + + - name: Download MDBX artifact + uses: actions/download-artifact@v4 + with: + name: mdbx-ios-artifacts + path: ios + + - name: Unpack MDBX artifact + working-directory: ios + run: tar -xzf mdbx-ios-artifacts.tgz + + - name: Cache Xcode build data + uses: actions/cache@v4 + with: + path: ios/DerivedData + key: ${{ runner.os }}-xcode-${{ matrix.scheme }}-${{ matrix.configuration }}-${{ needs.mdbx-artifact.outputs.mdbx-sha }}-${{ needs.mdbx-artifact.outputs.mdbx-tooling }}-${{ hashFiles('ios/Monica.xcodeproj/project.pbxproj', 'ios/Monica.xcodeproj/xcshareddata/xcschemes/*.xcscheme', 'ios/SwiftPackages/**/Package.swift', 'ios/SwiftPackages/**/Package.resolved') }} + restore-keys: | + ${{ runner.os }}-xcode-${{ matrix.scheme }}-${{ matrix.configuration }}- + ${{ runner.os }}-xcode- + + - name: Build scheme + working-directory: ios + run: | + set -euo pipefail + xcodebuild build \ + -project Monica.xcodeproj \ + -scheme "${{ matrix.scheme }}" \ + -configuration "${{ matrix.configuration }}" \ + -destination "generic/platform=iOS Simulator" \ + -derivedDataPath DerivedData \ + CODE_SIGNING_ALLOWED=NO \ + CODE_SIGNING_REQUIRED=NO + + tests: + name: Run Monica XCTest suite + runs-on: macos-15 + needs: mdbx-artifact + + steps: + - name: Check out iOS repository + uses: actions/checkout@v4 + with: + path: ios + + - name: Download MDBX artifact + uses: actions/download-artifact@v4 + with: + name: mdbx-ios-artifacts + path: ios + + - name: Unpack MDBX artifact + working-directory: ios + run: tar -xzf mdbx-ios-artifacts.tgz + + - name: Cache Xcode test build data + uses: actions/cache@v4 + with: + path: ios/DerivedData + key: ${{ runner.os }}-xcode-tests-${{ needs.mdbx-artifact.outputs.mdbx-sha }}-${{ needs.mdbx-artifact.outputs.mdbx-tooling }}-${{ hashFiles('ios/Monica.xcodeproj/project.pbxproj', 'ios/Monica.xcodeproj/xcshareddata/xcschemes/*.xcscheme', 'ios/SwiftPackages/**/Package.swift', 'ios/SwiftPackages/**/Package.resolved') }} + restore-keys: | + ${{ runner.os }}-xcode-tests- + ${{ runner.os }}-xcode- + + - name: Select available iPhone simulator + run: | + set -euo pipefail + device_name="$(xcrun simctl list devices available | awk -F'[()]' '/iPhone/ {gsub(/^[ \t]+|[ \t]+$/, "", $1); print $1; exit}')" + if [ -z "$device_name" ]; then + echo "No available iPhone simulator found." + xcrun simctl list devices available + exit 1 + fi + echo "IOS_DESTINATION=platform=iOS Simulator,name=${device_name},OS=latest" >> "$GITHUB_ENV" + echo "Selected simulator: ${device_name}" + + - name: Run tests + working-directory: ios + run: | + set -euo pipefail + xcodebuild test \ + -project Monica.xcodeproj \ + -scheme Monica \ + -destination "$IOS_DESTINATION" \ + -derivedDataPath DerivedData \ + CODE_SIGNING_ALLOWED=NO \ + CODE_SIGNING_REQUIRED=NO