Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
a235934
Add JsonPretty format option, make Json compact
mattleibow Feb 15, 2026
68e4873
Enhance simulator create: return UDID, add --boot --wait --format flags
mattleibow Feb 15, 2026
151d4ca
Enhance simulator boot: add --format, improve error handling
mattleibow Feb 15, 2026
885b013
Add --force flag to simulator delete
mattleibow Feb 15, 2026
94d2cce
Add tests, enable CI tests, split into 3 pipelines, add E2E
mattleibow Feb 15, 2026
fab3498
Fix run.yml: use --no-launch-profile to prevent launch settings prefix
mattleibow Feb 15, 2026
48f7324
Fix run.yml verify step: use xcrun simctl list instead of broken JSON
mattleibow Feb 15, 2026
7ea9e63
Update to .NET 10, add iOS workload install
mattleibow Feb 15, 2026
908cf26
Fix E2E: use sed injection instead of partial class for log marker
mattleibow Feb 15, 2026
6a09afc
Fix run.yml: add Xcode 26.2 setup for iOS app build
mattleibow Feb 15, 2026
a733b15
Fix run.yml: use build output instead of publish for simulator
mattleibow Feb 15, 2026
5c8de2c
Fix run.yml: use build output for sim, redirect NBGV env to /dev/null
mattleibow Feb 15, 2026
9fb5fb3
Fix run.yml: validate every step, use jq/xcrun for verification
mattleibow Feb 15, 2026
147004f
Fix run.yml: verify install with simulator app list --format json
mattleibow Feb 15, 2026
48182aa
Fix JSON output: use Console.WriteLine instead of AnsiConsole.WriteLine
mattleibow Feb 15, 2026
74631c2
Fix run.yml: correct install/launch args, case-sensitive bundle ID, s…
mattleibow Feb 15, 2026
41a2f7a
Fix run.yml: add --no-build to prevent MSBuild warnings in stdout
mattleibow Feb 15, 2026
3356eb3
ci: use dotnet DLL invocation instead of dotnet run
mattleibow Feb 15, 2026
19b0187
ci: use dotnet publish for iOS app and search in bin/ only
mattleibow Feb 15, 2026
dff7ec4
ci: use dotnet build instead of publish for simulator app
mattleibow Feb 15, 2026
0fe44ec
ci: improve app path discovery with fallback search
mattleibow Feb 15, 2026
142446d
ci: replace timeout with background process for macOS compat
mattleibow Feb 15, 2026
31e3aa8
fix: increase simulator boot timeout to 300s for Xcode 26.2
mattleibow Feb 15, 2026
d2f13eb
fix: restructure log capture to run synchronously after launch
mattleibow Feb 15, 2026
2c15091
fix: remove all error suppression from CI
mattleibow Feb 15, 2026
57b15d7
fix: set NO_COLOR=1 for log capture to prevent ANSI in JSON output
mattleibow Feb 15, 2026
b739879
fix: write errors to stderr and output empty JSON array for no logs
mattleibow Feb 15, 2026
8554473
test: add OutputHelper unit tests for JSON/XML output purity
mattleibow Feb 15, 2026
28e88dc
fix: increase simulator boot timeout to 300s for CI reliability
mattleibow Feb 15, 2026
60d2d0a
fix: skip IDB integration tests on Xcode 26+ and increase boot timeout
mattleibow Feb 15, 2026
e9955fd
fix: revert incorrect Xcode 26 skip, increase IDB startup timeout
mattleibow Feb 15, 2026
4c56653
ci: separate IDB integration tests from blocking CI
mattleibow Feb 15, 2026
cfa9bc9
fix: fix missed 120s boot timeout in SimulatorLifecycle test
mattleibow Feb 15, 2026
19d850f
fix: relax Maps log predicate test assertion
mattleibow Feb 15, 2026
69eb077
fix: use SpringBoard predicate for structured log filter test
mattleibow Feb 15, 2026
495e35e
fix: propagate exit code and output JSON error on boot failure
mattleibow Feb 16, 2026
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 5 additions & 39 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CI
name: Build and Publish

on:
pull_request:
Expand All @@ -17,6 +17,8 @@ jobs:
fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
- name: ⚙️ Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x
- name: 📦 Pack
shell: pwsh
run: |
Expand All @@ -33,44 +35,6 @@ jobs:
name: NuGet
path: ./artifacts

test:
if: github.event_name != 'release'
name: 🧪 Test
permissions:
contents: read
checks: write
pull-requests: write
env:
APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }}
APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
APP_STORE_CONNECT_PRIVATE_KEY: ${{ secrets.APP_STORE_CONNECT_PRIVATE_KEY }}
needs: build
runs-on: macos-latest
steps:
- name: 📥 Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
- name: ⚙️ Setup .NET
uses: actions/setup-dotnet@v5
- name: 🍺 Install IDB Companion
run: |
brew tap facebook/fb
brew install idb-companion
- name: 🧪 Run Tests
run: |
dotnet test ./AppleDev.Test/AppleDev.Test.csproj --logger "trx;LogFileName=test-results-appledev.trx" --logger "console;verbosity=detailed" --results-directory ./TestResults
dotnet test ./AppleDev.FbIdb.Test/AppleDev.FbIdb.Test.csproj --logger "trx;LogFileName=test-results-fbidb.trx" --logger "console;verbosity=detailed" --results-directory ./TestResults

- name: 📊 Publish Test Results
uses: dorny/test-reporter@v2
if: always() && github.event_name != 'release'
with:
name: Test Results
path: './TestResults/*.trx'
reporter: dotnet-trx
fail-on-error: true

publish:
name: 🚀 Publish
needs: build
Expand All @@ -83,6 +47,8 @@ jobs:
name: NuGet
- name: ⚙️ Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x
- name: 🚀 Push NuGet
run: |
dotnet nuget push *.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_ORG_API_KEY }}
124 changes: 124 additions & 0 deletions .github/workflows/run.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
name: Run iOS Simulator

on:
pull_request:
push:
branches: [ main ]

jobs:
run:
name: Run
runs-on: macos-latest
steps:
- name: 📥 Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: 🛠️ Setup Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '26.2'
- name: ⚙️ Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x
- name: 📦 Install iOS workload
run: dotnet workload install ios --source https://api.nuget.org/v3/index.json
- name: 🔨 Build the project
run: |
GITHUB_ENV=/dev/null dotnet build AppleDev.Tool/AppleDev.Tool.csproj
echo "TOOL=$PWD/AppleDev.Tool/bin/Debug/net10.0/apple.dll" >> "$GITHUB_ENV"

- name: 📋 List available simulators
run: dotnet $TOOL simulator list

- name: 🆕 Create and boot simulator
run: |
RESULT=$(dotnet $TOOL simulator create "E2ETestSim" --device-type "iPhone 16" --boot --wait --timeout 300 --format json)
echo "Simulator create result: $RESULT"
UDID=$(echo "$RESULT" | jq -r '.udid')
if [ -z "$UDID" ] || [ "$UDID" = "null" ]; then
echo "❌ Failed to parse UDID from simulator create output"
echo "Raw output: $RESULT"
echo "--- Attempting to list simulators for debugging ---"
dotnet $TOOL simulator list
exit 1
fi
echo "✅ UDID: $UDID"
echo "--- Verifying simulator exists and is booted via tool ---"
SIMS=$(dotnet $TOOL simulator list --format json)
if ! echo "$SIMS" | jq -e ".[] | select(.udid == \"$UDID\" and .state == \"Booted\")" > /dev/null 2>&1; then
echo "❌ Simulator $UDID not found as Booted in simulator list"
echo "$SIMS" | jq ".[] | select(.name == \"E2ETestSim\")"
exit 1
fi
echo "✅ Simulator $UDID is Booted"

- name: 📱 Create test iOS app
run: |
dotnet new ios -n TestApp --output TestApp
sed -i.bak 's/return true;/System.Console.WriteLine("TestApp: E2E_APP_STARTED_SUCCESSFULLY"); return true;/' TestApp/AppDelegate.cs
dotnet build TestApp/TestApp.csproj -f net10.0-ios -c Debug -r iossimulator-arm64
echo "--- All .app bundles found ---"
find TestApp -name "TestApp.app" -type d | head -10
APP_PATH=$(find TestApp/bin -name "TestApp.app" -type d | head -1)
if [ -z "$APP_PATH" ]; then
APP_PATH=$(find TestApp -name "TestApp.app" -type d -not -path "*/obj/*" | head -1)
fi
if [ -z "$APP_PATH" ]; then
APP_PATH=$(find TestApp -name "TestApp.app" -type d | head -1)
fi
if [ -z "$APP_PATH" ]; then
echo "❌ Could not find TestApp.app after build"
exit 1
fi
echo "✅ App built: $APP_PATH"

- name: 📦 Install and verify app on simulator
run: |
APP_PATH=$(find TestApp/bin -name "TestApp.app" -type d | head -1)
if [ -z "$APP_PATH" ]; then
APP_PATH=$(find TestApp -name "TestApp.app" -type d -not -path "*/obj/*" | head -1)
fi
if [ -z "$APP_PATH" ]; then
APP_PATH=$(find TestApp -name "TestApp.app" -type d | head -1)
fi
echo "Installing app: $APP_PATH"
dotnet $TOOL simulator app install "E2ETestSim" "$APP_PATH"
echo "--- Verifying app is installed via simulator app list ---"
APPS=$(dotnet $TOOL simulator app list "E2ETestSim" --format json)
if ! echo "$APPS" | jq -e '.[] | select(.CFBundleIdentifier == "com.companyname.TestApp")' > /dev/null 2>&1; then
echo "❌ com.companyname.TestApp not found in simulator app list"
echo "$APPS" | jq '.[].CFBundleIdentifier' | head -10
exit 1
fi
echo "✅ App installed and verified via CLI"

- name: 🚀 Launch and verify test app
run: |
dotnet $TOOL simulator app launch "E2ETestSim" "com.companyname.TestApp"
echo "Waiting for app to run..."
sleep 10
echo "--- Capturing logs ---"
dotnet $TOOL simulator logs "E2ETestSim" --format json > simulator-logs.json
if [ ! -s simulator-logs.json ]; then
echo "❌ No logs captured"
exit 1
fi
echo "--- Log entries ---"
cat simulator-logs.json | jq length
echo "✅ App launched successfully"

- name: 🧹 Cleanup simulator
if: always()
run: dotnet $TOOL simulator delete --force "E2ETestSim"

- name: 📤 Upload logs
if: always()
uses: actions/upload-artifact@v5
with:
name: simulator-logs
path: |
simulator-logs.json
simulator-logs.txt
if-no-files-found: ignore
64 changes: 64 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Tests

on:
pull_request:
push:
branches: [ main ]

permissions:
checks: write
pull-requests: write

jobs:
test:
name: Test
runs-on: macos-latest
env:
APP_STORE_CONNECT_KEY_ID: ${{ secrets.APP_STORE_CONNECT_KEY_ID }}
APP_STORE_CONNECT_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
APP_STORE_CONNECT_PRIVATE_KEY: ${{ secrets.APP_STORE_CONNECT_PRIVATE_KEY }}
steps:
- name: 📥 Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: ⚙️ Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: 10.0.x
- name: 🍺 Install IDB Companion
run: |
brew tap facebook/fb
brew install idb-companion
- name: 🧪 Run Tests
run: |
dotnet test ./AppleDev.Test/AppleDev.Test.csproj --logger "trx;LogFileName=test-results-appledev.trx" --logger "console;verbosity=detailed" --results-directory ./TestResults
dotnet test ./AppleDev.Tool.Tests/AppleDev.Tool.Tests.csproj --logger "trx;LogFileName=test-results-tool.trx" --logger "console;verbosity=detailed" --results-directory ./TestResults

- name: 🧪 Run IDB Integration Tests
if: always()
continue-on-error: true
run: |
dotnet test ./AppleDev.FbIdb.Test/AppleDev.FbIdb.Test.csproj --logger "trx;LogFileName=test-results-fbidb.trx" --logger "console;verbosity=detailed" --results-directory ./TestResults

- name: 📊 Publish Test Results
uses: dorny/test-reporter@v2
if: always()
with:
name: Test Results
path: |
./TestResults/test-results-appledev.trx
./TestResults/test-results-tool.trx
reporter: dotnet-trx
fail-on-error: true
fail-on-empty: false

- name: 📊 Publish IDB Test Results
uses: dorny/test-reporter@v2
if: always()
with:
name: IDB Integration Test Results (Flaky)
path: './TestResults/test-results-fbidb.trx'
reporter: dotnet-trx
fail-on-error: false
fail-on-empty: false
2 changes: 1 addition & 1 deletion AppStoreConnectClient/AppStoreConnectClient.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down
2 changes: 1 addition & 1 deletion AppleDev.FbIdb.Test/AppleDev.FbIdb.Test.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down
4 changes: 2 additions & 2 deletions AppleDev.FbIdb.Test/IdbClientIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public async Task InitializeAsync()
await _simCtl.BootAsync(SimulatorUdid!);

// Wait for it to be fully booted
var booted = await _simCtl.WaitForBootedAsync(SimulatorUdid!, TimeSpan.FromSeconds(120));
var booted = await _simCtl.WaitForBootedAsync(SimulatorUdid!, TimeSpan.FromSeconds(300));
if (!booted)
{
SkipReason = "Simulator failed to boot within timeout";
Expand Down Expand Up @@ -127,7 +127,7 @@ private async Task<IdbClient> CreateConnectedClientAsync()
new IdbCompanionOptions
{
VerboseLogging = true,
StartupTimeout = TimeSpan.FromSeconds(60)
StartupTimeout = TimeSpan.FromSeconds(120)
},
new XUnitLogger<IdbClient>(_testOutputHelper));

Expand Down
2 changes: 1 addition & 1 deletion AppleDev.FbIdb/AppleDev.FbIdb.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
Expand Down
2 changes: 1 addition & 1 deletion AppleDev.Mcp.Server/AppleDev.Mcp.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down
2 changes: 1 addition & 1 deletion AppleDev.Test/AppleDev.Test.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down
Loading
Loading