Skip to content

ci(ios): build the core once per run instead of once per job - #766

Merged
TarikGul merged 3 commits into
mainfrom
tg/ios-shared-core
Sep 14, 2026
Merged

TarikGul merged 3 commits into
mainfrom
tg/ios-shared-core

Conversation

@TarikGul

@TarikGul TarikGul commented Sep 14, 2026

Copy link
Copy Markdown
Member

The iOS checks took 30m54s. They now take 18m41s wall clock, measured rather
than predicted.

job before after
core did not exist 6m19s
build 30m54s on macos-26 9m19s on macos-26-xlarge
test 19m21s 12m05s
preview would have been a third copy 9m21s
wall clock 30m54s 18m41s

build is the striking one, 30m54s to 9m19s, because it lost both problems at
once: it was generating the core itself for 11m13s, and doing it on three cpus.

Build the core once

Every app job generated the same core. A core job now does it once and carries
the result as an artifact, packaged with tar so the xcframework keeps its layout
and executable bits, which upload-artifact does not preserve.

Each path is checked before packaging. A bootstrap that stops producing one
fails in core with the path named, rather than in three app jobs at package
resolution, which is a much harder error to read.

The provider has no Binaries in that set on purpose. ios-bootstrap runs
provider-swift, which generates its Swift bindings but not its xcframework,
and the root manifest resolves that binary from the published release unless
TRUAPI_PROVIDER_USE_LOCAL_BINARY is set. The first run of this branch found
that by failing on it.

Move the heaviest job to the larger runner

build archives 2,533 Swift files for a device. It was on three cpus while
test finished eleven minutes earlier on five.

What is now the long pole

test at 12m05s, so the critical path is core plus test. Further work
belongs on #763: the SPM cache has never hit, which is worth understanding
before anything else.

Part of #763.

Measured on a green run, the checks took 30m54s, and a third of that was the
same work done three times. Every app job generated the core itself: 11m13s in
build, 5m44s in test, and a third copy once preview landed.

A core job now builds it once and carries it to the app jobs as an artifact,
through tar so the xcframework keeps its layout and executable bits. The output
is deterministic for a commit, so there is nothing to gain from repeating it.

The build job also moves to the larger runner. It was doing the heaviest work,
archiving 2,533 Swift files for a device, on three cpus, while test finished
eleven minutes earlier on five. The same bootstrap step took 11m13s on macos-26
and 5m44s on macos-26-xlarge, so this is roughly half the speed for the job that
needs it most.

The preview job no longer asks for a simulator-only core. It shares the one the
build job needs, which carries both slices.
@github-actions github-actions Bot added the github_actions Pull requests that update GitHub Actions code label Sep 14, 2026
The first run failed packaging on ios/truapi-provider/Binaries, which does not
exist. ios-bootstrap runs provider-swift, generating the provider's Swift
bindings but not its xcframework, and the root manifest resolves that binary
from the published release unless TRUAPI_PROVIDER_USE_LOCAL_BINARY is set.

Each remaining path is now checked before packaging, so a bootstrap that stops
producing one fails here with the path named, rather than in three app jobs at
package resolution.
@github-actions

github-actions Bot commented Sep 14, 2026

Copy link
Copy Markdown

CI Status: 17 required jobs green, 13 passed and 4 skipped by path filter.

All job results
job result
android-bindings skipped
changes success
changeset-guard skipped
codegen success
e2e skipped
explorer success
ios-bindings success
ios-swift skipped
licenses success
playground success
release-guard success
rust success
ts-client success
ts-debugger success
ts-host success
wasm-provider success
workflow-lint success

Commit 345ba314 · run log

Comment thread .github/workflows/ios-pr.yml
Comment thread .github/workflows/ios-pr.yml Outdated
Comment thread .github/workflows/ios-pr.yml
Three things from review.

The core artifact is named after the run id, which is stable across attempts, so
a rerun uploaded a name that already existed and failed. It now overwrites.
Adding the attempt to the name instead would break "re-run failed jobs", which
does not rerun core, leaving the app jobs looking for a name never uploaded.

The download moves to the pin the rest of the repository uses, which validates
the digest. A truncated tarball now fails at the download rather than as a gzip
error inside tar, several steps later.

Every job in the file now has a budget. The app jobs get thirty against a
measured nine to twelve minutes; core keeps forty five because it is the one
still compiling Rust, where a cold cache legitimately runs long.
@TarikGul
TarikGul added this pull request to the merge queue Sep 14, 2026
Merged via the queue into main with commit 13aa9e4 Sep 14, 2026
28 checks passed
@TarikGul
TarikGul deleted the tg/ios-shared-core branch September 14, 2026 18:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

github_actions Pull requests that update GitHub Actions code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants