Move iOS app into repo with public-only Convex sync and proprietary licensing #4324
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: macOS Compatibility | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| jobs: | |
| compat-tests: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: warp-macos-15-arm64-6x | |
| timeout: 30 | |
| smoke: true | |
| skip_zig: false | |
| - os: warp-macos-26-arm64-6x | |
| timeout: 30 | |
| smoke: false | |
| skip_zig: true # zig 0.15.2 MachO linker can't resolve libSystem on macOS 26 | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: ${{ matrix.timeout }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| submodules: recursive | |
| - name: Select Xcode | |
| run: | | |
| set -euo pipefail | |
| # Pick the latest Xcode installed on the runner. GitHub-hosted macos-14 | |
| # defaults to Xcode 15.4, but the project needs Xcode 16+ (Swift tools | |
| # version 6.0 required by sentry-cocoa). | |
| XCODE_APP="$(ls -d /Applications/Xcode_*.app 2>/dev/null | sort | tail -n 1)" | |
| if [ -z "$XCODE_APP" ]; then | |
| XCODE_APP="/Applications/Xcode.app" | |
| fi | |
| XCODE_DIR="$XCODE_APP/Contents/Developer" | |
| if [ ! -d "$XCODE_DIR" ]; then | |
| echo "No Xcode found under /Applications" >&2 | |
| exit 1 | |
| fi | |
| echo "Selected: $XCODE_APP" | |
| echo "DEVELOPER_DIR=$XCODE_DIR" >> "$GITHUB_ENV" | |
| export DEVELOPER_DIR="$XCODE_DIR" | |
| XCODE_VERSION_OUTPUT="$(xcodebuild -version)" | |
| XCODE_VER="${XCODE_VERSION_OUTPUT%%$'\n'*}" | |
| echo "XCODE_VER=$XCODE_VER" >> "$GITHUB_ENV" | |
| echo "$XCODE_VERSION_OUTPUT" | |
| xcrun --sdk macosx --show-sdk-path | |
| sw_vers | |
| - name: Cache GhosttyKit.xcframework | |
| id: cache-ghosttykit | |
| uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4 | |
| with: | |
| path: GhosttyKit.xcframework | |
| key: ghosttykit-${{ hashFiles('.gitmodules', 'ghostty') }} | |
| - name: Download pre-built GhosttyKit.xcframework | |
| if: steps.cache-ghosttykit.outputs.cache-hit != 'true' | |
| run: | | |
| ./scripts/download-prebuilt-ghosttykit.sh | |
| - name: Install zig | |
| if: ${{ !matrix.skip_zig }} | |
| run: | | |
| ZIG_REQUIRED="0.15.2" | |
| if command -v zig >/dev/null 2>&1 && zig version 2>/dev/null | grep -q "^${ZIG_REQUIRED}"; then | |
| echo "zig ${ZIG_REQUIRED} already installed" | |
| else | |
| echo "Installing zig ${ZIG_REQUIRED} from tarball" | |
| curl -fSL "https://ziglang.org/download/${ZIG_REQUIRED}/zig-aarch64-macos-${ZIG_REQUIRED}.tar.xz" -o /tmp/zig.tar.xz | |
| tar xf /tmp/zig.tar.xz -C /tmp | |
| sudo mkdir -p /usr/local/bin /usr/local/lib | |
| sudo cp -f /tmp/zig-aarch64-macos-${ZIG_REQUIRED}/zig /usr/local/bin/zig | |
| sudo cp -rf /tmp/zig-aarch64-macos-${ZIG_REQUIRED}/lib /usr/local/lib/zig | |
| export PATH="/usr/local/bin:$PATH" | |
| zig version | |
| fi | |
| - name: Cache DerivedData | |
| uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4 | |
| with: | |
| path: ~/Library/Developer/Xcode/DerivedData/GhosttyTabs-* | |
| key: deriveddata-${{ matrix.os }}-${{ env.XCODE_VER }}-${{ hashFiles('GhosttyTabs.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved') }}-${{ hashFiles('GhosttyTabs.xcodeproj/project.pbxproj') }} | |
| restore-keys: | | |
| deriveddata-${{ matrix.os }}-${{ env.XCODE_VER }}-${{ hashFiles('GhosttyTabs.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved') }}- | |
| deriveddata-${{ matrix.os }}-${{ env.XCODE_VER }}- | |
| - name: Cache Swift packages | |
| uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4 | |
| with: | |
| path: .ci-source-packages | |
| key: spm-${{ matrix.os }}-${{ hashFiles('GhosttyTabs.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved') }} | |
| restore-keys: spm-${{ matrix.os }}- | |
| - name: Resolve Swift packages | |
| run: | | |
| set -euo pipefail | |
| SOURCE_PACKAGES_DIR="$PWD/.ci-source-packages" | |
| mkdir -p "$SOURCE_PACKAGES_DIR" | |
| for attempt in 1 2 3; do | |
| if xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux-unit -configuration Debug \ | |
| -clonedSourcePackagesDirPath "$SOURCE_PACKAGES_DIR" \ | |
| -resolvePackageDependencies; then | |
| exit 0 | |
| fi | |
| if [ "$attempt" -eq 3 ]; then | |
| echo "Failed to resolve Swift packages after 3 attempts" >&2 | |
| exit 1 | |
| fi | |
| echo "Package resolution failed on attempt $attempt, retrying..." | |
| sleep $((attempt * 5)) | |
| done | |
| - name: Run unit tests | |
| env: | |
| CMUX_SKIP_ZIG_BUILD: ${{ matrix.skip_zig && '1' || '0' }} | |
| run: | | |
| set -euo pipefail | |
| SOURCE_PACKAGES_DIR="$PWD/.ci-source-packages" | |
| run_unit_tests() { | |
| xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux-unit -configuration Debug \ | |
| -clonedSourcePackagesDirPath "$SOURCE_PACKAGES_DIR" \ | |
| -disableAutomaticPackageResolution \ | |
| -destination "platform=macOS" \ | |
| -skip-testing:cmuxTests/AppDelegateShortcutRoutingTests/testCmdWClosesWindowWhenClosingLastSurfaceInLastWorkspace \ | |
| test 2>&1 | |
| } | |
| set +e | |
| run_unit_tests | tee /tmp/test-output.txt | |
| EXIT_CODE=${PIPESTATUS[0]} | |
| OUTPUT=$(cat /tmp/test-output.txt) | |
| set -e | |
| # SwiftPM binary artifact resolution can occasionally fail on ephemeral | |
| # runners. Retry once after clearing caches. | |
| if [ "$EXIT_CODE" -ne 0 ] && echo "$OUTPUT" | grep -q "Could not resolve package dependencies"; then | |
| echo "SwiftPM package resolution failed, clearing caches and retrying once" | |
| rm -rf ~/Library/Caches/org.swift.swiftpm | |
| mkdir -p ~/Library/Caches/org.swift.swiftpm | |
| rm -rf ~/Library/Developer/Xcode/DerivedData/GhosttyTabs-* | |
| set +e | |
| run_unit_tests | tee /tmp/test-output.txt | |
| EXIT_CODE=${PIPESTATUS[0]} | |
| OUTPUT=$(cat /tmp/test-output.txt) | |
| set -e | |
| fi | |
| if [ "$EXIT_CODE" -ne 0 ]; then | |
| SUMMARY=$(echo "$OUTPUT" | grep "Executed.*tests.*with.*failures" | tail -1) | |
| if echo "$SUMMARY" | grep -q "(0 unexpected)"; then | |
| echo "All failures are expected, treating as pass" | |
| else | |
| echo "Unexpected test failures detected" | |
| exit 1 | |
| fi | |
| fi | |
| - name: Create virtual display | |
| if: matrix.smoke | |
| run: | | |
| set -euo pipefail | |
| echo "=== Display before ===" | |
| system_profiler SPDisplaysDataType 2>/dev/null || echo "(no display info)" | |
| echo "" | |
| clang -framework Foundation -framework CoreGraphics \ | |
| -o /tmp/create-virtual-display scripts/create-virtual-display.m | |
| /tmp/create-virtual-display & | |
| VDISPLAY_PID=$! | |
| echo "VDISPLAY_PID=$VDISPLAY_PID" >> "$GITHUB_ENV" | |
| sleep 3 | |
| echo "=== Display after ===" | |
| system_profiler SPDisplaysDataType 2>/dev/null || echo "(no display info)" | |
| - name: Build app for smoke test | |
| if: matrix.smoke | |
| run: | | |
| set -euo pipefail | |
| SOURCE_PACKAGES_DIR="$PWD/.ci-source-packages" | |
| xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug \ | |
| -clonedSourcePackagesDirPath "$SOURCE_PACKAGES_DIR" \ | |
| -disableAutomaticPackageResolution \ | |
| -destination "platform=macOS" build | |
| - name: Smoke test | |
| if: matrix.smoke | |
| run: | | |
| set -euo pipefail | |
| chmod +x scripts/smoke-test-ci.sh | |
| scripts/smoke-test-ci.sh |