mirror of
https://github.com/callstack/agent-device.git
synced 2026-09-14 20:06:34 +08:00
02d548dfc9
* ci: consolidate CI workflow from 15 jobs to 8 Merge single-gate ubuntu jobs into grouped jobs sharing one checkout and install: Lint & Format (plus the static text assertions), Repo Guards (layering/selector/wiring/maestro/mcp-metadata), Compatibility & Provenance (shared fetch-depth: 0 checkout), Typecheck & Package, and Integration Tests (absorbs the web smoke with step-scoped env). Every gate remains an independently named run-gate step; the gate manifest derives lane ownership structurally. Drop the Bun setup from FreeRange: @chenglou/freerange's bin is a plain Node script. It stays GitHub-owned; only the runtime requirement is retired. * ci: fold FreeRange into Repo Guards and skip no-op fixture release jobs FreeRange runs on plain Node now, so its gate joins Repo Guards as the last step instead of occupying its own worker for the slowest guard. The fixture release matrix filters to entries that will actually build, so a cached-fingerprint PR starts zero release runners. * ci: fold host XCTests into the macOS smoke lane and shard Coverage The macOS lane now builds one unit-test-flagged runner bundle that both the host XCTest run and the replay smoke consume, so the host lane no longer occupies its own macos-26 runner behind a separate queue. The host lane's file moves with it, and check:xctest-selection follows. Coverage shards across two runners via blob reports and merges them on a report job that evaluates thresholds once over the full suite and produces every coverage artifact. The tmpdir leak check runs per shard, since a leak lands on whichever runner executed the file. * ci: drop local shard-smoke artifacts from tracking * ci: enforce coverage thresholds only on the merged run A shard evaluates its own half-suite coverage, so the global gate fired per shard. Shards now report without gating; Coverage Report keeps the real thresholds over the full merged suite. * ci: include hidden files when uploading coverage blobs
149 lines
5.8 KiB
YAML
149 lines
5.8 KiB
YAML
name: macOS
|
|
|
|
on:
|
|
pull_request:
|
|
paths-ignore:
|
|
- 'docs/**'
|
|
- 'website/**'
|
|
- 'README.md'
|
|
- 'AGENTS.md'
|
|
- 'CHANGELOG.md'
|
|
- 'CONTEXT.md'
|
|
- 'CONTRIBUTING.md'
|
|
- 'LICENSE'
|
|
- 'SECURITY.md'
|
|
- '.github/actions/build-docs/action.yml'
|
|
- '.github/workflows/deploy.yml'
|
|
- '.github/workflows/pr-preview.yml'
|
|
- '.github/workflows/pr-preview-cleanup.yml'
|
|
push:
|
|
branches:
|
|
- main
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
# One macOS lane for everything the macOS host can prove: command coverage,
|
|
# the runner's pure-decision XCTests, the helper, and the replay smoke. All
|
|
# of it consumes one runner build, compiled with the unit-test flag so the
|
|
# host XCTest run below has a bundle to execute (#1781 A7).
|
|
#
|
|
# Which tests that build reaches is not a list: it is everything the macOS
|
|
# build compiles, and the simulator-only tests keep themselves out with an
|
|
# `os(iOS)` guard (see the classification note in RunnerTests.swift). The
|
|
# `-skip-testing:` entry is validated by `pnpm check:xctest-selection` for
|
|
# the same reason the nightly's is: `RunnerTests/testCommand` is the
|
|
# runner's 24-hour server entry point, and a typo re-arms the hang. The
|
|
# lane's reporter asserts the executed count equals the reach the check
|
|
# derives from source, so a build without the compile flag or a guard that
|
|
# compiles a file out reads as red rather than as a smaller green.
|
|
#
|
|
# Kill criterion: if the host run proves flaky where the simulator run of the
|
|
# same tests is not (a platform-branch difference this classification
|
|
# missed), gate the offender `os(iOS)` and it returns to the simulator lanes;
|
|
# if that happens to more than a handful, the host lane is the wrong tool and
|
|
# goes.
|
|
smoke-macos:
|
|
name: Smoke Tests
|
|
runs-on: macos-26
|
|
timeout-minutes: 80
|
|
env:
|
|
AGENT_DEVICE_STATE_DIR: ${{ github.workspace }}/.tmp/agent-device-state
|
|
AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH: ${{ github.workspace }}/.tmp/macos-runner-derived
|
|
AGENT_DEVICE_XCUITEST_INCLUDE_UNIT_TESTS: '1'
|
|
RESULT_BUNDLE_PATH: ${{ github.workspace }}/.tmp/xctest-host/RunnerTests.xcresult
|
|
RESULT_SUMMARY_PATH: ${{ github.workspace }}/.tmp/xctest-host/test-results-summary.json
|
|
XCTEST_LANE: host
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
|
|
- name: Setup toolchain
|
|
uses: ./.github/actions/setup-node-pnpm
|
|
|
|
- name: Run macOS command coverage contract
|
|
uses: ./.github/actions/run-gate
|
|
with: { gate: macos-coverage }
|
|
|
|
- name: Restore and build macOS XCTest runner
|
|
uses: ./.github/actions/setup-apple-runner-build
|
|
with:
|
|
derived-path: ${{ env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH }}
|
|
cache-key-prefix: macos-runner-prebuilt
|
|
gate: swift-runner-macos
|
|
xcuitest-platform: macos
|
|
xcuitest-destination: platform=macOS,arch=arm64
|
|
|
|
- name: Run the host-runnable runner XCTests
|
|
run: |
|
|
set -euo pipefail
|
|
XCTESTRUN_PATH="$(find "$AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH/Build/Products" -maxdepth 1 -name '*.xctestrun' -print -quit)"
|
|
test -n "$XCTESTRUN_PATH"
|
|
mkdir -p "$(dirname "$RESULT_BUNDLE_PATH")"
|
|
xcodebuild test-without-building \
|
|
-xctestrun "$XCTESTRUN_PATH" \
|
|
-destination 'platform=macOS,arch=arm64' \
|
|
-skip-testing:AgentDeviceRunnerUITests/RunnerTests/testCommand \
|
|
-resultBundlePath "$RESULT_BUNDLE_PATH"
|
|
|
|
# Same shape as xctest-nightly.yml: extract is best-effort, the report step asserts.
|
|
- name: Extract the test-results summary
|
|
if: always()
|
|
run: |
|
|
set -uo pipefail
|
|
[ -d "$RESULT_BUNDLE_PATH" ] || exit 0
|
|
xcrun xcresulttool get test-results summary --path "$RESULT_BUNDLE_PATH" --compact \
|
|
> "$RESULT_SUMMARY_PATH" 2>/dev/null ||
|
|
xcrun xcresulttool get test-results summary --path "$RESULT_BUNDLE_PATH" \
|
|
> "$RESULT_SUMMARY_PATH" 2>/dev/null ||
|
|
rm -f "$RESULT_SUMMARY_PATH"
|
|
exit 0
|
|
|
|
- name: Report the run and assert it executed the source-derived set
|
|
if: always()
|
|
run: |
|
|
set -euo pipefail
|
|
if [ ! -s "$RESULT_SUMMARY_PATH" ]; then
|
|
echo 'No usable test-results summary was produced, so nothing here can show a test ran.'
|
|
echo 'The suite step above failed before or during the run; read its log first.'
|
|
echo '### iOS runner host XCTest lane' >> "$GITHUB_STEP_SUMMARY"
|
|
echo 'No result-bundle summary; see the run log and the uploaded bundle.' >> "$GITHUB_STEP_SUMMARY"
|
|
exit 1
|
|
fi
|
|
node --experimental-strip-types scripts/xctest-run-summary.ts
|
|
|
|
- name: Upload result bundle
|
|
if: always()
|
|
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
with:
|
|
name: xctest-host-results-${{ github.run_id }}-${{ github.run_attempt }}
|
|
path: .tmp/xctest-host
|
|
if-no-files-found: warn
|
|
|
|
- name: Build macOS helper
|
|
uses: ./.github/actions/run-gate
|
|
with: { gate: macos-helper }
|
|
|
|
- name: Run macOS integration test
|
|
uses: ./.github/actions/run-gate
|
|
with:
|
|
gate: replay-macos
|
|
args: |
|
|
--retries
|
|
2
|
|
--report-junit
|
|
test/artifacts/replays-macos.junit.xml
|
|
|
|
- name: Upload macOS artifacts
|
|
if: always()
|
|
uses: ./.github/actions/upload-agent-device-artifacts
|
|
with:
|
|
artifact-name: macos-artifacts
|
|
agent-state-dir: ${{ env.AGENT_DEVICE_STATE_DIR }}
|
|
runner-derived-path: ${{ env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH }}
|