ci(ios): build the core once per run instead of once per job - #766
Merged
Merged
Conversation
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.
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.
|
CI Status: 17 required jobs green, 13 passed and 4 skipped by path filter. All job results
Commit |
Imod7
approved these changes
Sep 14, 2026
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.
filvecchiato
approved these changes
Sep 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The iOS checks took 30m54s. They now take 18m41s wall clock, measured rather
than predicted.
corebuildmacos-26macos-26-xlargetestpreviewbuildis the striking one, 30m54s to 9m19s, because it lost both problems atonce: 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
corejob now does it once and carriesthe result as an artifact, packaged with tar so the xcframework keeps its layout
and executable bits, which
upload-artifactdoes not preserve.Each path is checked before packaging. A bootstrap that stops producing one
fails in
corewith the path named, rather than in three app jobs at packageresolution, which is a much harder error to read.
The provider has no
Binariesin that set on purpose.ios-bootstraprunsprovider-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_BINARYis set. The first run of this branch foundthat by failing on it.
Move the heaviest job to the larger runner
buildarchives 2,533 Swift files for a device. It was on three cpus whiletestfinished eleven minutes earlier on five.What is now the long pole
testat 12m05s, so the critical path iscoreplustest. Further workbelongs on #763: the SPM cache has never hit, which is worth understanding
before anything else.
Part of #763.