Skip to content
Merged
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
30 changes: 30 additions & 0 deletions .github/actions/select-simulator/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Select iOS simulator
description: >
Finds the first available iPhone simulator, downloading the iOS platform
first if none is installed, and exposes its name as the `device` output.
outputs:
device:
description: The name of the selected iPhone simulator.
value: ${{ steps.select.outputs.device }}
runs:
using: composite
steps:
- id: select
shell: bash
run: |
set -euo pipefail
find_device() {
xcrun simctl list devices available --json \
| jq -r '[.devices | to_entries[] | select(.key|test("iOS")) | .value[] | select(.isAvailable and (.name|startswith("iPhone")))][0].name // empty'
}
DEVICE=$(find_device)
if [ -z "$DEVICE" ]; then
sudo xcodebuild -downloadPlatform iOS
DEVICE=$(find_device)
fi
if [ -z "$DEVICE" ]; then
echo "::error::No available iPhone simulator found" >&2
exit 1
fi
echo "device=$DEVICE" >> "$GITHUB_OUTPUT"
echo "Using: $DEVICE"
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Keep the GitHub Actions used by the workflows up to date. The library has no
# package dependencies, so actions are the only ecosystem to watch.
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
groups:
actions:
patterns:
- "*"
1 change: 1 addition & 0 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ jobs:
deploy:
name: Deploy to GitHub Pages
runs-on: macos-26
timeout-minutes: 30
permissions:
contents: read
pages: write
Expand Down
36 changes: 22 additions & 14 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
pull_request:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: test-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
Expand All @@ -14,6 +17,7 @@ jobs:
package:
name: Package tests (iOS Simulator)
runs-on: macos-26
timeout-minutes: 45
steps:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: if the simulator isn't preinstalled, the fallback in select-simulator runs sudo xcodebuild -downloadPlatform iOS, which can itself take a while — combined with the actual test run, this could occasionally bump into the new 30-minute cap on a cold runner. Not a blocker since this is a rare fallback path, just something to watch if CI starts timing out intermittently.

- uses: actions/checkout@v7
- name: Select Xcode
Expand All @@ -26,13 +30,7 @@ jobs:
swift --version
- name: Select simulator
id: sim
run: |
DEVICE=$(xcrun simctl list devices available --json \
| jq -r '[.devices | to_entries[] | select(.key|test("iOS")) | .value[] | select(.isAvailable and (.name|startswith("iPhone")))][0].name // empty')
if [ -z "$DEVICE" ]; then sudo xcodebuild -downloadPlatform iOS; DEVICE=$(xcrun simctl list devices available --json | jq -r '[.devices|to_entries[]|select(.key|test("iOS"))|.value[]|select(.isAvailable and (.name|startswith("iPhone")))][0].name // empty'); fi
if [ -z "$DEVICE" ]; then echo "::error::No available iPhone simulator found" >&2; exit 1; fi
echo "device=$DEVICE" >> "$GITHUB_OUTPUT"
echo "Using: $DEVICE"
uses: ./.github/actions/select-simulator
- name: Test
run: |
set -o pipefail
Expand All @@ -41,11 +39,26 @@ jobs:
xcodebuild test \
-scheme SwipeMenuViewController \
-destination "platform=iOS Simulator,name=${{ steps.sim.outputs.device }}" \
-enableCodeCoverage YES \
-resultBundlePath TestResults.xcresult \
CODE_SIGNING_ALLOWED=NO
- name: Report code coverage
run: |
set -euo pipefail
{
echo "### Code coverage"
echo ""
echo "| Target | Line coverage |"
echo "|---|---|"
# List the library targets only; the test bundle's own coverage is noise.
xcrun xccov view --report --json TestResults.xcresult \
| jq -r '.targets[] | select(((.name | endswith(".xctest")) or (.name | endswith("Tests"))) | not) | "| \(.name) | \((.lineCoverage * 10000 | round) / 100)% |"'
} >> "$GITHUB_STEP_SUMMARY"

example:
name: Example app build
runs-on: macos-26
timeout-minutes: 45
steps:
- uses: actions/checkout@v7
- name: Select Xcode
Expand All @@ -68,13 +81,7 @@ jobs:
run: xcodegen generate --spec Example/project.yml
- name: Select simulator
id: sim
run: |
DEVICE=$(xcrun simctl list devices available --json \
| jq -r '[.devices | to_entries[] | select(.key|test("iOS")) | .value[] | select(.isAvailable and (.name|startswith("iPhone")))][0].name // empty')
if [ -z "$DEVICE" ]; then sudo xcodebuild -downloadPlatform iOS; DEVICE=$(xcrun simctl list devices available --json | jq -r '[.devices|to_entries[]|select(.key|test("iOS"))|.value[]|select(.isAvailable and (.name|startswith("iPhone")))][0].name // empty'); fi
if [ -z "$DEVICE" ]; then echo "::error::No available iPhone simulator found" >&2; exit 1; fi
echo "device=$DEVICE" >> "$GITHUB_OUTPUT"
echo "Using: $DEVICE"
uses: ./.github/actions/select-simulator
- name: Build and test
run: |
set -o pipefail
Expand All @@ -88,6 +95,7 @@ jobs:
docc:
name: Documentation build
runs-on: macos-26
timeout-minutes: 20
steps:
- uses: actions/checkout@v7
- name: Select Xcode
Expand Down