Merge pull request #1 from elegantchaos/integration/stack #18
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
| # -------------------------------------------------------------------------------- | |
| # This workflow was automatically generated by ActionBuilderTool 2.2.1 (139). | |
| # (see https://github.com/elegantchaos/ActionBuilderCore for more details) | |
| # -------------------------------------------------------------------------------- | |
| name: Tests | |
| on: [push, pull_request] | |
| jobs: | |
| iOS-swift63: | |
| name: iOS (Swift 6.3, Xcode matching Swift 6.3) | |
| runs-on: macos-26 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Make Logs Directory | |
| run: | | |
| LOGS_DIR="${GITHUB_WORKSPACE:-$PWD}/logs" | |
| mkdir -p "$LOGS_DIR" | |
| if [[ "$PWD/logs" != "$LOGS_DIR" && ! -e logs ]] | |
| then | |
| ln -s "$LOGS_DIR" logs | |
| fi | |
| { | |
| echo "timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)" | |
| echo "runner=${RUNNER_NAME:-unknown} (${RUNNER_OS:-unknown}/${RUNNER_ARCH:-unknown})" | |
| echo "workflow=${GITHUB_WORKFLOW:-unknown}" | |
| echo "job=${GITHUB_JOB:-unknown}" | |
| echo "run_id=${GITHUB_RUN_ID:-unknown}" | |
| echo "ref=${GITHUB_REF:-unknown}" | |
| echo "sha=${GITHUB_SHA:-unknown}" | |
| } > "$LOGS_DIR/run.log" | |
| - name: Install xcbeautify | |
| run: | | |
| if command -v xcbeautify >/dev/null 2>&1 | |
| then | |
| echo "xcbeautify already installed." | |
| elif brew install xcbeautify > logs/install-xcbeautify.log 2>&1 | |
| then | |
| echo "xcbeautify installed." | |
| else | |
| echo "::error::Failed to install xcbeautify." | |
| cat logs/install-xcbeautify.log | |
| exit 1 | |
| fi | |
| - name: Resolve Xcode Version | |
| id: resolve-xcode | |
| run: | | |
| REQUESTED_SWIFT="6.3" | |
| PREFERRED_XCODE="26.4" | |
| ls -d /Applications/Xcode* > logs/xcode-versions.log | |
| FOUND_XCODE="" | |
| while read -r APP | |
| do | |
| DEV_DIR="$APP/Contents/Developer" | |
| SWIFT_VERSION=$(DEVELOPER_DIR="$DEV_DIR" xcrun swift --version 2>/dev/null | head -n 1 | sed -E 's/.*version ([0-9]+\.[0-9]+).*/\1/') | |
| XCODE_VERSION=$(DEVELOPER_DIR="$DEV_DIR" xcodebuild -version 2>/dev/null | awk '/^Xcode / {print $2; exit}') | |
| if [[ "$SWIFT_VERSION" == "$REQUESTED_SWIFT" ]] | |
| then | |
| FOUND_XCODE="$XCODE_VERSION" | |
| if [[ "$APP" == *[Bb][Ee][Tt][Aa]* ]] | |
| then | |
| FOUND_XCODE="$FOUND_XCODE-beta" | |
| fi | |
| if [[ "$XCODE_VERSION" == "$PREFERRED_XCODE"* ]] | |
| then | |
| break | |
| fi | |
| fi | |
| done < <(ls -d /Applications/Xcode*.app | sort -Vr) | |
| if [[ "$FOUND_XCODE" == "" ]] | |
| then | |
| echo "No installed Xcode matched Swift $REQUESTED_SWIFT." | |
| echo "Detected toolchains:" | |
| while read -r APP | |
| do | |
| DEV_DIR="$APP/Contents/Developer" | |
| XCODE_VERSION=$(DEVELOPER_DIR="$DEV_DIR" xcodebuild -version 2>/dev/null | awk '/^Xcode / {print $2; exit}') | |
| SWIFT_VERSION=$(DEVELOPER_DIR="$DEV_DIR" xcrun swift --version 2>/dev/null | head -n 1 | sed -E 's/.*version ([0-9]+\.[0-9]+).*/\1/') | |
| echo " Xcode $XCODE_VERSION -> Swift $SWIFT_VERSION" | |
| done < <(ls -d /Applications/Xcode*.app | sort -Vr) | |
| exit 1 | |
| fi | |
| echo "version=$FOUND_XCODE" >> "$GITHUB_OUTPUT" | |
| - name: Select Xcode Version | |
| uses: maxim-lobanov/setup-xcode@v1 | |
| with: | |
| xcode-version: ${{ steps.resolve-xcode.outputs.version }} | |
| - name: Xcode Version | |
| run: | | |
| xcodebuild -version | |
| swift --version | |
| - name: Prepare Destination Picker | |
| run: | | |
| cat > destination-picker.sh <<'EOF' | |
| extract_destination_field() { | |
| local line="$1" | |
| local field="$2" | |
| printf '%s\n' "$line" | sed -nE "s/.*${field}:[[:space:]]*([^,}]+).*/\\1/p" | xargs | |
| } | |
| load_best_destination() { | |
| local destinations_log="$1" | |
| local simulator_platform="$2" | |
| local device_name_prefix="$3" | |
| BEST_DESTINATION=$( | |
| while IFS= read -r line | |
| do | |
| [[ "$line" == *"platform:${simulator_platform}"* ]] || continue | |
| [[ "$line" == *"name:${device_name_prefix}"* ]] || continue | |
| [[ "$line" != *"unavailable"* ]] || continue | |
| id=$(extract_destination_field "$line" "id") | |
| os=$(extract_destination_field "$line" "OS") | |
| name=$(extract_destination_field "$line" "name") | |
| [[ -n "$id" && -n "$os" ]] || continue | |
| IFS=. read -r major minor patch <<< "$os" | |
| printf "%d\t%d\t%d\t%s\t%s\t%s\n" "${major:-0}" "${minor:-0}" "${patch:-0}" "$os" "$id" "$name" | |
| done < "$destinations_log" | sort -k1,1nr -k2,2nr -k3,3nr | head -n 1 | |
| ) | |
| DESTINATION_OS=$(echo "$BEST_DESTINATION" | awk -F"\t" '{print $4}' | xargs) | |
| DESTINATION_ID=$(echo "$BEST_DESTINATION" | awk -F"\t" '{print $5}' | xargs) | |
| DESTINATION_NAME=$(echo "$BEST_DESTINATION" | awk -F"\t" '{print $6}' | xargs) | |
| [[ "$DESTINATION_NAME" != "" && "$DESTINATION_OS" != "" ]] | |
| } | |
| pick_destination_if_available() { | |
| local platform_id="$1" | |
| local simulator_platform="$2" | |
| local device_name_prefix="$3" | |
| local destinations_log="logs/destinations-${platform_id}.log" | |
| load_best_destination "$destinations_log" "$simulator_platform" "$device_name_prefix" | |
| } | |
| pick_destination() { | |
| local platform_id="$1" | |
| local simulator_platform="$2" | |
| local device_name_prefix="$3" | |
| local failure_message="$4" | |
| local destinations_log="logs/destinations-${platform_id}.log" | |
| if ! load_best_destination "$destinations_log" "$simulator_platform" "$device_name_prefix" | |
| then | |
| echo "$failure_message" | |
| cat "$destinations_log" | |
| return 1 | |
| fi | |
| } | |
| boot_destination() { | |
| local platform_id="$1" | |
| local platform_name="$2" | |
| local boot_log="logs/boot-${platform_id}.log" | |
| echo "Booting ${platform_name} simulator ${DESTINATION_NAME:-unknown} (OS ${DESTINATION_OS:-unknown}, id=${DESTINATION_ID:-unknown})." | |
| xcrun simctl boot "$DESTINATION_ID" >"$boot_log" 2>&1 || true | |
| if ! xcrun simctl bootstatus "$DESTINATION_ID" -b >>"$boot_log" 2>&1 | |
| then | |
| echo "Failed to boot ${platform_name} simulator ${DESTINATION_NAME:-unknown} (OS ${DESTINATION_OS:-unknown}, id=${DESTINATION_ID:-unknown})." | |
| cat "$boot_log" | |
| return 1 | |
| fi | |
| } | |
| EOF | |
| - name: Detect Workspace & Scheme (iOS) | |
| run: | | |
| WORKSPACE="Icons.xcworkspace" | |
| if [[ ! -e "$WORKSPACE" ]] | |
| then | |
| WORKSPACE="." | |
| GOTPACKAGE=$(xcodebuild -workspace . -list | (grep Icons-Package || true)) | |
| if [[ $GOTPACKAGE != "" ]] | |
| then | |
| SCHEME="Icons-Package" | |
| else | |
| SCHEME="Icons" | |
| fi | |
| else | |
| SCHEME="Icons-iOS" | |
| fi | |
| echo "export PATH='swift-latest:$PATH'; WORKSPACE='$WORKSPACE'; SCHEME='$SCHEME'" > setup.sh | |
| - name: Select Simulator Destination (iOS) | |
| id: select-destination | |
| run: | | |
| source "setup.sh" | |
| source "destination-picker.sh" | |
| echo "available=false" >> "$GITHUB_OUTPUT" | |
| mark_destination_unavailable() { | |
| local message="$1" | |
| local log="${2:-}" | |
| echo "::warning::$message" | |
| if [[ -n "$log" && -f "$log" ]] | |
| then | |
| cat "$log" | |
| fi | |
| { | |
| echo "### iOS simulator unavailable" | |
| echo "" | |
| echo "$message" | |
| echo "" | |
| echo "Build/test steps for this job were skipped because the simulator destination could not be prepared." | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| } | |
| if ! xcrun simctl list > logs/simctl-list-iOS.log 2>&1 | |
| then | |
| mark_destination_unavailable "Unable to connect to CoreSimulator while preparing iOS." "logs/simctl-list-iOS.log" | |
| exit 0 | |
| fi | |
| if ! xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -showdestinations > logs/destinations-iOS.log 2>&1 | |
| then | |
| mark_destination_unavailable "Unable to list iOS simulator destinations." "logs/destinations-iOS.log" | |
| exit 0 | |
| fi | |
| if pick_destination_if_available "iOS" "iOS Simulator" "iPhone" | |
| then | |
| echo "Using existing iOS simulator destination." | |
| else | |
| echo "No available iOS simulator destination found. Downloading platform support." | |
| if ! xcodebuild -downloadPlatform iOS > logs/download-iOS.log 2>&1 | |
| then | |
| mark_destination_unavailable "Unable to download iOS platform support." "logs/download-iOS.log" | |
| exit 0 | |
| fi | |
| if ! xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -showdestinations > logs/destinations-iOS.log 2>&1 | |
| then | |
| mark_destination_unavailable "Unable to list iOS simulator destinations after downloading platform support." "logs/destinations-iOS.log" | |
| exit 0 | |
| fi | |
| if ! pick_destination_if_available "iOS" "iOS Simulator" "iPhone" | |
| then | |
| mark_destination_unavailable "No available non-beta iPhone simulator destination found." "logs/destinations-iOS.log" | |
| exit 0 | |
| fi | |
| fi | |
| echo "Selected iOS simulator: ${DESTINATION_NAME:-unknown} (OS ${DESTINATION_OS:-unknown}, id=${DESTINATION_ID:-unknown})." | |
| if ! boot_destination "iOS" "iOS" | |
| then | |
| mark_destination_unavailable "Failed to boot iOS simulator ${DESTINATION_NAME:-unknown} (OS ${DESTINATION_OS:-unknown}, id=${DESTINATION_ID:-unknown})." "logs/boot-iOS.log" | |
| exit 0 | |
| fi | |
| { | |
| echo "available=true" | |
| echo "id=$DESTINATION_ID" | |
| echo "name=$DESTINATION_NAME" | |
| echo "os=$DESTINATION_OS" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Test (iOS Release) | |
| if: ${{ steps.select-destination.outputs.available == 'true' }} | |
| run: | | |
| set -o pipefail | |
| source "setup.sh" | |
| DESTINATION_ID="${{ steps.select-destination.outputs.id }}" | |
| DESTINATION_NAME="${{ steps.select-destination.outputs.name }}" | |
| DESTINATION_OS="${{ steps.select-destination.outputs.os }}" | |
| echo "Testing workspace $WORKSPACE scheme $SCHEME on ${DESTINATION_NAME:-unknown} (iOS ${DESTINATION_OS:-unknown}, id=${DESTINATION_ID:-unknown})." | |
| xcodebuild test -workspace "$WORKSPACE" -scheme "$SCHEME" -destination "id=$DESTINATION_ID" -configuration Release CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO ENABLE_TESTABILITY=YES | tee logs/xcodebuild-iOS-test-release.log | xcbeautify --quiet --disable-logging --renderer github-actions | |
| - name: Upload Logs | |
| uses: actions/upload-artifact@v7 | |
| if: always() | |
| with: | |
| name: iOS-swift63-logs | |
| path: logs | |
| macOS-swift63: | |
| name: macOS (Swift 6.3) | |
| runs-on: macos-26 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Make Logs Directory | |
| run: | | |
| LOGS_DIR="${GITHUB_WORKSPACE:-$PWD}/logs" | |
| mkdir -p "$LOGS_DIR" | |
| if [[ "$PWD/logs" != "$LOGS_DIR" && ! -e logs ]] | |
| then | |
| ln -s "$LOGS_DIR" logs | |
| fi | |
| { | |
| echo "timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)" | |
| echo "runner=${RUNNER_NAME:-unknown} (${RUNNER_OS:-unknown}/${RUNNER_ARCH:-unknown})" | |
| echo "workflow=${GITHUB_WORKFLOW:-unknown}" | |
| echo "job=${GITHUB_JOB:-unknown}" | |
| echo "run_id=${GITHUB_RUN_ID:-unknown}" | |
| echo "ref=${GITHUB_REF:-unknown}" | |
| echo "sha=${GITHUB_SHA:-unknown}" | |
| } > "$LOGS_DIR/run.log" | |
| - name: Install xcbeautify | |
| run: | | |
| if command -v xcbeautify >/dev/null 2>&1 | |
| then | |
| echo "xcbeautify already installed." | |
| elif brew install xcbeautify > logs/install-xcbeautify.log 2>&1 | |
| then | |
| echo "xcbeautify installed." | |
| else | |
| echo "::error::Failed to install xcbeautify." | |
| cat logs/install-xcbeautify.log | |
| exit 1 | |
| fi | |
| - name: Select Swift | |
| uses: elegantchaos/setup-swift@allow-patch | |
| with: | |
| swift-version: "6.3" | |
| allow-patch: true | |
| - name: Swift Version | |
| run: swift --version | |
| - name: Build (release) | |
| run: | | |
| LOG="logs/swift-build-release.log" | |
| if swift build --configuration release --quiet >"$LOG" 2>&1 | |
| then | |
| echo "Build (release) succeeded." | |
| else | |
| echo "::error::Build (release) failed." | |
| cat "$LOG" | xcbeautify --quiet --disable-logging --renderer github-actions || cat "$LOG" | |
| echo "Build (release) failed." | |
| exit 1 | |
| fi | |
| - name: Test (release XCTest) | |
| run: | | |
| LOG="logs/swift-test-xctest-release.log" | |
| if swift test --disable-swift-testing --configuration release >"$LOG" 2>&1 | |
| then | |
| echo "Test (release XCTest) succeeded." | |
| else | |
| echo "::error::Test (release XCTest) failed." | |
| cat "$LOG" | xcbeautify --quiet --disable-logging --renderer github-actions || cat "$LOG" | |
| echo "Test (release XCTest) failed." | |
| exit 1 | |
| fi | |
| - name: Test (release Swift Testing) | |
| run: | | |
| LOG="logs/swift-test-swift-testing-release.log" | |
| if swift test --disable-xctest --configuration release >"$LOG" 2>&1 | |
| then | |
| echo "Test (release Swift Testing) succeeded." | |
| else | |
| echo "::error::Test (release Swift Testing) failed." | |
| cat "$LOG" | xcbeautify --quiet --disable-logging --renderer github-actions || cat "$LOG" | |
| echo "Test (release Swift Testing) failed." | |
| exit 1 | |
| fi | |
| - name: Upload Logs | |
| uses: actions/upload-artifact@v7 | |
| if: always() | |
| with: | |
| name: macOS-swift63-logs | |
| path: logs | |
| tvOS-swift63: | |
| name: tvOS (Swift 6.3, Xcode matching Swift 6.3) | |
| runs-on: macos-26 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Make Logs Directory | |
| run: | | |
| LOGS_DIR="${GITHUB_WORKSPACE:-$PWD}/logs" | |
| mkdir -p "$LOGS_DIR" | |
| if [[ "$PWD/logs" != "$LOGS_DIR" && ! -e logs ]] | |
| then | |
| ln -s "$LOGS_DIR" logs | |
| fi | |
| { | |
| echo "timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)" | |
| echo "runner=${RUNNER_NAME:-unknown} (${RUNNER_OS:-unknown}/${RUNNER_ARCH:-unknown})" | |
| echo "workflow=${GITHUB_WORKFLOW:-unknown}" | |
| echo "job=${GITHUB_JOB:-unknown}" | |
| echo "run_id=${GITHUB_RUN_ID:-unknown}" | |
| echo "ref=${GITHUB_REF:-unknown}" | |
| echo "sha=${GITHUB_SHA:-unknown}" | |
| } > "$LOGS_DIR/run.log" | |
| - name: Install xcbeautify | |
| run: | | |
| if command -v xcbeautify >/dev/null 2>&1 | |
| then | |
| echo "xcbeautify already installed." | |
| elif brew install xcbeautify > logs/install-xcbeautify.log 2>&1 | |
| then | |
| echo "xcbeautify installed." | |
| else | |
| echo "::error::Failed to install xcbeautify." | |
| cat logs/install-xcbeautify.log | |
| exit 1 | |
| fi | |
| - name: Resolve Xcode Version | |
| id: resolve-xcode | |
| run: | | |
| REQUESTED_SWIFT="6.3" | |
| PREFERRED_XCODE="26.4" | |
| ls -d /Applications/Xcode* > logs/xcode-versions.log | |
| FOUND_XCODE="" | |
| while read -r APP | |
| do | |
| DEV_DIR="$APP/Contents/Developer" | |
| SWIFT_VERSION=$(DEVELOPER_DIR="$DEV_DIR" xcrun swift --version 2>/dev/null | head -n 1 | sed -E 's/.*version ([0-9]+\.[0-9]+).*/\1/') | |
| XCODE_VERSION=$(DEVELOPER_DIR="$DEV_DIR" xcodebuild -version 2>/dev/null | awk '/^Xcode / {print $2; exit}') | |
| if [[ "$SWIFT_VERSION" == "$REQUESTED_SWIFT" ]] | |
| then | |
| FOUND_XCODE="$XCODE_VERSION" | |
| if [[ "$APP" == *[Bb][Ee][Tt][Aa]* ]] | |
| then | |
| FOUND_XCODE="$FOUND_XCODE-beta" | |
| fi | |
| if [[ "$XCODE_VERSION" == "$PREFERRED_XCODE"* ]] | |
| then | |
| break | |
| fi | |
| fi | |
| done < <(ls -d /Applications/Xcode*.app | sort -Vr) | |
| if [[ "$FOUND_XCODE" == "" ]] | |
| then | |
| echo "No installed Xcode matched Swift $REQUESTED_SWIFT." | |
| echo "Detected toolchains:" | |
| while read -r APP | |
| do | |
| DEV_DIR="$APP/Contents/Developer" | |
| XCODE_VERSION=$(DEVELOPER_DIR="$DEV_DIR" xcodebuild -version 2>/dev/null | awk '/^Xcode / {print $2; exit}') | |
| SWIFT_VERSION=$(DEVELOPER_DIR="$DEV_DIR" xcrun swift --version 2>/dev/null | head -n 1 | sed -E 's/.*version ([0-9]+\.[0-9]+).*/\1/') | |
| echo " Xcode $XCODE_VERSION -> Swift $SWIFT_VERSION" | |
| done < <(ls -d /Applications/Xcode*.app | sort -Vr) | |
| exit 1 | |
| fi | |
| echo "version=$FOUND_XCODE" >> "$GITHUB_OUTPUT" | |
| - name: Select Xcode Version | |
| uses: maxim-lobanov/setup-xcode@v1 | |
| with: | |
| xcode-version: ${{ steps.resolve-xcode.outputs.version }} | |
| - name: Xcode Version | |
| run: | | |
| xcodebuild -version | |
| swift --version | |
| - name: Prepare Destination Picker | |
| run: | | |
| cat > destination-picker.sh <<'EOF' | |
| extract_destination_field() { | |
| local line="$1" | |
| local field="$2" | |
| printf '%s\n' "$line" | sed -nE "s/.*${field}:[[:space:]]*([^,}]+).*/\\1/p" | xargs | |
| } | |
| load_best_destination() { | |
| local destinations_log="$1" | |
| local simulator_platform="$2" | |
| local device_name_prefix="$3" | |
| BEST_DESTINATION=$( | |
| while IFS= read -r line | |
| do | |
| [[ "$line" == *"platform:${simulator_platform}"* ]] || continue | |
| [[ "$line" == *"name:${device_name_prefix}"* ]] || continue | |
| [[ "$line" != *"unavailable"* ]] || continue | |
| id=$(extract_destination_field "$line" "id") | |
| os=$(extract_destination_field "$line" "OS") | |
| name=$(extract_destination_field "$line" "name") | |
| [[ -n "$id" && -n "$os" ]] || continue | |
| IFS=. read -r major minor patch <<< "$os" | |
| printf "%d\t%d\t%d\t%s\t%s\t%s\n" "${major:-0}" "${minor:-0}" "${patch:-0}" "$os" "$id" "$name" | |
| done < "$destinations_log" | sort -k1,1nr -k2,2nr -k3,3nr | head -n 1 | |
| ) | |
| DESTINATION_OS=$(echo "$BEST_DESTINATION" | awk -F"\t" '{print $4}' | xargs) | |
| DESTINATION_ID=$(echo "$BEST_DESTINATION" | awk -F"\t" '{print $5}' | xargs) | |
| DESTINATION_NAME=$(echo "$BEST_DESTINATION" | awk -F"\t" '{print $6}' | xargs) | |
| [[ "$DESTINATION_NAME" != "" && "$DESTINATION_OS" != "" ]] | |
| } | |
| pick_destination_if_available() { | |
| local platform_id="$1" | |
| local simulator_platform="$2" | |
| local device_name_prefix="$3" | |
| local destinations_log="logs/destinations-${platform_id}.log" | |
| load_best_destination "$destinations_log" "$simulator_platform" "$device_name_prefix" | |
| } | |
| pick_destination() { | |
| local platform_id="$1" | |
| local simulator_platform="$2" | |
| local device_name_prefix="$3" | |
| local failure_message="$4" | |
| local destinations_log="logs/destinations-${platform_id}.log" | |
| if ! load_best_destination "$destinations_log" "$simulator_platform" "$device_name_prefix" | |
| then | |
| echo "$failure_message" | |
| cat "$destinations_log" | |
| return 1 | |
| fi | |
| } | |
| boot_destination() { | |
| local platform_id="$1" | |
| local platform_name="$2" | |
| local boot_log="logs/boot-${platform_id}.log" | |
| echo "Booting ${platform_name} simulator ${DESTINATION_NAME:-unknown} (OS ${DESTINATION_OS:-unknown}, id=${DESTINATION_ID:-unknown})." | |
| xcrun simctl boot "$DESTINATION_ID" >"$boot_log" 2>&1 || true | |
| if ! xcrun simctl bootstatus "$DESTINATION_ID" -b >>"$boot_log" 2>&1 | |
| then | |
| echo "Failed to boot ${platform_name} simulator ${DESTINATION_NAME:-unknown} (OS ${DESTINATION_OS:-unknown}, id=${DESTINATION_ID:-unknown})." | |
| cat "$boot_log" | |
| return 1 | |
| fi | |
| } | |
| EOF | |
| - name: Detect Workspace & Scheme (tvOS) | |
| run: | | |
| WORKSPACE="Icons.xcworkspace" | |
| if [[ ! -e "$WORKSPACE" ]] | |
| then | |
| WORKSPACE="." | |
| GOTPACKAGE=$(xcodebuild -workspace . -list | (grep Icons-Package || true)) | |
| if [[ $GOTPACKAGE != "" ]] | |
| then | |
| SCHEME="Icons-Package" | |
| else | |
| SCHEME="Icons" | |
| fi | |
| else | |
| SCHEME="Icons-tvOS" | |
| fi | |
| echo "export PATH='swift-latest:$PATH'; WORKSPACE='$WORKSPACE'; SCHEME='$SCHEME'" > setup.sh | |
| - name: Select Simulator Destination (tvOS) | |
| id: select-destination | |
| run: | | |
| source "setup.sh" | |
| source "destination-picker.sh" | |
| echo "available=false" >> "$GITHUB_OUTPUT" | |
| mark_destination_unavailable() { | |
| local message="$1" | |
| local log="${2:-}" | |
| echo "::warning::$message" | |
| if [[ -n "$log" && -f "$log" ]] | |
| then | |
| cat "$log" | |
| fi | |
| { | |
| echo "### tvOS simulator unavailable" | |
| echo "" | |
| echo "$message" | |
| echo "" | |
| echo "Build/test steps for this job were skipped because the simulator destination could not be prepared." | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| } | |
| if ! xcrun simctl list > logs/simctl-list-tvOS.log 2>&1 | |
| then | |
| mark_destination_unavailable "Unable to connect to CoreSimulator while preparing tvOS." "logs/simctl-list-tvOS.log" | |
| exit 0 | |
| fi | |
| if ! xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -showdestinations > logs/destinations-tvOS.log 2>&1 | |
| then | |
| mark_destination_unavailable "Unable to list tvOS simulator destinations." "logs/destinations-tvOS.log" | |
| exit 0 | |
| fi | |
| if pick_destination_if_available "tvOS" "tvOS Simulator" "Apple TV" | |
| then | |
| echo "Using existing tvOS simulator destination." | |
| else | |
| echo "No available tvOS simulator destination found. Downloading platform support." | |
| if ! xcodebuild -downloadPlatform tvOS > logs/download-tvOS.log 2>&1 | |
| then | |
| mark_destination_unavailable "Unable to download tvOS platform support." "logs/download-tvOS.log" | |
| exit 0 | |
| fi | |
| if ! xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -showdestinations > logs/destinations-tvOS.log 2>&1 | |
| then | |
| mark_destination_unavailable "Unable to list tvOS simulator destinations after downloading platform support." "logs/destinations-tvOS.log" | |
| exit 0 | |
| fi | |
| if ! pick_destination_if_available "tvOS" "tvOS Simulator" "Apple TV" | |
| then | |
| mark_destination_unavailable "No available non-beta Apple TV simulator destination found." "logs/destinations-tvOS.log" | |
| exit 0 | |
| fi | |
| fi | |
| echo "Selected tvOS simulator: ${DESTINATION_NAME:-unknown} (OS ${DESTINATION_OS:-unknown}, id=${DESTINATION_ID:-unknown})." | |
| if ! boot_destination "tvOS" "tvOS" | |
| then | |
| mark_destination_unavailable "Failed to boot tvOS simulator ${DESTINATION_NAME:-unknown} (OS ${DESTINATION_OS:-unknown}, id=${DESTINATION_ID:-unknown})." "logs/boot-tvOS.log" | |
| exit 0 | |
| fi | |
| { | |
| echo "available=true" | |
| echo "id=$DESTINATION_ID" | |
| echo "name=$DESTINATION_NAME" | |
| echo "os=$DESTINATION_OS" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Test (tvOS Release) | |
| if: ${{ steps.select-destination.outputs.available == 'true' }} | |
| run: | | |
| set -o pipefail | |
| source "setup.sh" | |
| DESTINATION_ID="${{ steps.select-destination.outputs.id }}" | |
| DESTINATION_NAME="${{ steps.select-destination.outputs.name }}" | |
| DESTINATION_OS="${{ steps.select-destination.outputs.os }}" | |
| echo "Testing workspace $WORKSPACE scheme $SCHEME on ${DESTINATION_NAME:-unknown} (tvOS ${DESTINATION_OS:-unknown}, id=${DESTINATION_ID:-unknown})." | |
| xcodebuild test -workspace "$WORKSPACE" -scheme "$SCHEME" -destination "id=$DESTINATION_ID" -configuration Release CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO ENABLE_TESTABILITY=YES | tee logs/xcodebuild-tvOS-test-release.log | xcbeautify --quiet --disable-logging --renderer github-actions | |
| - name: Upload Logs | |
| uses: actions/upload-artifact@v7 | |
| if: always() | |
| with: | |
| name: tvOS-swift63-logs | |
| path: logs | |