Skip to content

ci(macos): run the darwin-only Vitest files on a lane that reaches them - #2944

Merged
thymikee merged 2 commits into
mainfrom
test/darwin-only-tests-actually-run
Sep 25, 2026
Merged

thymikee merged 2 commits into
mainfrom
test/darwin-only-tests-actually-run

Conversation

@thymikee

Copy link
Copy Markdown
Member

Summary

.github/workflows/macos.yml:168 is the only Vitest invocation in the repo that runs on macOS,
and it was a hand-written two-file list. Meanwhile the only job that collects
packages/*/src/**/*.test.ts is the unit-ci gate on ubuntu-latest (ci.yml:286). Anything
guarded on process.platform === 'darwin' therefore had no lane that could execute it — the file was
collected and skipped, forever. Six tests across two files were dying this way.

File What it was the only guard for
packages/platform-apple/src/foldable/simulator-hid-native.test.ts (whole file, describe.skipIf(!darwin)) the samples column of contracts/fixtures/fold-keyframes.json, checked against the ObjC interpolation in apple/fold-helper/Fold.m. Its TypeScript twin device-rotation-fold-input.test.ts reads only valid and keyframesJson
packages/capture-kit/src/recording/__tests__/recording-scripts.test.ts (t.skip ×3) swiftc -typecheck over apple/runner/AgentDeviceRunner/RecordingScripts

The samples column was genuinely unguarded on every lane — measured. Nudging one
samples[2].angle from 160 to 163:

  • simulator-hid-native.test.ts → 1 failed, AssertionError: opening reversal at 1667ms
  • device-rotation-fold-input.test.ts (what Linux CI actually runs) → 14 passed

So a corrupted golden sample could merge green today and the native keyframe rule would never notice.
Fixture reverted before committing.

Why these join the existing step instead of a new one

I expected to add an unconditional step. I didn't, because selectAppleBridgeProof
(scripts/apple-ci-impact.ts:43) already fires on any change under apple/ or
packages/platform-apple/src/ — which is precisely the input set of both tests (the .m, the Swift
scripts). They run when their subject moved and cost nothing when it did not, with no new macOS
minutes on unrelated PRs. The step is renamed to say what it now covers.

Validation

Tested at 325dd4d29.

  • All four files in the step, in one invocation, on this darwin host → 4 files / 58 tests passed
  • The mutant run above, then reverted; git status showed only macos.yml
  • .github/workflows/macos.yml parsed with a YAML parser to confirm the step, its if:, and all four
    continuation lines survived the edit
  • pnpm check:affected --run → exit 0; oxlint . --deny-warnings → exit 0

One gap left open deliberately: editing the recording-scripts test file alone does not trigger
the step, because packages/capture-kit/ is outside the classifier's two prefixes. Widening
selectAppleBridgeProof is affected-check-model territory with its own tests — a workflow change is
the wrong place to do it, so it is flagged here instead of folded in.

@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
Installed (including dependencies) 4.82 MB 4.81 MB -1.1 kB
Package (unpacked) 4.81 MB 4.81 MB -1.1 kB
Package (download) 1.44 MB 1.44 MB -155 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 23.0 ms 23.2 ms +0.2 ms
CLI --help 66.0 ms 63.8 ms -2.2 ms

@thymikee

Copy link
Copy Markdown
Member Author

Reviewed at 325dd4d. This isn't green yet, and both failures trace to this diff.

scripts/tests/apple-ci-impact.test.ts:63 pins the literal step-name substring - name: Verify clean-installed Simulator snapshot bridge preparation and checks it appears after replay. The step was renamed in .github/workflows/macos.yml to Verify the darwin-only native source proofs (...), so indexOf now returns -1 and the assertion fails with "expected -1 to be greater than 6134" — this is exactly the Coverage job's failure. Please update the pinned substring (or match on a stable prefix instead of the full title) in the same PR: https://github.com/callstack/agent-device/blob/325dd4d/scripts/__tests__/apple-ci-impact.test.ts#L63

.github/workflows/macos.yml:168 newly routes recording-scripts.test.ts onto a Vitest lane, and its swiftc typecheck now actually runs instead of being skipped everywhere. Its siblings in the same step move the real compiler call into beforeAll to keep it out of per-test wall time (see fold-helper-cache.test.ts:164-166 and native-runtime.test.ts:102-104), but recording-scripts.test.ts calls assertSwiftScriptTypechecks inside the test() body. The slow-test reporter enforces a 2.5s budget for packages/** and hard-fails at 2x; this case took 7.97s, which aborts the step before pnpm check:package runs and is why Smoke Tests fails. Can you move the swiftc compiles into beforeAll the same way the sibling files already do, so the per-test timer only measures the assertion? https://github.com/callstack/agent-device/blob/325dd4d/.github/workflows/macos.yml#L168

Coverage and one Smoke Tests job fail on the exact macos.yml Vitest step this PR touches. The ios.yml Smoke Tests failure is a keyboard text-entry mismatch with no reference to the changed step in its log, so it looks like a pre-existing flake rather than something this PR caused, though I haven't checked recent main runs to confirm that. The workflow edit correctly forces the darwin-only lane to run in full under the impact test's uncertain-ownership rule, so that part is expected, not a defect.

Once the step-name pin is fixed and the swiftc calls move to beforeAll, please re-run the macOS lane and confirm the macos.yml Smoke Tests job goes green with pnpm check:package's snapshot-bridge-preparation step completing — that's the route this diff actually changes, so it needs to be observed passing, not just reasoned about.

`.github/workflows/macos.yml:168` is the only Vitest invocation in the repository that
runs on macOS. It was a hand-written two-file list, so a test guarded on
`process.platform === 'darwin'` had no lane that could execute it: the sole job that
collects `packages/*/src/**/*.test.ts` is the `unit-ci` gate on `ubuntu-latest`, where
the whole file skips.

Two files were dying that way, six tests between them:

- `packages/platform-apple/src/foldable/simulator-hid-native.test.ts` — the only consumer
  of the `samples` column of `contracts/fixtures/fold-keyframes.json`. The ObjC
  interpolation in `apple/fold-helper/Fold.m` is the thing those samples check, and the
  TypeScript twin (`device-rotation-fold-input.test.ts`) reads only `valid` and
  `keyframesJson`. Proven: nudging one `angle` from 160 to 163 reddens this file
  ("opening reversal at 1667ms") while the TS legs that Linux CI actually runs report
  14 passed. The column was unguarded on every lane.
- `packages/capture-kit/src/recording/__tests__/recording-scripts.test.ts` — `swiftc
  -typecheck` over `apple/runner/AgentDeviceRunner/RecordingScripts`.

Both join the existing conditional step rather than a new unconditional one, because
`selectAppleBridgeProof` (`scripts/apple-ci-impact.ts:43`) already fires on any change
under `apple/` or `packages/platform-apple/src/` — which is exactly the input set of both
tests — so they run when their subject moved and cost nothing when it did not. The step is
renamed to say what it now covers. All four files pass together here: 58 tests.

One gap left on purpose: editing the recording-scripts test file alone does not trigger the
step, since `packages/capture-kit/` is outside the classifier's prefixes. Widening
`selectAppleBridgeProof` is affected-check model territory with its own tests, not a
workflow edit; noted rather than folded in.
…st wall time

Both failures on this PR traced to my own diff.

`scripts/__tests__/apple-ci-impact.test.ts` pinned the literal step title
`- name: Verify clean-installed Simulator snapshot bridge preparation`, which I renamed, so
`indexOf` returned -1 and the Coverage job died on "expected -1 to be greater than 6134".
Patching the string would just re-pin the same prose, so the assertion moved to what the
steps actually run: the replay step is found by `with.gate === 'replay-macos'`, the
clean-install proof by the `--verify-snapshot-bridge-preparation` flag it passes (unique in
the file, and named by `scripts/check-package.ts:42`). The lookup walks jobs in file order
through the `yaml` parser this test already imports, so a reindented `run:` block or a
multi-line `with:` no longer reads as a sequencing change. Proven non-vacuous: retagging the
replay step so the proof no longer follows it fails with "expected -1 to be greater than -1".

`recording-scripts.test.ts` called `assertSwiftScriptTypechecks` from inside `test()`, so the
7.97s `swiftc` launch landed on the per-case clock, blew through 2x the `packages/**` budget,
and aborted the step before `pnpm check:package` ran. The three compiles now run in one
`beforeAll`, following the note at `fold-helper-cache.test.ts:164` — one SDK probe, both
shared-source compiles paid once instead of per case. The cases drop to 1ms/0ms/0ms while the
`describe.skipIf` keeps them darwin-only, which also removes the per-test `t.skip` branches.

Detection is unchanged and was checked three ways against real sources: a type error in
`recording-inspect.swift` fails the inspect case alone; one in `recording-overlay.swift` fails
the overlay case alone; one in the shared `RecordingExportSupport.swift` fails exactly the two
cases that compile it. All fixtures reverted.
@thymikee
thymikee force-pushed the test/darwin-only-tests-actually-run branch from 325dd4d to 115021a Compare September 25, 2026 06:00
@thymikee

Copy link
Copy Markdown
Member Author

Both findings were correct and both traced to my diff. Fixed in 115021a4f, rebased onto 56e8e70a1.

1. The step-name pin. Rather than re-pin the renamed prose, the assertion now locates both steps
by what they run: the replay by with.gate === 'replay-macos', the clean-install proof by the
--verify-snapshot-bridge-preparation flag it passes (unique in the file, and named by
scripts/check-package.ts:42). Steps are resolved through the yaml parser the test already imports,
walking jobs in file order, so a reindented run: block can't read as a sequencing change either.
Non-vacuity checked: retagging the replay step so the proof no longer follows it fails with
expected -1 to be greater than -1.

2. swiftc on the per-case clock. The three -typecheck invocations moved into one beforeAll,
following the note at fold-helper-cache.test.ts:164. One SDK probe and both shared-source compiles
are now paid once per file instead of once per case; the cases went 7.97s → 1ms/0ms/0ms.
describe.skipIf keeps them darwin-only, which also removed the three per-test t.skip branches.
Detection verified against real sources three ways — a type error in recording-inspect.swift fails
the inspect case alone, one in recording-overlay.swift fails the overlay case alone, and one in the
shared RecordingExportSupport.swift fails exactly the two cases that compile it. Fixtures reverted.

macOS lane observed green, job 107963122067
(Smoke Tests, completed/success). The renamed step ran all four files:

✓ unit-core packages/platform-apple/src/foldable/fold-helper-cache.test.ts (5 tests)
✓ unit-core packages/platform-apple/src/snapshot-source/native-runtime.test.ts (47 tests)
✓ unit-core packages/platform-apple/src/foldable/simulator-hid-native.test.ts (1 test)
✓ unit-core packages/capture-kit/src/recording/__tests__/recording-scripts.test.ts (5 tests)
Test Files  4 passed (4)
     Tests  58 passed (58)

No slow-test gate output, and the step continued into the part that previously never got to run:

$ node --experimental-strip-types scripts/check-package.ts -- --verify-snapshot-bridge-preparation
Prepared the Simulator snapshot bridge from the clean-installed package.

58 passed is the same count I measured locally across those four files, so nothing was silently
skipped on the runner.

On the ios.yml failure — your read that it was not mine looks right, and I found a second
instance: run 36042822212 failed the same Smoke Tests job on
test/remove-test-only-command-catalog-export, a branch that touched only src/commands/index.ts
and two test files, and which has since merged. The two failures are not identical though, so they
may be one flaky lane rather than one bug: mine was
TEXT_ENTRY_MISMATCH — expected "ada@example.test", observed "ada@example" in
smoke-ios-simulator.test.ts:7 (step: append email suffix from coordinate focus), while the #2934
one surfaced as a runner capture/provisioning hint. Neither log mentions the macos.yml step. I did
not chase further — flagging it as worth its own look since it hit two unrelated branches inside an
hour, and #2936 ("retain bridge circuit diagnostics in smoke") landing the same day suggests
someone is already in that area.

@thymikee

Copy link
Copy Markdown
Member Author

Reviewed at 115021a. This is ready for human review.

Both issues from the earlier pass (325dd4d, #2944 (comment)) are fixed at the root: the darwin-only Vitest files now run on a lane that reaches them, and the mechanism holds up under static review — beforeAll exclusion from the slow-test reporter's per-test-case measurement, and YAML-field-based step lookup. CI reports 19 checks, all passing, and the two that map to this change (macOS Smoke Tests, recording-scripts.test.ts, apple-ci-impact.test.ts) are green. I did not re-run the macOS job myself; this reads on the reported results plus the static check of the mechanism.

Not blocking: could the recording-scripts typecheck proof's inputs (test/integration/support/recording-inspect.swift and packages/capture-kit/src/recording/__tests__/) be added to selectAppleBridgeProof in scripts/apple-ci-impact.ts, since running the selector on either path alone returns run:false today — worth a follow-up scripts/__tests__/apple-ci-impact.test.ts case, but it can be taken or left.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Sep 25, 2026
@thymikee
thymikee merged commit 769ee23 into main Sep 25, 2026
19 checks passed
@thymikee
thymikee deleted the test/darwin-only-tests-actually-run branch September 25, 2026 06:48
@github-actions

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-09-25 06:48 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant