# Apple client CI — runs on the self-hosted macOS runner (home-mac-mini-1, host mode; # see scripts/ci/setup-macos-runner.sh). Builds the Rust core into # PunktfunkCore.xcframework, then builds + tests the Swift package. Network-dependent # tests (RemoteFirstLightTests) self-skip without PUNKTFUNK_REMOTE_HOST. # # A second job (`screenshots`) captures the App Store Connect screenshots of the REAL UI # (mac window + iOS/iPad/tvOS Simulators, see clients/apple/tools/screenshots.sh) and attaches # them to the run as a single zip artifact (`punktfunk-appstore-screenshots`). It is isolated # from the build/test job and best-effort, so a capture gap never reds the core signal. name: apple on: push: branches: [main] pull_request: workflow_dispatch: jobs: swift: runs-on: macos-arm64 timeout-minutes: 60 steps: - uses: actions/checkout@v4 - name: Rust toolchain (self-healing on a fresh runner) run: | if ! command -v rustup >/dev/null && [ ! -x "$HOME/.cargo/bin/rustup" ]; then curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ | sh -s -- -y --no-modify-path --profile minimal fi RUSTUP="$(command -v rustup || echo "$HOME/.cargo/bin/rustup")" dirname "$RUSTUP" >> "$GITHUB_PATH" "$RUSTUP" target add aarch64-apple-darwin x86_64-apple-darwin - name: Build PunktfunkCore.xcframework run: bash scripts/build-xcframework.sh - name: Build (PunktfunkKit + PunktfunkClient app shell) working-directory: clients/apple run: swift build - name: Test (unit + real-codec round trip; remote tests self-skip) working-directory: clients/apple run: swift test # App Store screenshots of the real UI, zipped and attached to the run as a build artifact. # Skipped on PRs (cost); runs on main pushes + manual dispatch. Needs the build/test job green # first, and is a separate job so a capture hiccup can never red the core signal. # # Scope = the two REQUIRED iOS sizes (iPhone 6.9" + iPad 13"), captured on the Simulator # (`simctl io screenshot`, no Screen Recording grant needed). macOS and tvOS are deliberately # NOT in CI: the self-hosted runner is headless (no window-server session), so the mac window # capture can't run there; tvOS needs the Tier-3 build-std slice. Generate those two locally on # a GUI Mac with `clients/apple/tools/screenshots.sh macos tvos`. screenshots: needs: swift if: gitea.event_name != 'pull_request' runs-on: macos-arm64 timeout-minutes: 75 steps: - uses: actions/checkout@v4 - name: Rust toolchain + iOS Simulator targets run: | if ! command -v rustup >/dev/null && [ ! -x "$HOME/.cargo/bin/rustup" ]; then curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ | sh -s -- -y --no-modify-path --profile minimal fi RUSTUP="$(command -v rustup || echo "$HOME/.cargo/bin/rustup")" dirname "$RUSTUP" >> "$GITHUB_PATH" "$RUSTUP" target add aarch64-apple-darwin x86_64-apple-darwin \ aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios - name: Build PunktfunkCore.xcframework (mac + iOS slices) run: BUILD_IOS=1 bash scripts/build-xcframework.sh - name: Capture screenshots (iPhone 6.9" + iPad 13"; auto-creates the Simulators) working-directory: clients/apple env: SETTLE: "8" # Simulators settle slower than a local run run: | # Independent invocations: one platform failing skips it, not the other. bash tools/screenshots.sh ios || echo "::warning::iOS (iPhone 6.9\") screenshots skipped" bash tools/screenshots.sh ipad || echo "::warning::iPad 13\" screenshots skipped" echo "Produced:"; ls -la screenshots || true - name: Upload screenshots (zip artifact) if: always() # v3, not v4: Gitea's artifact backend identifies as GHES, which @actions/artifact v2+ # (upload-artifact@v4) refuses. v3 uses the older API Gitea supports; download is still a zip. uses: actions/upload-artifact@v3 with: name: punktfunk-appstore-screenshots path: clients/apple/screenshots if-no-files-found: warn retention-days: 30