name: Swift CI on: workflow_call: permissions: contents: read pull-requests: write issues: write env: DEVELOPER_DIR: /Applications/Xcode_16.4.app/Contents/Developer jobs: lint: name: Lint Swift Code runs-on: self-hosted steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Xcode run: | # DEVELOPER_DIR is already set in env, so no need for xcode-select xcodebuild -version swift --version - name: Install linting tools continue-on-error: true shell: bash run: | # Check if tools are already installed, install if not if ! which swiftlint >/dev/null 2>&1; then echo "Installing swiftlint..." brew install swiftlint || echo "Failed to install swiftlint" else echo "swiftlint is already installed at: $(which swiftlint)" fi if ! which swiftformat >/dev/null 2>&1; then echo "Installing swiftformat..." brew install swiftformat || echo "Failed to install swiftformat" else echo "swiftformat is already installed at: $(which swiftformat)" fi # Show final status echo "SwiftLint: $(which swiftlint || echo 'not found')" echo "SwiftFormat: $(which swiftformat || echo 'not found')" - name: Run SwiftFormat (check mode) id: swiftformat continue-on-error: true run: | swiftformat . --lint 2>&1 | tee swiftformat-output.txt echo "result=${PIPESTATUS[0]}" >> $GITHUB_OUTPUT - name: Run SwiftLint id: swiftlint continue-on-error: true run: | swiftlint 2>&1 | tee swiftlint-output.txt echo "result=${PIPESTATUS[0]}" >> $GITHUB_OUTPUT - name: Read SwiftFormat Output if: always() id: swiftformat-output run: | if [ -f swiftformat-output.txt ]; then echo 'content<> $GITHUB_OUTPUT cat swiftformat-output.txt >> $GITHUB_OUTPUT echo 'EOF' >> $GITHUB_OUTPUT else echo "content=No output" >> $GITHUB_OUTPUT fi - name: Read SwiftLint Output if: always() id: swiftlint-output run: | if [ -f swiftlint-output.txt ]; then echo 'content<> $GITHUB_OUTPUT cat swiftlint-output.txt >> $GITHUB_OUTPUT echo 'EOF' >> $GITHUB_OUTPUT else echo "content=No output" >> $GITHUB_OUTPUT fi - name: Report SwiftFormat Results if: always() uses: ./.github/actions/lint-reporter with: title: 'Swift Formatting (SwiftFormat)' lint-result: ${{ steps.swiftformat.outputs.result == '0' && 'success' || 'failure' }} lint-output: ${{ steps.swiftformat-output.outputs.content }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: Report SwiftLint Results if: always() uses: ./.github/actions/lint-reporter with: title: 'Swift Linting (SwiftLint)' lint-result: ${{ steps.swiftlint.outputs.result == '0' && 'success' || 'failure' }} lint-output: ${{ steps.swiftlint-output.outputs.content }} github-token: ${{ secrets.GITHUB_TOKEN }} build-and-test: name: Build and Test macOS App runs-on: self-hosted steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Xcode run: | # DEVELOPER_DIR is already set in env, so no need for xcode-select xcodebuild -version swift --version - name: Install build tools continue-on-error: true shell: bash run: | # Check if xcbeautify is already installed, install if not if ! which xcbeautify >/dev/null 2>&1; then echo "Installing xcbeautify..." brew install xcbeautify || echo "Failed to install xcbeautify" else echo "xcbeautify is already installed at: $(which xcbeautify)" fi # Show final status echo "xcbeautify: $(which xcbeautify || echo 'not found')" - name: Setup Rust uses: dtolnay/rust-toolchain@stable with: targets: x86_64-apple-darwin,aarch64-apple-darwin - name: Cache Rust dependencies uses: useblacksmith/rust-cache@v3 with: workspaces: tty-fwd - name: Build tty-fwd universal binary working-directory: tty-fwd run: | chmod +x build-universal.sh ./build-universal.sh - name: Build Debug timeout-minutes: 30 run: | set -o pipefail && \ xcodebuild build \ -workspace VibeTunnel.xcworkspace \ -scheme VibeTunnel \ -configuration Debug \ -destination "platform=macOS" \ CODE_SIGN_IDENTITY="" \ CODE_SIGNING_REQUIRED=NO \ | xcbeautify - name: Build Release timeout-minutes: 30 run: | set -o pipefail && \ xcodebuild build \ -workspace VibeTunnel.xcworkspace \ -scheme VibeTunnel \ -configuration Release \ -destination "platform=macOS" \ CODE_SIGN_IDENTITY="" \ CODE_SIGNING_REQUIRED=NO \ | xcbeautify - name: Run tests timeout-minutes: 20 run: | set -o pipefail && \ xcodebuild test \ -workspace VibeTunnel.xcworkspace \ -scheme VibeTunnel \ -configuration Debug \ -destination "platform=macOS" \ -resultBundlePath TestResults \ CODE_SIGN_IDENTITY="" \ CODE_SIGNING_REQUIRED=NO \ | xcbeautify - name: Upload test results if: failure() uses: actions/upload-artifact@v4 with: name: swift-test-results path: TestResults - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: swift-build-artifacts path: | build/Build/Products/Debug/VibeTunnel.app build/Build/Products/Release/VibeTunnel.app