Skip to content

build: restore the Apple targets, and the app-target tests that never compiled - #1892

Merged
ryanbr merged 3 commits into
mainfrom
fix/strandtests-dailymetric-init
Sep 5, 2026
Merged

ryanbr merged 3 commits into
mainfrom
fix/strandtests-dailymetric-init

Conversation

@ryanbr

@ryanbr ryanbr commented Sep 5, 2026

Copy link
Copy Markdown
Owner

main does not currently compile on iOS or macOS. This restores both, and app-build is green on this branch (run 33952090013) after four rounds of the gate reporting one layer at a time.

What was broken

Fix Introduced by Since
WhoopSerialIdentity.logSafe(serial:) called positionally in FrameRouter #1635 copy change today
DailyMetric(day:sleepHrOnly:) compact inits — the initializer's first twelve parameters are required #1879 earlier
fillingNilFields / takingSleepFields in a private extension, invisible even to @testable pre-existing —
DayCycleRecoveryTests using UserProfile without importing StrandAnalytics #1572 on merge

The logSafe one is the live breakage: Kotlin accepts a positional argument so the Android twin compiled and looked correct, while Swift requires the label and both Apple targets stopped building.

Why none of it was caught

A PR touching only Strand/ and android/ runs no check that compiles Swift. The package matrix needs Packages/; StrandTests runs only in the on-demand app-build, which is disabled by default. So a green tick on such a PR means Android and the Python tools — nothing about the Apple targets.

That is how four independent breakages accumulated unnoticed, one of them from a community PR. It also means a test file can be merged in a state where it has never compiled and stay that way indefinitely, which is what happened to two of the four above.

The fixes

Each is the smallest thing that makes the code reachable, not a rewrite:

  • The label is added at the call site.
  • DailySkinTempAbsoluteCarryTests already had a row(...) helper filling the twelve required parameters; the sleep-carry cases now use it and it carries the fields they need, so none can drift back into a compact call.
  • The private extension becomes internal — still module-confined. It stayed private only because the tests calling it never ran.
  • One missing import.

Verification

  • app-build SUCCESS on both targets — the only check that compiles this code.
  • Android suite unaffected and green; Swift files parse.
  • No behaviour change: an argument label, a test helper, an access level, an import.

Worth doing separately

This will recur. Either make app-build required for Strand/** changes, or add a cheap compile-only job to the default checks. Without one, the next Swift-only PR merges with the same blind spot.

…them

`DailySkinTempAbsoluteCarryTests` has not compiled since #1879. `DailyMetric`'s initializer defaults
only from `spo2Pct` onward — its first twelve parameters are required — and the sleep-carry cases I
added there call compact forms like `DailyMetric(day:sleepHrOnly:)` that do not exist. Swift resolves
those against `takingSleepFields(from:)` instead, which is why the error reads "missing argument for
parameter 'from'" and points nowhere useful.

The file already had a `row(...)` helper filling the required twelve; the new cases simply did not use
it. It now also carries the sleep fields they need, and every case goes through it, so none can drift
back into a compact call.

This shipped to main and stayed there because `StrandTests` runs only in the on-demand app-build,
never in default CI, so a red app target is invisible until someone dispatches it. It surfaced now
only because #1862 needed the Swift compile gate for its own reasons.
`WhoopSerialIdentity.logSafe(serial:)` takes a labelled argument and the call added in #1635's copy
change passed it positionally. Kotlin accepts that, so the Android build stayed green and the twin
looked fine; Swift does not, and both Apple targets have failed to compile since that merge.

It reached main because a PR touching only `Strand/` and `android/` runs no check that compiles
Swift: the package matrix needs `Packages/`, and StrandTests only runs in the on-demand app-build. A
green tick on that PR meant Android and the Python tools, nothing more.
Two more the compile gate surfaced once the first layer cleared.

`DailyMetric.fillingNilFields` and `takingSleepFields` sit in a `private extension`, which even
`@testable import` cannot see, so the cases exercising them could never have compiled. Widened to
internal, still module-confined. They stayed private because nothing demanded otherwise: the tests
calling them have never run.

`DayCycleRecoveryTests` referenced `UserProfile` without importing StrandAnalytics, which arrived with
the day-cycle work in #1572 and has been red since.

Both are the same story as the rest of this branch. StrandTests runs only in the on-demand app-build,
so a test file can be merged in a state where it does not compile and stay that way indefinitely.
@ryanbr
ryanbr merged commit 0ae341f into main Sep 5, 2026
5 checks passed
@ryanbr
ryanbr deleted the fix/strandtests-dailymetric-init branch September 5, 2026 07:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant