From d20ea5fd311cf8d8facb2d25821e4c9a4277d2ff Mon Sep 17 00:00:00 2001 From: Kieran Osgood Date: Wed, 12 Aug 2026 17:51:24 +0100 Subject: [PATCH] Drop the duplicate Swift compile in build_and_test_samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Part of the macOS CI speed-up. Tracked on shop/issues-checkout-kit#1203, under shop/issues-checkout-kit#1202. ## Problem `build_and_test_samples` builds two apps out of one `Samples.xcworkspace`. Both resolve the root Swift package and Apollo iOS 2.0.6. The second `run_app` passed `clean`, which deletes the shared build products the first `run_app` just produced, inside a single CI step. ## Change `platforms/swift/Scripts/build_and_test_samples:31` drops `clean` from the second app. Line 30 is untouched, so this PR moves exactly one variable and the measurement stays attributable. ## Why this one is not a cache enabler The script has two `clean` calls, and they cost different things. Only the second one wastes time on CI today: | Line | App | Cost on a fresh runner | Removed by | | --- | --- | --- | --- | | 30 | `CheckoutKitSwiftDemo` | None. Nothing exists yet to clean. | #637, with the cache | | 31 | `ShopifyAcceleratedCheckoutsApp` | A full recompile of the shared products line 30's app just built. | this PR | `xcode_run` passes neither `-derivedDataPath` nor `-workspace`. Both `run_app` calls therefore run from `platforms/swift/Samples` against one workspace and one default DerivedData. The Swift package and Apollo iOS 2.0.6 sit in both schemes' dependency graphs, so cleaning the second scheme deletes products the first scheme produced seconds earlier, in the same step. Line 30 is the enabler-only one: it deletes nothing today and only starts to matter once a restored cache is there to delete. That is why it is folded into the DerivedData PR rather than this one, as agreed. ## Baseline to beat Last 30 successful `main` runs of `ci.yml`, measured with a local `gh api` script. | Job | n | median | p90 | min | max | | --- | --- | --- | --- | --- | --- | | `Swift / build-and-test-samples` | 11 | 6m38s | 8m10s | 5m06s | 9m57s | | ↳ step `Run Tests` | 11 | 6m04s | — | — | — | `Run Tests` is 91% of the job. **How the gate works.** A step time only exists on `main`, so this merges first and is measured after. Re-measure the same step over 10 `main` runs, then append the delta to shop/issues-checkout-kit#1202. If the delta does not appear, revert this PR and stop the stack there — the later phases assume this premise holds. ## Verification - `shadowenv exec -- ./scripts/test_ruby` — green. - Cold run of the script itself. `dev swift test sample` runs `test_samples`, which never calls `build_and_test_samples`, so it does not cover this change. 🟡 The saving is read off the script, not timed locally. The mechanism is not in doubt, but the size of it is. If you want a number before merging rather than after, say so and I will time the second `run_app` with and without `clean` from the same warm state. ## Open question for the author `platforms/swift/Scripts/build_samples:24` carries the identical `clean build` double-compile, on both apps. It is deliberately untouched here and nowhere else in this stack: it is reachable only from `dev.yml:377,384`, so it costs no CI time, and changing it would add a second variable to the measurement. Say the word and it becomes a one-line follow-up, so the local path matches CI. --- platforms/swift/Scripts/build_and_test_samples | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platforms/swift/Scripts/build_and_test_samples b/platforms/swift/Scripts/build_and_test_samples index e2d29fcb4..f3c59611b 100755 --- a/platforms/swift/Scripts/build_and_test_samples +++ b/platforms/swift/Scripts/build_and_test_samples @@ -28,4 +28,4 @@ run_app() { } run_app CheckoutKitSwiftDemo "clean build test" -run_app ShopifyAcceleratedCheckoutsApp "clean build" +run_app ShopifyAcceleratedCheckoutsApp "build"