* Set up full test suite in CI and Xcode Cloud Add build-ghosttykit.yml workflow to pre-build and publish GhosttyKit.xcframework as a GitHub release on manaflow-ai/ghostty, keyed by submodule SHA. Add ci_scripts/ci_post_clone.sh for Xcode Cloud to download the pre-built xcframework with retry logic. Create cmux-ci scheme that runs both cmuxTests and cmuxUITests. Switch the CI tests job from running a single UI test class to the full suite. * Run unit tests + single UI test class on self-hosted runner The self-hosted runner can't launch the full app for UI tests (no GUI session), so run all unit tests via cmux-unit scheme and keep the original UpdatePillUITests as a smoke test. Full UI test suite runs on Xcode Cloud which has proper macOS GUI support. * Handle expected test failures in unit tests step xcodebuild returns exit code 65 even for expected failures (XCTExpectFailure). Parse the summary line to only fail the CI job when there are unexpected failures.
120 lines
3.9 KiB
YAML
120 lines
3.9 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
pull_request:
|
|
|
|
jobs:
|
|
workflow-guard-tests:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
|
|
- name: Validate self-hosted runner guards
|
|
run: ./tests/test_ci_self_hosted_guard.sh
|
|
|
|
- name: Validate create-dmg version pinning
|
|
run: ./tests/test_ci_create_dmg_pinned.sh
|
|
|
|
web-typecheck:
|
|
runs-on: ubuntu-latest
|
|
defaults:
|
|
run:
|
|
working-directory: web
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 # v2
|
|
|
|
- name: Install dependencies
|
|
run: bun install --frozen-lockfile
|
|
|
|
- name: Typecheck
|
|
run: bun tsc --noEmit
|
|
|
|
tests:
|
|
# Never run self-hosted jobs for fork pull requests.
|
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
|
runs-on: self-hosted
|
|
concurrency:
|
|
group: self-hosted-build
|
|
cancel-in-progress: false
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: Select Xcode
|
|
run: |
|
|
set -euo pipefail
|
|
if [ -d "/Applications/Xcode.app/Contents/Developer" ]; then
|
|
XCODE_DIR="/Applications/Xcode.app/Contents/Developer"
|
|
else
|
|
XCODE_APP="$(ls -d /Applications/Xcode*.app 2>/dev/null | head -n 1 || true)"
|
|
if [ -n "$XCODE_APP" ]; then
|
|
XCODE_DIR="$XCODE_APP/Contents/Developer"
|
|
else
|
|
echo "No Xcode.app found under /Applications" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
echo "DEVELOPER_DIR=$XCODE_DIR" >> "$GITHUB_ENV"
|
|
export DEVELOPER_DIR="$XCODE_DIR"
|
|
xcodebuild -version
|
|
xcrun --sdk macosx --show-sdk-path
|
|
|
|
- name: Download Metal Toolchain
|
|
run: xcodebuild -downloadComponent MetalToolchain
|
|
|
|
- name: Build GhosttyKit.xcframework
|
|
run: |
|
|
set -euo pipefail
|
|
if ! command -v zig >/dev/null 2>&1; then
|
|
if command -v brew >/dev/null 2>&1; then
|
|
brew install zig
|
|
else
|
|
echo "zig is required to build GhosttyKit.xcframework. Install zig and retry." >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
(cd ghostty && zig build -Demit-xcframework=true -Demit-macos-app=false)
|
|
rm -rf GhosttyKit.xcframework
|
|
cp -R ghostty/macos/GhosttyKit.xcframework GhosttyKit.xcframework
|
|
test -d GhosttyKit.xcframework
|
|
|
|
- name: Clean DerivedData
|
|
run: |
|
|
# Remove stale build cache to avoid incremental build errors
|
|
rm -rf ~/Library/Developer/Xcode/DerivedData/GhosttyTabs-*
|
|
|
|
- name: Run unit tests
|
|
run: |
|
|
set -euo pipefail
|
|
# xcodebuild exits 65 even for expected failures (XCTExpectFailure).
|
|
# Capture output and fail only if there are unexpected failures.
|
|
set +e
|
|
OUTPUT=$(xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux-unit -configuration Debug \
|
|
-destination "platform=macOS" test 2>&1)
|
|
EXIT_CODE=$?
|
|
set -e
|
|
echo "$OUTPUT"
|
|
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: Run UI tests
|
|
run: |
|
|
set -euo pipefail
|
|
xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug -destination "platform=macOS" -only-testing:cmuxUITests/UpdatePillUITests test
|