stim 1.19.0 → 1.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -3
- package/dist/{activity-BSw0x84R.mjs → activity-BaMpUQ4-.mjs} +3 -3
- package/dist/{agent-device-usage-output-Bjxu_VmX.mjs → agent-device-usage-output-VPaOgGaF.mjs} +7 -7
- package/dist/android-CLbBJ2ve.mjs +1258 -0
- package/dist/{android-DE5g_5gv.mjs → android-CZh6ElG5.mjs} +2 -2
- package/dist/{android-BdQC6zs1.mjs → android-DE8-JfGW.mjs} +105 -47
- package/dist/{android-cas-C87geAg-.mjs → android-cas-BFpS84v2.mjs} +9 -5
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/android-eXfIjKJr.mjs +6 -0
- package/dist/api-run.mjs +159 -8
- package/dist/{api-DIf_s86s.mjs → api-zuX3ynYN.mjs} +5 -1
- package/dist/api.d.mts +98 -4
- package/dist/api.mjs +1 -1
- package/dist/{app-install-CFI4ptUL.mjs → app-install-Cg9YJy3x.mjs} +9 -8
- package/dist/artifact-Ctb2jpw6.mjs +807 -0
- package/dist/artifact-DXk_Fle_.mjs +772 -0
- package/dist/artifact-lifecycle-DzPpBYvK.mjs +30 -0
- package/dist/{browser-web-CDhqQxhv.mjs → browser-web-xQWC2RWl.mjs} +19 -19
- package/dist/{budget-Dz-kyXLv.mjs → budget-RFbwFpG5.mjs} +3101 -3062
- package/dist/build-COBA1tBc.mjs +462 -0
- package/dist/{build-facts-B87vo-Im.d.mts → build-facts-DcLv2HSd.d.mts} +1 -32
- package/dist/build-plan-CRjAA6Qi.mjs +553 -0
- package/dist/{cache-manifest-DiwKSyv9.mjs → cache-manifest-qA3dT2x2.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{manifest-CX0d1IkZ.mjs → ccache-CtbqWxIC.mjs} +13 -19
- package/dist/{chrome-BTUOo8p2.mjs → chrome-Dp2lMLBe.mjs} +1 -1
- package/dist/{cli-C9Zvgbdc.mjs → cli-sGqlPu1n.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/{client-CuUo8Nvg.mjs → client-zqjFd79D.mjs} +89 -307
- package/dist/collector-run.d.mts +4 -0
- package/dist/collector-run.mjs +7 -7
- package/dist/{command-output-Bt8ygHE7.mjs → command-output-CPDq_90S.mjs} +2 -2
- package/dist/{config-DC5jEtd1.mjs → config-D0LhTY3S.mjs} +8 -12
- package/dist/{created-devices-D0s26Hx5.mjs → created-devices-CXBMtoj5.mjs} +7 -6
- package/dist/{dependency-state-DKaS1OM9.mjs → dependency-state-B2m8eqsS.mjs} +2 -2
- package/dist/{detached-entry-pB_IPfV4.mjs → detached-entry-BXq4fIl-.mjs} +1 -1
- package/dist/{dev-client-CDY_zAmD.mjs → dev-client-BqYjMIaC.mjs} +2 -2
- package/dist/{device-BHw0WlHl.mjs → device-BgNj-qVj.mjs} +8 -8
- package/dist/device-D4DqjSZZ.mjs +727 -0
- package/dist/{device-capacity-BoN1jQkO.mjs → device-capacity-DrwHwR97.mjs} +13 -14
- package/dist/device-host-worker.mjs +38 -18
- package/dist/device-ios-DE8KJd3b.mjs +413 -0
- package/dist/{device-lease-Cu7PtQpZ.mjs → device-lease-C309csaB.mjs} +138 -24
- package/dist/{device-lease-run-D38SnZtt.mjs → device-lease-run-Baelt3nc.mjs} +4 -4
- package/dist/{device-pool-CP4rAsHx.mjs → device-pool-DtK9S6AD.mjs} +3 -3
- package/dist/{device-remote-B5GiUifk.mjs → device-remote-DjsNw8DD.mjs} +17 -68
- package/dist/doctor-DiP9HsIP.mjs +515 -0
- package/dist/{doctor-PRJH94v6.mjs → doctor-Dunu3Nv1.mjs} +333 -744
- package/dist/{doctor-watchman-wZhyTdp4.mjs → doctor-watchman-XJzT8tK-.mjs} +15 -13
- package/dist/{simslim-D9LkJxIO.mjs → eas-build-0gadvrca.mjs} +6 -152
- package/dist/{stim-installations-DbmUjsLv.mjs → eas-session-ledger-DJDeL4Uq.mjs} +57 -4
- package/dist/{error-diagnostics--v5HGOU0.mjs → error-diagnostics-BhQtoLrZ.mjs} +17 -12
- package/dist/errors-DzkMYh8Q.mjs +205 -0
- package/dist/{exec-i8GDPwq9.mjs → exec-B81Qodjn.mjs} +40 -10
- package/dist/{gc-CyHMcKcn.mjs → gc-D5cz5G0k.mjs} +22 -21
- package/dist/{device-ios-B2ruohE-.mjs → gradle-CZZo1TSA.mjs} +21 -650
- package/dist/{guide-dRaQJJk9.mjs → guide-DakjcoUt.mjs} +503 -251
- package/dist/{hosted-android-Bs7fytj7.mjs → hosted-android-C-D8Dj0_.mjs} +5 -5
- package/dist/{hosted-client-C5G4h_OJ.mjs → hosted-client--hNFgixu.mjs} +9 -3
- package/dist/{hosted-ios-Bik035eL.mjs → hosted-ios-Chx9XQyI.mjs} +3 -3
- package/dist/{hosted-logs-CI9Az9a4.mjs → hosted-logs-Bkz0Hxzh.mjs} +8 -8
- package/dist/{hosted-macos-DABm3ScO.mjs → hosted-macos-ckTjN-0V.mjs} +7 -6
- package/dist/{hosted-native-DbV2aUVw.mjs → hosted-native-3KXZ5-qn.mjs} +17 -14
- package/dist/{idle-shutdown-DYiMBn34.mjs → idle-shutdown-DhAUyf5s.mjs} +7 -7
- package/dist/{ios-DYUr9LGc.mjs → ios-BDBN-xpf.mjs} +8 -7
- package/dist/ios-CQ8bHQXB.mjs +1112 -0
- package/dist/{ios-DCrkgXEM.mjs → ios-VGvNdsv2.mjs} +1 -1
- package/dist/{ios-device-CrW8aMb5.mjs → ios-device-B1B14xND.mjs} +1 -1
- package/dist/{ios-device-CJ_ZOGky.mjs → ios-device-BWHKGaJq.mjs} +3 -3
- package/dist/{ios-BWbHFZVz.mjs → ios-o896T9PE.mjs} +195 -35
- package/dist/ios-project-BeOXKPt2.mjs +197 -0
- package/dist/{ios-state-By0XuLTQ.mjs → ios-state-BsXMwo5y.mjs} +1 -1
- package/dist/js-swap-Z_mSuRrx.mjs +432 -0
- package/dist/{react-native-ios-CSpIxexZ.mjs → launch-BootbMk4.mjs} +59 -612
- package/dist/launch-V1zqiOYn.mjs +745 -0
- package/dist/{launch-verify-DCveSE6d.mjs → launch-verify-Dl78EVgR.mjs} +26 -7
- package/dist/{logs-Bao1HOMy.mjs → logs-Bh4eqCCc.mjs} +11 -11
- package/dist/{macos-ciyBdTY5.mjs → macos-D7irBW3A.mjs} +42 -50
- package/dist/macos-kivF8qKz.mjs +2 -0
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +13 -10
- package/dist/{metro-DI2AjPF_.mjs → metro-_ZIE3Axg.mjs} +18 -5
- package/dist/{metro-gateway-BxpJLIwh.mjs → metro-gateway-BzlQZQmU.mjs} +2 -2
- package/dist/miss-reason-SuTptY-I.mjs +238 -0
- package/dist/{named-ports-B4iWH4E-.mjs → named-ports-O1TIl7tx.mjs} +3 -3
- package/dist/native-android-D94RlJ-X.mjs +226 -0
- package/dist/native-gradle-inputs-BQnIdAlL.mjs +356 -0
- package/dist/{native-runtime-BGxsbfny.mjs → native-runtime-D024BAvm.mjs} +9 -8
- package/dist/native-xcode-inputs-UElfGs59.mjs +306 -0
- package/dist/native-xcode-ios-CjS-nDVY.mjs +434 -0
- package/dist/{ndjson-LGZAMsqa.mjs → ndjson-GOnbyvso.mjs} +6 -6
- package/dist/offload-worker.d.mts +41 -7
- package/dist/offload-worker.mjs +409 -74
- package/dist/{ownership-EB0ySdGK.mjs → ownership-BrjepDiv.mjs} +2 -2
- package/dist/{placement-log-Dxe34rJm.mjs → placement-log-BItXET1x.mjs} +1 -1
- package/dist/plan-Jwu_vr-F.mjs +260 -0
- package/dist/plan-placement-B466UYMU.mjs +73 -0
- package/dist/{ports-ByPc0_97.mjs → ports-BFRL6JTj.mjs} +3 -3
- package/dist/{prebuild-BKJ3wJI1.mjs → prebuild-DB_zLOLc.mjs} +4 -4
- package/dist/{preview-BbSottmO.mjs → preview-BRLFRhTz.mjs} +50 -32
- package/dist/project-DX8fXyw_.mjs +1131 -0
- package/dist/project-plan-BPwbLwQu.mjs +10 -0
- package/dist/{pull-request-IHNdMnG8.mjs → pull-request-vOhLNmIb.mjs} +1 -1
- package/dist/pull-requests.mjs +1 -1
- package/dist/react-native-android-CuXM3QS8.mjs +921 -0
- package/dist/react-native-build-JUF31S8U.mjs +239 -0
- package/dist/react-native-doctor-BQHqiXaQ.mjs +78 -0
- package/dist/react-native-ios-DtVO4qf2.mjs +595 -0
- package/dist/{recordings-Bv8McZN4.mjs → recordings-Bk-VivUV.mjs} +1 -1
- package/dist/{reload-rAPdqeRR.mjs → reload-D9V7D8gP.mjs} +17 -13
- package/dist/remote-CZiTijxG.mjs +192 -0
- package/dist/{remote-cache-N3hAEaAL.mjs → remote-cache-fxcl5C-L.mjs} +5 -5
- package/dist/result-BrfgXtdO.mjs +186 -0
- package/dist/{run-lAkle1-c.mjs → run-ClC8UVB5.mjs} +3 -3
- package/dist/{server-bare-CkIjnegq.mjs → server-bare-dWjAarki.mjs} +5 -5
- package/dist/server-command-DnJYLnr4.mjs +69 -0
- package/dist/{server-expo-n3tUi3Em.mjs → server-expo-CUuzP9Mp.mjs} +107 -82
- package/dist/server-expo-Dvkd7JcF.mjs +2 -0
- package/dist/{settings-CxgngUZk.mjs → settings-Bbztm4oV.mjs} +179 -129
- package/dist/{settings-2am7TSxp.mjs → settings-BuKMOANA.mjs} +6 -6
- package/dist/{state-lKh8shBp.d.mts → settings-vk3mJGSm.d.mts} +4 -2
- package/dist/settings.schema.json +84 -0
- package/dist/simslim-ChMfe8rg.mjs +149 -0
- package/dist/{slot-launch-HV_KtPIw.mjs → slot-launch-CeCRr6MK.mjs} +6 -6
- package/dist/{stage-BgaZJVZY.mjs → stage-BNKKdDNc.mjs} +6 -3
- package/dist/{start-DtxthMfI.mjs → start-CRkG-mZ7.mjs} +97 -68
- package/dist/start-mh6bS27z.mjs +2 -0
- package/dist/{state-Tp4uImDS.mjs → state-BUpAmt2r.mjs} +1 -1
- package/dist/{state-D2KtnALG.mjs → state-lqxdOH_g.mjs} +32 -12
- package/dist/{stats-8EJ5ivFT.mjs → stats-CaB1MxMi.mjs} +5 -5
- package/dist/{status-BEeL6IKz.mjs → status-BDGHwkCs.mjs} +3 -1
- package/dist/{status-BOyp0CUl.mjs → status-C7vzkInu.mjs} +81 -293
- package/dist/status-watch-ZaVqRdtW.mjs +296 -0
- package/dist/{stim-desktop-C65jk_q2.mjs → stim-desktop-8GQX2OV8.mjs} +1 -1
- package/dist/{stop-zDlknFoz.mjs → stop-BO80KJoT.mjs} +21 -20
- package/dist/{stop-DRipAg-e.mjs → stop-BU7JaFCg.mjs} +2 -2
- package/dist/{stop-D0UIpZuh.mjs → stop-Cftw_sXJ.mjs} +5 -5
- package/dist/supervisor-run.d.mts +7 -2
- package/dist/supervisor-run.mjs +32 -20
- package/dist/{support-DsNaFg6D.mjs → support-Ca6PZbpr.mjs} +17 -7
- package/dist/{support-CNqYkV0y.mjs → support-Co0wk8Cv.mjs} +61 -8
- package/dist/{swiftpm-macos-aJzPAj1t.mjs → swiftpm-macos-siFSkmCO.mjs} +5 -5
- package/dist/tailnet-D7-tE_ug.mjs +265 -0
- package/dist/toolchain-B12psPA2.mjs +2 -0
- package/dist/{toolchain-C3xSoyUl.mjs → toolchain-SqehyPLw.mjs} +206 -53
- package/dist/{trigger-CAhmG-4s.mjs → trigger-C0MWBi8O.mjs} +2 -2
- package/dist/trigger-SHLOWJ4O.mjs +2 -0
- package/dist/{warm-progress-pFLB2e6P.mjs → warm-progress-5FAXkXIg.mjs} +6 -6
- package/dist/{watchman-BL1IdOtq.mjs → watchman-CqmaGcIb.mjs} +6 -6
- package/dist/{web-DbbrPUn0.mjs → web-BTjzE8mc.mjs} +9 -13
- package/dist/web-CHN5gh34.mjs +2 -0
- package/dist/web-run.mjs +10 -10
- package/dist/{workspace-state-CR9X86xJ.mjs → workspace-state-CvgTFe-h.mjs} +36 -36
- package/dist/{workspaces-Djb2gfi9.mjs → workspaces-C4kqIOlx.mjs} +1260 -1258
- package/dist/worktree-Cgnm6vZt.mjs +2 -0
- package/dist/{worktree-BL4M1rhB.mjs → worktree-DtRsh6go.mjs} +86 -50
- package/package.json +6 -5
- package/shim/native-android.gradle +101 -0
- package/dist/android-BXc6BmEi.mjs +0 -3732
- package/dist/android-BvV1gGdN.mjs +0 -4
- package/dist/ios-ITYno9rO.mjs +0 -2241
- package/dist/macos-nIOATJmR.mjs +0 -2
- package/dist/metro-store-BAHFcJm6.mjs +0 -106
- package/dist/miss-reason-CjQCOKqq.mjs +0 -1743
- package/dist/plan-placement-BVY59qa8.mjs +0 -290
- package/dist/project-B5eQ1USs.mjs +0 -612
- package/dist/react-native-ios-BMh2i25I.mjs +0 -2
- package/dist/server-expo-DGsdUGX2.mjs +0 -2
- package/dist/start-D8NbxNBb.mjs +0 -2
- package/dist/trigger-CoalsMTV.mjs +0 -2
- package/dist/web-DFpFeZu5.mjs +0 -2
- package/dist/worktree-DV-A0LNL.mjs +0 -2
|
@@ -0,0 +1,807 @@
|
|
|
1
|
+
import { n as ownership_claim_exports } from "./process-identity-Biv3arCO.mjs";
|
|
2
|
+
import { A as providerDownloadPath, j as providerUploadOutcome, k as prepareProviderDownloadDir, v as waitForSharedBuild } from "./device-lease-C309csaB.mjs";
|
|
3
|
+
import { x as workspaceDir } from "./workspace-state-CvgTFe-h.mjs";
|
|
4
|
+
import { _ as stepTimer, i as formatDuration, l as phaseLine, m as shortHash } from "./command-output-CPDq_90S.mjs";
|
|
5
|
+
import { x as runCancellationSignal } from "./tailnet-D7-tE_ug.mjs";
|
|
6
|
+
import { a as easAuthNote, s as isEasAuthFailureText, t as RESOLVE_TIMEOUT_MS } from "./remote-cache-fxcl5C-L.mjs";
|
|
7
|
+
import { _ as requireLocalBuild, c as offloadPlacement, h as namedBuildMachine, i as closeOffload, l as placementLoad, n as buildPlacementCandidates, o as offloadBuild, p as OffloadRefusal, r as chooseBuildMachine, u as remotePhaseText } from "./client-zqjFd79D.mjs";
|
|
8
|
+
import { i as skippedMissReason } from "./miss-reason-SuTptY-I.mjs";
|
|
9
|
+
import { t as buildPlacementRecord } from "./placement-log-BItXET1x.mjs";
|
|
10
|
+
import { t as runArtifactLifecycle } from "./artifact-lifecycle-DzPpBYvK.mjs";
|
|
11
|
+
import { S as compilationCacheActivityLine, _ as COMPILATION_CACHE_NOT_RUN } from "./toolchain-SqehyPLw.mjs";
|
|
12
|
+
import { S as xcodeFailureReport, p as printDiagnostics } from "./support-Co0wk8Cv.mjs";
|
|
13
|
+
import { r as finishIosUpload, t as IosRecipeRefusal } from "./ios-project-BeOXKPt2.mjs";
|
|
14
|
+
import { rmSync } from "node:fs";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { machineCapacity } from "@stim-cli/core/state";
|
|
17
|
+
import { createWarnOnce, resolveTieredBuild, storeTieredBuild } from "@stim-cli/cache";
|
|
18
|
+
import chalk from "chalk";
|
|
19
|
+
//#region src/commands/ios/artifact.ts
|
|
20
|
+
const PROVIDER_SKIPPED_ON_DEVICE = "a device build is local-tier only: its cache key names the iphoneos slice, and a remote or provider entry is keyed for the simulator";
|
|
21
|
+
function fail(failure) {
|
|
22
|
+
throw new IosRecipeRefusal(failure);
|
|
23
|
+
}
|
|
24
|
+
async function acquireIosArtifact({ root, logFile, recipe, physical, configuration, buildMachine = "auto", cache, easBuild, maxBuilds, progress }, d) {
|
|
25
|
+
const { phase, note, logWriter, stats, step, miss, hit: lateHit, place, waitingOn, waitingFor } = progress;
|
|
26
|
+
const cachePolicy = cache.policy;
|
|
27
|
+
const signal = runCancellationSignal() ?? new AbortController().signal;
|
|
28
|
+
const cacheTarget = (key) => ({
|
|
29
|
+
projectRoot: root,
|
|
30
|
+
platform: "ios",
|
|
31
|
+
key,
|
|
32
|
+
signal
|
|
33
|
+
});
|
|
34
|
+
let useBuildCache = cachePolicy.read;
|
|
35
|
+
let cacheIneligible = null;
|
|
36
|
+
const cacheProviderConfig = cache.providerConfig;
|
|
37
|
+
let compilationCache = COMPILATION_CACHE_NOT_RUN;
|
|
38
|
+
const temporaryDirs = /* @__PURE__ */ new Set();
|
|
39
|
+
const releaseArtifact = () => {
|
|
40
|
+
for (const directory of temporaryDirs) {
|
|
41
|
+
try {
|
|
42
|
+
rmSync(directory, {
|
|
43
|
+
recursive: true,
|
|
44
|
+
force: true
|
|
45
|
+
});
|
|
46
|
+
} catch {}
|
|
47
|
+
temporaryDirs.delete(directory);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
let buildLock = null;
|
|
51
|
+
const releaseLock = () => {
|
|
52
|
+
if (!buildLock) return;
|
|
53
|
+
const held = buildLock;
|
|
54
|
+
buildLock = null;
|
|
55
|
+
try {
|
|
56
|
+
d.releaseBuildLock(held);
|
|
57
|
+
} catch (e) {
|
|
58
|
+
note(chalk.dim(`Could not release the build lock at ${held.path}: ${e?.message || e}`));
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
let buildSlot = null;
|
|
62
|
+
const releaseSlot = () => {
|
|
63
|
+
if (!buildSlot) return;
|
|
64
|
+
const held = buildSlot;
|
|
65
|
+
buildSlot = null;
|
|
66
|
+
try {
|
|
67
|
+
d.releaseBuildSlot(held);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
note(chalk.dim(`Could not release the build slot: ${e?.message || e}`));
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
let fingerprint = "";
|
|
73
|
+
let cacheKey = "";
|
|
74
|
+
let storeHash = null;
|
|
75
|
+
let storeKey = null;
|
|
76
|
+
let appPath = null;
|
|
77
|
+
let bundleId = null;
|
|
78
|
+
let cacheHit = false;
|
|
79
|
+
let offloadedTo = null;
|
|
80
|
+
let handoff = null;
|
|
81
|
+
let offloadFallback = null;
|
|
82
|
+
let fallbackMachine = null;
|
|
83
|
+
let hereReason = "no remote Mac is paired";
|
|
84
|
+
let slotWaitMs;
|
|
85
|
+
let builtOn;
|
|
86
|
+
const fallBack = (reason, line = reason, info = {}) => {
|
|
87
|
+
logWriter().write(buildPlacementRecord({
|
|
88
|
+
platform: "ios",
|
|
89
|
+
buildMachine,
|
|
90
|
+
candidates: info.candidates,
|
|
91
|
+
event: "placement_fallback",
|
|
92
|
+
fallback: {
|
|
93
|
+
code: info.code ?? "fallback",
|
|
94
|
+
reason,
|
|
95
|
+
machine: info.machine
|
|
96
|
+
}
|
|
97
|
+
}));
|
|
98
|
+
if (namedBuildMachine(buildMachine)) throw new OffloadRefusal(buildMachine, reason);
|
|
99
|
+
requireLocalBuild(buildMachine);
|
|
100
|
+
offloadFallback = reason;
|
|
101
|
+
buildFailure = {
|
|
102
|
+
...buildFailure,
|
|
103
|
+
offloadFallback: reason
|
|
104
|
+
};
|
|
105
|
+
phase("build", `${line} -> building here`);
|
|
106
|
+
};
|
|
107
|
+
const openOffload = { choice: null };
|
|
108
|
+
let remote = null;
|
|
109
|
+
let abandonedRemote = false;
|
|
110
|
+
let uploadPending = null;
|
|
111
|
+
let providerUpload = null;
|
|
112
|
+
let providerName = null;
|
|
113
|
+
let providerLoad = null;
|
|
114
|
+
const cacheWarn = createWarnOnce((line) => note(chalk.yellow(phaseLine("cache", line))));
|
|
115
|
+
const loadProvider = cachePolicy.remote && cacheProviderConfig && !physical ? () => providerLoad ??= d.loadCacheProvider({
|
|
116
|
+
projectRoot: root,
|
|
117
|
+
config: cacheProviderConfig
|
|
118
|
+
}) : null;
|
|
119
|
+
if (cacheProviderConfig && physical) note(chalk.dim(phaseLine("cache", PROVIDER_SKIPPED_ON_DEVICE)));
|
|
120
|
+
let waitedForBuild = null;
|
|
121
|
+
let releasedWait = null;
|
|
122
|
+
let swapFellBack = false;
|
|
123
|
+
let buildFailure = {};
|
|
124
|
+
let missReason = null;
|
|
125
|
+
async function resolveInitialFingerprint() {
|
|
126
|
+
if (easBuild?.ok) {
|
|
127
|
+
fingerprint = storeHash = easBuild.fingerprint;
|
|
128
|
+
cacheKey = storeKey = easBuild.cacheKey;
|
|
129
|
+
appPath = easBuild.path;
|
|
130
|
+
cacheHit = easBuild.cacheHit;
|
|
131
|
+
providerName = "eas";
|
|
132
|
+
stats.setCacheKey(cacheKey);
|
|
133
|
+
recipe.validateExternal(appPath);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (useBuildCache) step("cache-lookup");
|
|
137
|
+
const fingerprintTimer = stepTimer(d.now);
|
|
138
|
+
const identity = await recipe.identity();
|
|
139
|
+
if ("cacheIneligible" in identity) {
|
|
140
|
+
cacheIneligible = identity.cacheIneligible;
|
|
141
|
+
useBuildCache = false;
|
|
142
|
+
phase("fingerprint", `unavailable: ${cacheIneligible}`);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
fingerprint = identity.hash;
|
|
146
|
+
cacheKey = identity.key;
|
|
147
|
+
stats.setCacheKey(cacheKey);
|
|
148
|
+
storeHash = fingerprint;
|
|
149
|
+
storeKey = cacheKey;
|
|
150
|
+
const found = await resolveTieredBuild({
|
|
151
|
+
local: recipe.cache(),
|
|
152
|
+
loadProvider,
|
|
153
|
+
target: {
|
|
154
|
+
projectRoot: root,
|
|
155
|
+
platform: "ios",
|
|
156
|
+
key: cacheKey
|
|
157
|
+
},
|
|
158
|
+
destinationDir: providerDownloadPath(workspaceDir(root)),
|
|
159
|
+
ensureDestination: prepareProviderDownloadDir,
|
|
160
|
+
skipRead: !useBuildCache,
|
|
161
|
+
warn: cacheWarn
|
|
162
|
+
});
|
|
163
|
+
const cached = found?.tier === "local" ? found.path : null;
|
|
164
|
+
cacheHit = cached ? "local" : false;
|
|
165
|
+
phase("fingerprint", `${shortHash(fingerprint)} ${cached ? "hit" : "miss"}${useBuildCache ? "" : cache.disabledByFlag ? " (--no-build-cache)" : " (cache reuse off in config)"} ${fingerprintTimer()}`);
|
|
166
|
+
if (found?.tier === "provider") {
|
|
167
|
+
cacheHit = "remote";
|
|
168
|
+
providerName = found.providerName ?? null;
|
|
169
|
+
phase("cache", `provider hit (${providerName})${found.storedLocally ? " -> stored locally" : ""}`);
|
|
170
|
+
}
|
|
171
|
+
appPath = found?.path ?? null;
|
|
172
|
+
}
|
|
173
|
+
async function resolveRemoteArtifact() {
|
|
174
|
+
if (cacheIneligible || !recipe.legacyCache) return null;
|
|
175
|
+
if (!appPath) {
|
|
176
|
+
const loaded = await recipe.legacyCache.load();
|
|
177
|
+
if (loaded?.unavailable) note(chalk.yellow(phaseLine("cache", `provider not usable: ${loaded.unavailable}`)));
|
|
178
|
+
else if (loaded?.provider) remote = loaded;
|
|
179
|
+
if (remote?.name === "eas") {
|
|
180
|
+
const auth = d.checkEasAuth({
|
|
181
|
+
projectRoot: root,
|
|
182
|
+
owner: loaded?.owner || null
|
|
183
|
+
});
|
|
184
|
+
const authNote = easAuthNote(auth);
|
|
185
|
+
if (authNote) note(chalk.yellow(phaseLine("cache", authNote)));
|
|
186
|
+
if (auth?.code === "logged-out") remote = null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (remote && useBuildCache) {
|
|
190
|
+
const remoteTimer = stepTimer(d.now);
|
|
191
|
+
const hit = await d.resolveRemote({
|
|
192
|
+
logWriter: logWriter(),
|
|
193
|
+
provider: remote.provider,
|
|
194
|
+
platform: "ios",
|
|
195
|
+
projectRoot: root,
|
|
196
|
+
fingerprintHash: fingerprint,
|
|
197
|
+
runOptions: recipe.legacyCache?.runOptions ?? null
|
|
198
|
+
});
|
|
199
|
+
if (hit?.appPath) {
|
|
200
|
+
let stored = null;
|
|
201
|
+
try {
|
|
202
|
+
stored = await recipe.cache().store({
|
|
203
|
+
...cacheTarget(cacheKey),
|
|
204
|
+
sourcePath: hit.appPath,
|
|
205
|
+
overwrite: false
|
|
206
|
+
}) ?? null;
|
|
207
|
+
} catch (e) {
|
|
208
|
+
note(chalk.yellow(phaseLine("cache", `remote hit could not be stored locally: ${e?.message || e}`)));
|
|
209
|
+
}
|
|
210
|
+
appPath = stored || hit.appPath;
|
|
211
|
+
cacheHit = "remote";
|
|
212
|
+
phase("cache", `remote hit (${remote.name})${stored ? " -> stored locally" : ""} ${remoteTimer()}`);
|
|
213
|
+
} else if (hit?.timedOut) {
|
|
214
|
+
abandonedRemote = true;
|
|
215
|
+
note(chalk.yellow(phaseLine("cache", `${remote.name} did not answer within ${formatDuration(RESOLVE_TIMEOUT_MS)}; building instead`)));
|
|
216
|
+
} else if (hit?.failed) {
|
|
217
|
+
const authNote = remote.name === "eas" && isEasAuthFailureText(hit.failed) ? easAuthNote({
|
|
218
|
+
code: "logged-out",
|
|
219
|
+
reason: hit.failed
|
|
220
|
+
}) : null;
|
|
221
|
+
note(chalk.yellow(phaseLine("cache", authNote || `${remote.name} could not be used: ${hit.failed}; building instead`)));
|
|
222
|
+
} else phase("cache", `remote miss (${remote.name}) ${remoteTimer()}`);
|
|
223
|
+
}
|
|
224
|
+
return remote;
|
|
225
|
+
}
|
|
226
|
+
async function awaitSharedBuild() {
|
|
227
|
+
if (!useBuildCache || appPath) return;
|
|
228
|
+
const shared = await waitForSharedBuild({
|
|
229
|
+
platform: "ios",
|
|
230
|
+
key: cacheKey,
|
|
231
|
+
fingerprint,
|
|
232
|
+
root,
|
|
233
|
+
logFile,
|
|
234
|
+
command: "stim ios",
|
|
235
|
+
acquire: d.acquireBuildLock,
|
|
236
|
+
wait: d.waitForBuild,
|
|
237
|
+
now: d.now,
|
|
238
|
+
phase: (text) => {
|
|
239
|
+
step("wait");
|
|
240
|
+
phase("build", text);
|
|
241
|
+
},
|
|
242
|
+
waitingOn,
|
|
243
|
+
warn: (text) => note(chalk.yellow(phaseLine("build", text))),
|
|
244
|
+
out: note
|
|
245
|
+
});
|
|
246
|
+
if (shared.refusal) fail({
|
|
247
|
+
...shared.refusal,
|
|
248
|
+
build: {
|
|
249
|
+
fingerprint,
|
|
250
|
+
cacheKey,
|
|
251
|
+
cacheHit,
|
|
252
|
+
cacheSkipped: !useBuildCache
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
buildLock = shared.lock;
|
|
256
|
+
releasedWait = shared.released;
|
|
257
|
+
if (shared.hit) {
|
|
258
|
+
appPath = shared.hit.path;
|
|
259
|
+
cacheHit = "local";
|
|
260
|
+
waitedForBuild = shared.hit.waited;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
const installableCachedApp = async (path) => {
|
|
264
|
+
const prepared = await recipe.materialize(path, {
|
|
265
|
+
fresh: false,
|
|
266
|
+
ownTemporary: (directory) => temporaryDirs.add(directory)
|
|
267
|
+
});
|
|
268
|
+
if (!prepared) swapFellBack = true;
|
|
269
|
+
return prepared;
|
|
270
|
+
};
|
|
271
|
+
async function prepareCachedArtifact(cachedPath) {
|
|
272
|
+
const prepared = await installableCachedApp(cachedPath);
|
|
273
|
+
if (!prepared) {
|
|
274
|
+
cacheHit = false;
|
|
275
|
+
waitedForBuild = null;
|
|
276
|
+
}
|
|
277
|
+
return prepared;
|
|
278
|
+
}
|
|
279
|
+
function reasonForMiss(rekeyedBy) {
|
|
280
|
+
if (swapFellBack) return {
|
|
281
|
+
reason: skippedMissReason("the cached app could not be reused, so this run built it fresh"),
|
|
282
|
+
diff: null
|
|
283
|
+
};
|
|
284
|
+
if (cacheIneligible) return {
|
|
285
|
+
reason: skippedMissReason(cacheIneligible),
|
|
286
|
+
diff: null
|
|
287
|
+
};
|
|
288
|
+
if (!useBuildCache) return {
|
|
289
|
+
reason: skippedMissReason(cache.disabledByFlag ? "cache reuse turned off by --no-build-cache" : "cache reuse off in config"),
|
|
290
|
+
diff: null
|
|
291
|
+
};
|
|
292
|
+
return recipe.explain(rekeyedBy);
|
|
293
|
+
}
|
|
294
|
+
function explainMiss(rekeyedBy) {
|
|
295
|
+
const explained = reasonForMiss(rekeyedBy);
|
|
296
|
+
missReason = explained.reason;
|
|
297
|
+
if (explained.diff) logWriter().write(explained.diff);
|
|
298
|
+
buildFailure = {
|
|
299
|
+
...buildFailure,
|
|
300
|
+
missReason
|
|
301
|
+
};
|
|
302
|
+
miss(missReason);
|
|
303
|
+
phase("cache", `miss: ${missReason.summary}`);
|
|
304
|
+
if (missReason.kind === "no-baseline") {
|
|
305
|
+
const untracked = recipe.untrackedLine();
|
|
306
|
+
if (untracked) note(chalk.dim(phaseLine("fingerprint", untracked)));
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
async function settleStoreKeyAfterCompile() {
|
|
310
|
+
if (!storeHash || !storeKey) return;
|
|
311
|
+
const identity = await recipe.validate();
|
|
312
|
+
storeHash = identity?.hash ?? null;
|
|
313
|
+
storeKey = identity?.key ?? null;
|
|
314
|
+
buildFailure = {
|
|
315
|
+
...buildFailure,
|
|
316
|
+
fingerprint: storeHash,
|
|
317
|
+
cacheKey: storeKey
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
async function takeBuildSlot() {
|
|
321
|
+
requireLocalBuild(buildMachine);
|
|
322
|
+
if (!maxBuilds) return;
|
|
323
|
+
try {
|
|
324
|
+
buildSlot = await d.acquireBuildSlot({
|
|
325
|
+
automatic: buildMachine === "auto",
|
|
326
|
+
max: maxBuilds,
|
|
327
|
+
root,
|
|
328
|
+
logFile,
|
|
329
|
+
out: note,
|
|
330
|
+
waitingFor: (info) => waitingFor?.(info, "build-slot")
|
|
331
|
+
});
|
|
332
|
+
slotWaitMs = buildSlot.slotWaitMs;
|
|
333
|
+
} catch (e) {
|
|
334
|
+
requireLocalBuild(buildMachine);
|
|
335
|
+
const refusal = (0, ownership_claim_exports.claimFailure)(e, "stim ios");
|
|
336
|
+
if (refusal) fail({
|
|
337
|
+
code: refusal.code,
|
|
338
|
+
message: refusal.message,
|
|
339
|
+
remedy: refusal.remedy,
|
|
340
|
+
build: buildFailure
|
|
341
|
+
});
|
|
342
|
+
note(chalk.yellow(phaseLine("build", `could not take a build slot: ${e?.message || e}; building anyway`)));
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
/** Whether this build should leave this Mac, before any machine is asked; null builds here. */
|
|
346
|
+
function placeBuild() {
|
|
347
|
+
if (cacheIneligible) {
|
|
348
|
+
if (namedBuildMachine(buildMachine)) throw new OffloadRefusal(buildMachine, cacheIneligible);
|
|
349
|
+
hereReason = cacheIneligible;
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
const { mode, machines, localEnabled } = buildPlacementCandidates(buildMachine);
|
|
353
|
+
if (localEnabled && machines.length === 0 && !namedBuildMachine(buildMachine) && buildMachine !== "local") return null;
|
|
354
|
+
const { runtime, unsupported } = mode === "off" && !namedBuildMachine(buildMachine) ? {
|
|
355
|
+
runtime: null,
|
|
356
|
+
unsupported: null
|
|
357
|
+
} : recipe.offload?.context() ?? {
|
|
358
|
+
runtime: null,
|
|
359
|
+
unsupported: "this project integration does not support offloaded builds"
|
|
360
|
+
};
|
|
361
|
+
const here = machineCapacity();
|
|
362
|
+
const placement = offloadPlacement({
|
|
363
|
+
mode,
|
|
364
|
+
localEnabled,
|
|
365
|
+
machines: machines.length,
|
|
366
|
+
here,
|
|
367
|
+
unsupported,
|
|
368
|
+
selected: buildMachine
|
|
369
|
+
});
|
|
370
|
+
if (!placement.offload) {
|
|
371
|
+
hereReason = placement.reason;
|
|
372
|
+
logWriter().write(buildPlacementRecord({
|
|
373
|
+
platform: "ios",
|
|
374
|
+
buildMachine,
|
|
375
|
+
stays: {
|
|
376
|
+
code: placement.code,
|
|
377
|
+
reason: placement.reason
|
|
378
|
+
}
|
|
379
|
+
}));
|
|
380
|
+
if (mode !== "off") phase("build", `placement: here (${placement.reason})`);
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
return {
|
|
384
|
+
mode,
|
|
385
|
+
here,
|
|
386
|
+
code: placement.code,
|
|
387
|
+
reason: placement.reason,
|
|
388
|
+
runtime,
|
|
389
|
+
machines
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
/** Asks the paired machines once the post-mutation key is known; null builds here. */
|
|
393
|
+
async function chooseMachine(candidate) {
|
|
394
|
+
let asked = [];
|
|
395
|
+
const choice = await chooseBuildMachine({
|
|
396
|
+
projectRoot: root,
|
|
397
|
+
target: recipe.offload.target(candidate.runtime),
|
|
398
|
+
mode: candidate.mode,
|
|
399
|
+
here: candidate.here,
|
|
400
|
+
note: (line) => note(chalk.dim(phaseLine("build", `offload: ${line}`))),
|
|
401
|
+
machines: candidate.machines,
|
|
402
|
+
selected: buildMachine,
|
|
403
|
+
onCandidates: (each) => asked = each
|
|
404
|
+
});
|
|
405
|
+
if (typeof choice === "string") {
|
|
406
|
+
const only = candidate.machines.length === 1 ? candidate.machines[0].machine : null;
|
|
407
|
+
if (only && choice.startsWith(`${only}: `)) fallbackMachine = only;
|
|
408
|
+
fallBack(choice, choice, {
|
|
409
|
+
code: "no-remote-mac-took-it",
|
|
410
|
+
candidates: asked
|
|
411
|
+
});
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
openOffload.choice = choice;
|
|
415
|
+
logWriter().write(buildPlacementRecord({
|
|
416
|
+
platform: "ios",
|
|
417
|
+
buildMachine,
|
|
418
|
+
candidates: asked,
|
|
419
|
+
chose: {
|
|
420
|
+
machine: choice.machine,
|
|
421
|
+
reason: `${candidate.reason}${placementLoad(choice)}`
|
|
422
|
+
}
|
|
423
|
+
}));
|
|
424
|
+
phase("build", `placement: ${choice.machine} (${candidate.reason}${placementLoad(choice)})`);
|
|
425
|
+
return choice;
|
|
426
|
+
}
|
|
427
|
+
/** Builds on the chosen machine and stores the app under the post-mutation key; false builds here instead unless a machine was named. */
|
|
428
|
+
async function compileElsewhere({ choice, candidate }) {
|
|
429
|
+
const runtime = candidate.runtime;
|
|
430
|
+
if (!storeKey || !storeHash) {
|
|
431
|
+
if (namedBuildMachine(buildMachine)) fallBack("the build fingerprint or cache key is unavailable");
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
const stagingDir = join(workspaceDir(root), "offload", "ios");
|
|
435
|
+
const outcome = await offloadBuild({
|
|
436
|
+
choice,
|
|
437
|
+
expectedFingerprint: storeHash,
|
|
438
|
+
request: recipe.offload.request(runtime),
|
|
439
|
+
stagingDir,
|
|
440
|
+
onPhase: (name, msg) => phase(name, remotePhaseText(name, msg, choice.machine)),
|
|
441
|
+
onEnter: (name) => {
|
|
442
|
+
if (name === "compile" || name === "build" || name === "prebuild" || name === "pods") {
|
|
443
|
+
builtOn = choice.machine;
|
|
444
|
+
buildFailure = {
|
|
445
|
+
...buildFailure,
|
|
446
|
+
builtOn
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
place({
|
|
450
|
+
host: choice.machine,
|
|
451
|
+
phase: name
|
|
452
|
+
});
|
|
453
|
+
step(name === "prebuild" || name === "pods" ? name : "compile");
|
|
454
|
+
},
|
|
455
|
+
onRecord: (record) => logWriter().write({
|
|
456
|
+
...record,
|
|
457
|
+
offloadedTo: choice.machine
|
|
458
|
+
}),
|
|
459
|
+
note: (line) => phase("build", line)
|
|
460
|
+
});
|
|
461
|
+
place(null);
|
|
462
|
+
let stored = null;
|
|
463
|
+
let reason = outcome.ok ? null : outcome.reason;
|
|
464
|
+
if (outcome.ok) {
|
|
465
|
+
if (!await recipe.offload.unchanged()) reason = "the checkout here changed while it built";
|
|
466
|
+
else try {
|
|
467
|
+
stored = await recipe.cache().store({
|
|
468
|
+
...cacheTarget(storeKey),
|
|
469
|
+
sourcePath: outcome.artifactPath,
|
|
470
|
+
overwrite: !useBuildCache
|
|
471
|
+
}) ?? null;
|
|
472
|
+
} catch (e) {
|
|
473
|
+
reason = `could not store the app: ${e?.message || e}`;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
try {
|
|
477
|
+
rmSync(stagingDir, {
|
|
478
|
+
recursive: true,
|
|
479
|
+
force: true
|
|
480
|
+
});
|
|
481
|
+
} catch {}
|
|
482
|
+
step("compile");
|
|
483
|
+
const prepared = stored ? await installableCachedApp(stored) : null;
|
|
484
|
+
if (!outcome.ok || !prepared) {
|
|
485
|
+
const why = reason ?? "the stored app is not installable";
|
|
486
|
+
fallbackMachine = choice.machine;
|
|
487
|
+
fallBack(`${choice.machine}: ${why}`, `offload failed: ${why}`, {
|
|
488
|
+
code: "offload-failed",
|
|
489
|
+
machine: choice.machine
|
|
490
|
+
});
|
|
491
|
+
logWriter().write({
|
|
492
|
+
src: "build",
|
|
493
|
+
level: "warn",
|
|
494
|
+
event: "offload_failed",
|
|
495
|
+
msg: reason,
|
|
496
|
+
machine: choice.machine
|
|
497
|
+
});
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
const { timings } = outcome;
|
|
501
|
+
appPath = prepared;
|
|
502
|
+
builtOn = outcome.machine;
|
|
503
|
+
offloadedTo = outcome.machine;
|
|
504
|
+
handoff = outcome.handoff ?? null;
|
|
505
|
+
stats.setPlacement({
|
|
506
|
+
decision: "offloaded",
|
|
507
|
+
machine: outcome.machine,
|
|
508
|
+
reason: `${candidate.reason}${placementLoad(choice)}`,
|
|
509
|
+
buildMs: timings.totalMs
|
|
510
|
+
});
|
|
511
|
+
phase("build", `built on ${outcome.machine} in ${formatDuration(timings.totalMs)}: offer ${formatDuration(timings.offerMs)}, sync ${formatDuration(timings.syncMs)}, build ${formatDuration(timings.workerMs)}, fetch ${formatDuration(timings.fetchMs)}`);
|
|
512
|
+
compilationCache = outcome.compilationCache;
|
|
513
|
+
phase("cache", `compilation cache on ${outcome.machine} ${compilationCacheActivityLine(compilationCache)}`);
|
|
514
|
+
logWriter().write({
|
|
515
|
+
src: "build",
|
|
516
|
+
level: "info",
|
|
517
|
+
event: "offload_done",
|
|
518
|
+
msg: `built on ${outcome.machine}`,
|
|
519
|
+
timings
|
|
520
|
+
});
|
|
521
|
+
return true;
|
|
522
|
+
}
|
|
523
|
+
async function prepareSource() {
|
|
524
|
+
await recipe.prepare(() => miss(reasonForMiss([]).reason, true));
|
|
525
|
+
return recipe.reconcile();
|
|
526
|
+
}
|
|
527
|
+
async function revalidateSource({ identity, mutationLabel }) {
|
|
528
|
+
if (cacheIneligible || !identity) {
|
|
529
|
+
storeHash = null;
|
|
530
|
+
storeKey = null;
|
|
531
|
+
buildFailure = {
|
|
532
|
+
...buildFailure,
|
|
533
|
+
fingerprint: null,
|
|
534
|
+
cacheKey: null
|
|
535
|
+
};
|
|
536
|
+
} else if (identity.key !== storeKey) {
|
|
537
|
+
storeHash = identity.hash;
|
|
538
|
+
storeKey = identity.key;
|
|
539
|
+
buildFailure = {
|
|
540
|
+
...buildFailure,
|
|
541
|
+
fingerprint: storeHash,
|
|
542
|
+
cacheKey: storeKey
|
|
543
|
+
};
|
|
544
|
+
const late = useBuildCache ? await recipe.cache().resolve({
|
|
545
|
+
...cacheTarget(storeKey),
|
|
546
|
+
destinationDir: providerDownloadPath(workspaceDir(root))
|
|
547
|
+
}) : null;
|
|
548
|
+
if (late) {
|
|
549
|
+
const prepared = await installableCachedApp(late);
|
|
550
|
+
if (prepared) {
|
|
551
|
+
appPath = prepared;
|
|
552
|
+
cacheHit = "local";
|
|
553
|
+
lateHit();
|
|
554
|
+
phase("cache", `hit ${shortHash(storeHash)} (post-${mutationLabel} key)`);
|
|
555
|
+
if (releasedWait) {
|
|
556
|
+
waitedForBuild = releasedWait.facts;
|
|
557
|
+
phase("build", `waited ${formatDuration(waitedForBuild.ms)} for ${releasedWait.who}'s build -> installed from cache -- stim guide lifecycle concurrency`);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return appPath ? { ready: appPath } : null;
|
|
563
|
+
}
|
|
564
|
+
async function acquireRemoteArtifact(offload, { rekeyedBy }) {
|
|
565
|
+
explainMiss(rekeyedBy);
|
|
566
|
+
step("compile");
|
|
567
|
+
if (!storeKey) fallBack("no cache key to store the app under", "offload failed: no cache key to store the app under");
|
|
568
|
+
const choice = storeKey ? await chooseMachine(offload) : null;
|
|
569
|
+
if (choice) await compileElsewhere({
|
|
570
|
+
choice,
|
|
571
|
+
candidate: offload
|
|
572
|
+
});
|
|
573
|
+
return appPath ? { ready: appPath } : null;
|
|
574
|
+
}
|
|
575
|
+
async function compileHere(offload, { rekeyedBy }) {
|
|
576
|
+
if (!offload) explainMiss(rekeyedBy);
|
|
577
|
+
step("compile");
|
|
578
|
+
if (offload) stats.setPlacement({
|
|
579
|
+
decision: "fell-back",
|
|
580
|
+
slotWaitMs,
|
|
581
|
+
deviceSlotWaitMs: stats.deviceSlotWaitMs(),
|
|
582
|
+
reason: offloadFallback ?? "offload failed",
|
|
583
|
+
...fallbackMachine ? { machine: fallbackMachine } : {}
|
|
584
|
+
});
|
|
585
|
+
else stats.setPlacement({
|
|
586
|
+
decision: "here",
|
|
587
|
+
reason: hereReason,
|
|
588
|
+
slotWaitMs,
|
|
589
|
+
deviceSlotWaitMs: stats.deviceSlotWaitMs()
|
|
590
|
+
});
|
|
591
|
+
requireLocalBuild(buildMachine);
|
|
592
|
+
builtOn = "here";
|
|
593
|
+
buildFailure = {
|
|
594
|
+
...buildFailure,
|
|
595
|
+
builtOn
|
|
596
|
+
};
|
|
597
|
+
phase("build", `compiling ${configuration || "Debug"} with xcodebuild`);
|
|
598
|
+
const result = await recipe.compile();
|
|
599
|
+
compilationCache = result.compilationCache;
|
|
600
|
+
phase("cache", `compilation cache ${compilationCacheActivityLine(compilationCache)}`);
|
|
601
|
+
if (!result.ok) {
|
|
602
|
+
phase("build", `FAILED after ${formatDuration(result.durationMs)}`);
|
|
603
|
+
printDiagnostics(note, result);
|
|
604
|
+
const report = xcodeFailureReport(result, logFile);
|
|
605
|
+
fail({
|
|
606
|
+
code: result.code,
|
|
607
|
+
message: report.message,
|
|
608
|
+
remedy: report.remedy,
|
|
609
|
+
logPath: logFile,
|
|
610
|
+
build: {
|
|
611
|
+
...buildFailure,
|
|
612
|
+
diagnostics: result.diagnostics
|
|
613
|
+
}
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
stats.setBuildMs(result.durationMs);
|
|
617
|
+
phase("build", `ok (${formatDuration(result.durationMs)})`);
|
|
618
|
+
appPath = result.appPath;
|
|
619
|
+
bundleId = result.bundleId;
|
|
620
|
+
return appPath;
|
|
621
|
+
}
|
|
622
|
+
async function storeArtifact(artifactPath) {
|
|
623
|
+
if (storeKey && cachePolicy.write) try {
|
|
624
|
+
const stored = await storeTieredBuild({
|
|
625
|
+
local: recipe.cache(),
|
|
626
|
+
loadProvider,
|
|
627
|
+
target: {
|
|
628
|
+
projectRoot: root,
|
|
629
|
+
platform: "ios",
|
|
630
|
+
key: storeKey
|
|
631
|
+
},
|
|
632
|
+
sourcePath: artifactPath,
|
|
633
|
+
overwrite: !useBuildCache || swapFellBack,
|
|
634
|
+
warn: cacheWarn
|
|
635
|
+
});
|
|
636
|
+
providerUpload = stored.providerUpload;
|
|
637
|
+
providerName = stored.providerName ?? providerName;
|
|
638
|
+
} catch (e) {
|
|
639
|
+
note(chalk.yellow(`Could not store the build in the shared cache: ${e?.message || e}`));
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
async function finishArtifact(artifactPath) {
|
|
643
|
+
let installPath = artifactPath;
|
|
644
|
+
const prepared = await recipe.materialize(installPath, {
|
|
645
|
+
fresh: true,
|
|
646
|
+
ownTemporary: (directory) => temporaryDirs.add(directory)
|
|
647
|
+
});
|
|
648
|
+
if (!prepared) fail({
|
|
649
|
+
code: "STIM_INSTALL_FAILED",
|
|
650
|
+
message: "The project integration could not prepare the built app for installation.",
|
|
651
|
+
remedy: "Check the artifact preparation details above, then retry.",
|
|
652
|
+
build: {
|
|
653
|
+
...buildFailure,
|
|
654
|
+
appPath: installPath
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
installPath = prepared;
|
|
658
|
+
if (remote && !physical && storeHash) uploadPending = d.uploadRemote({
|
|
659
|
+
logWriter: logWriter(),
|
|
660
|
+
provider: remote.provider,
|
|
661
|
+
platform: "ios",
|
|
662
|
+
projectRoot: root,
|
|
663
|
+
fingerprintHash: storeHash,
|
|
664
|
+
buildPath: installPath,
|
|
665
|
+
runOptions: recipe.legacyCache?.runOptions ?? null
|
|
666
|
+
});
|
|
667
|
+
return installPath;
|
|
668
|
+
}
|
|
669
|
+
let transferred = false;
|
|
670
|
+
try {
|
|
671
|
+
appPath = await runArtifactLifecycle({
|
|
672
|
+
resolve: async () => {
|
|
673
|
+
await resolveInitialFingerprint();
|
|
674
|
+
if (easBuild) return {
|
|
675
|
+
kind: "ready",
|
|
676
|
+
artifact: appPath
|
|
677
|
+
};
|
|
678
|
+
remote = await resolveRemoteArtifact();
|
|
679
|
+
if (appPath) return {
|
|
680
|
+
kind: "cached",
|
|
681
|
+
artifact: appPath
|
|
682
|
+
};
|
|
683
|
+
miss(reasonForMiss([]).reason);
|
|
684
|
+
return { kind: "miss" };
|
|
685
|
+
},
|
|
686
|
+
claim: useBuildCache ? async () => {
|
|
687
|
+
await awaitSharedBuild();
|
|
688
|
+
return appPath;
|
|
689
|
+
} : void 0,
|
|
690
|
+
reuse: async (cached) => {
|
|
691
|
+
appPath = await prepareCachedArtifact(cached);
|
|
692
|
+
if (appPath) lateHit();
|
|
693
|
+
else if (swapFellBack) miss(reasonForMiss([]).reason);
|
|
694
|
+
return appPath;
|
|
695
|
+
},
|
|
696
|
+
build: {
|
|
697
|
+
placement: {
|
|
698
|
+
select: () => {
|
|
699
|
+
buildFailure = {
|
|
700
|
+
fingerprint,
|
|
701
|
+
cacheKey,
|
|
702
|
+
cacheHit,
|
|
703
|
+
cacheSkipped: !useBuildCache,
|
|
704
|
+
buildMachine
|
|
705
|
+
};
|
|
706
|
+
return placeBuild();
|
|
707
|
+
},
|
|
708
|
+
acquire: acquireRemoteArtifact
|
|
709
|
+
},
|
|
710
|
+
admit: takeBuildSlot,
|
|
711
|
+
prepare: prepareSource,
|
|
712
|
+
revalidate: revalidateSource,
|
|
713
|
+
compile: compileHere,
|
|
714
|
+
validate: async () => {
|
|
715
|
+
await settleStoreKeyAfterCompile();
|
|
716
|
+
return storeKey ? "cacheable" : "uncacheable";
|
|
717
|
+
},
|
|
718
|
+
store: storeArtifact,
|
|
719
|
+
finish: finishArtifact
|
|
720
|
+
},
|
|
721
|
+
release: () => {
|
|
722
|
+
if (openOffload.choice) closeOffload(openOffload.choice);
|
|
723
|
+
releaseLock();
|
|
724
|
+
releaseSlot();
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
const artifact = {
|
|
728
|
+
handoff,
|
|
729
|
+
path: appPath,
|
|
730
|
+
bundleId,
|
|
731
|
+
cache: {
|
|
732
|
+
identity: storeHash && storeKey ? {
|
|
733
|
+
fingerprint: storeHash,
|
|
734
|
+
key: storeKey
|
|
735
|
+
} : null,
|
|
736
|
+
hit: cacheHit,
|
|
737
|
+
providerName: remote?.name ?? providerName,
|
|
738
|
+
buildMachine,
|
|
739
|
+
...builtOn ? { builtOn } : {},
|
|
740
|
+
offloadedTo,
|
|
741
|
+
offloadFallback: offloadedTo ? null : offloadFallback,
|
|
742
|
+
readEnabled: useBuildCache,
|
|
743
|
+
missReason: cacheHit ? null : missReason,
|
|
744
|
+
waitedForBuild,
|
|
745
|
+
compilation: compilationCache
|
|
746
|
+
},
|
|
747
|
+
failureFields: {
|
|
748
|
+
...buildFailure,
|
|
749
|
+
buildMachine,
|
|
750
|
+
...builtOn ? { builtOn } : {},
|
|
751
|
+
fingerprint: storeHash,
|
|
752
|
+
cacheKey: storeKey,
|
|
753
|
+
cacheHit,
|
|
754
|
+
cacheSkipped: !useBuildCache
|
|
755
|
+
},
|
|
756
|
+
completeUploads: async () => {
|
|
757
|
+
const uploadWasAbandoned = await finishIosUpload(uploadPending, remote, phase, note);
|
|
758
|
+
const outcome = providerUploadOutcome(providerUpload ? await providerUpload : null, providerName);
|
|
759
|
+
if (outcome) {
|
|
760
|
+
if (outcome.warn) note(chalk.yellow(phaseLine("cache", outcome.line)));
|
|
761
|
+
else phase("cache", outcome.line);
|
|
762
|
+
}
|
|
763
|
+
return abandonedRemote || uploadWasAbandoned;
|
|
764
|
+
},
|
|
765
|
+
release: releaseArtifact
|
|
766
|
+
};
|
|
767
|
+
transferred = true;
|
|
768
|
+
return {
|
|
769
|
+
ok: true,
|
|
770
|
+
artifact
|
|
771
|
+
};
|
|
772
|
+
} catch (error) {
|
|
773
|
+
if (error instanceof OffloadRefusal) {
|
|
774
|
+
const refusal = error;
|
|
775
|
+
return {
|
|
776
|
+
ok: false,
|
|
777
|
+
failure: {
|
|
778
|
+
code: refusal.code,
|
|
779
|
+
message: refusal.message,
|
|
780
|
+
remedy: refusal.remedy,
|
|
781
|
+
build: {
|
|
782
|
+
...buildFailure,
|
|
783
|
+
buildMachine,
|
|
784
|
+
...builtOn ? { builtOn } : {}
|
|
785
|
+
}
|
|
786
|
+
},
|
|
787
|
+
compilationCache
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
if (error instanceof IosRecipeRefusal) return {
|
|
791
|
+
ok: false,
|
|
792
|
+
failure: {
|
|
793
|
+
...error.failure,
|
|
794
|
+
build: {
|
|
795
|
+
...buildFailure,
|
|
796
|
+
...error.failure.build
|
|
797
|
+
}
|
|
798
|
+
},
|
|
799
|
+
compilationCache
|
|
800
|
+
};
|
|
801
|
+
throw error;
|
|
802
|
+
} finally {
|
|
803
|
+
if (!transferred) releaseArtifact();
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
//#endregion
|
|
807
|
+
export { acquireIosArtifact as t };
|