Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .github/actions/prepare-simulator/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: "Prepare simulator"
description: "Creates and boots a custom simulator"
inputs:
runtime:
description: "Runtime name"
required: true
device:
description: "Device name"
required: true
outputs:
destination-id:
description: "Destination simulator ID"
value: ${{ steps.simulator.outputs.destination-id }}
runs:
using: composite
steps:
- name: "Install runtime"
shell: bash
run: |
RUNTIME="${{ inputs.runtime }}"
if xcrun simctl list | grep "$RUNTIME"
then
echo "$RUNTIME is already installed.";
else
echo "::group::Available runtimes:"
xcodes runtimes
echo "::endgroup::"
sudo xcodes runtimes install "$RUNTIME" --keep-archive;
fi

- name: "Create and boot simulator"
id: simulator
shell: bash
run: |
RUNTIME="${{ inputs.runtime }}"
DEVICE="${{ inputs.device }}"

DEVICE_ID=$(xcrun simctl list devicetypes -j | jq -r ".devicetypes.[] | select(.name==\"$DEVICE\").identifier")
echo $DEVICE_ID
if [ $(echo $DEVICE_ID | wc -l) != 1 ] || [ "$DEVICE_ID" = "" ]; then echo "Invalid Device ID"; exit 1; fi

RUNTIME_ID=$(xcrun simctl list runtimes -j | jq -r ".runtimes.[] | select(.name==\"$RUNTIME\").identifier")
echo $RUNTIME_ID
if [ $(echo $RUNTIME_ID | wc -l) != 1 ] || [ "$RUNTIME_ID" = "" ]; then echo "Invalid Runtime ID"; exit 1; fi

DESTINATION_ID=$(xcrun simctl create "Custom: $DEVICE, $RUNTIME" $DEVICE_ID $RUNTIME_ID)
xcrun simctl boot $DESTINATION_ID
echo "destination-id=$(echo $DESTINATION_ID)" >> $GITHUB_OUTPUT
83 changes: 83 additions & 0 deletions .github/workflows/xcode.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Xcode

on:
pull_request:
push:
branches: [develop, release]

jobs:
simulator:
name: "${{ matrix.scheme }}, Xcode ${{ matrix.env.xcode }}, ${{ matrix.env.runtime }}, ${{ matrix.env.device }}"
runs-on: macOS-26
strategy:
fail-fast: false
matrix:
scheme:
- "Base16"
- "Base32"
env:
- xcode: 26.4
runtime: "iOS 26.4"
device: "iPhone 17 Pro Max"
- xcode: 26.4
runtime: "watchOS 26.4"
device: "Apple Watch Series 11 (46mm)"
- xcode: 26.4
runtime: "tvOS 26.4"
device: "Apple TV 4K (3rd generation)"
- xcode: 26.4
runtime: "visionOS 26.4"
device: "Apple Vision Pro"
steps:
- uses: actions/checkout@v6
- name: "Select Xcode ${{ matrix.env.xcode }}"
uses: ./.github/actions/xcode-select
with:
version: ${{ matrix.env.xcode }}
- name: "Cache downloaded simulator runtimes"
uses: actions/cache@v5
with:
path: ~/Downloads/*.dmg
key: Xcode ${{ matrix.env.xcode }}+${{ matrix.env.runtime }}
- name: "Prepare simulator"
id: prepare-simulator
uses: ./.github/actions/prepare-simulator
with:
runtime: ${{ matrix.env.runtime }}
device: ${{ matrix.env.device }}
- name: "Build and test"
run: xcodebuild test -scheme "${{ matrix.scheme }}" -destination "id=${{ steps.prepare-simulator.outputs.destination-id }}"
- uses: sersoft-gmbh/swift-coverage-action@v5
with:
target-name-filter: ^Identifier$
- uses: codecov/codecov-action@v6
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true

macos:
name: "${{ matrix.scheme }}, Xcode ${{ matrix.xcode }}, macOS 26"
runs-on: macOS-26
strategy:
fail-fast: false
matrix:
scheme:
- "Base16"
- "Base32"
xcode:
- "26.4"
steps:
- uses: actions/checkout@v6
- name: "Select Xcode ${{ matrix.xcode }}"
uses: ./.github/actions/xcode-select
with:
version: ${{ matrix.xcode }}
- name: "Build and test"
run: xcodebuild test -scheme "${{ matrix.scheme }}" -destination "name=My Mac"
- uses: sersoft-gmbh/swift-coverage-action@v5
with:
target-name-filter: ^Identifier$
- uses: codecov/codecov-action@v6
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
Loading