stim 1.20.2 → 1.22.0
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 +141 -8
- package/dist/acquire-artifact-Co2k4f7O.mjs +171 -0
- package/dist/act-DsuqEkiM.mjs +2801 -0
- package/dist/activity-CMLmzp7o.mjs +1397 -0
- package/dist/{agent-device-usage-output-Dzgv6lgR.mjs → agent-device-usage-output-DUFaTMdd.mjs} +23 -67
- package/dist/{android-DCKZrNvV.mjs → android-ByRMUoiJ.mjs} +157 -93
- package/dist/{android-Mz_Inn3w.mjs → android-C7sVmyI9.mjs} +299 -116
- package/dist/{android-Dlzxshgp.mjs → android-DGkNqa_c.mjs} +5 -5
- package/dist/{android-HqP1_vB_.mjs → android-DR5lZ2Az.mjs} +2 -2
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/{android-cas-Bl-cLJBk.mjs → android-cas-ngferVq2.mjs} +7 -6
- package/dist/android-project-BCAAmMwz.mjs +12 -0
- package/dist/android-project-DVWyCbWU.d.mts +391 -0
- package/dist/api.d.mts +810 -64
- package/dist/api.mjs +782 -1
- package/dist/{artifact-HSwkIWEQ.mjs → artifact-8EY8SAPw.mjs} +240 -213
- package/dist/{artifact-D3czlUvT.mjs → artifact-DJPy518Y.mjs} +203 -164
- package/dist/artifact-platform-CXcmX_j3.mjs +27 -0
- package/dist/{browser-web-CA-F1GQo.mjs → browser-web-Bcv99PBM.mjs} +194 -64
- package/dist/budget-Cvwn54qV.mjs +9285 -0
- package/dist/{build-DYDbfkk5.mjs → build-CabC3G23.mjs} +153 -98
- package/dist/build-cache-Dv7RN200.mjs +602 -0
- package/dist/build-plan-DUC8Ka9y.mjs +248 -0
- package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DSeQjt-Q.mjs} +2 -2
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{ccache-zdKiYQ3E.mjs → ccache-Btwc36-I.mjs} +10 -9
- package/dist/{cdp-Dq_ypAlJ.mjs → cdp-3fwICjzi.mjs} +18 -5
- package/dist/{chrome-BnzZMqsR.mjs → chrome-Bbw689-6.mjs} +7 -4
- package/dist/{cli-CLP3diBm.mjs → cli-CHZa9Lvk.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/client-OyRoEuSr.mjs +1577 -0
- package/dist/collector-run.d.mts +4 -40
- package/dist/collector-run.mjs +9 -8
- package/dist/{command-output-BTy8hZ0F.mjs → command-output-gwpm28fu.mjs} +1 -1
- package/dist/config-DlrsduwG.mjs +955 -0
- package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-x9rN6bhs.mjs} +14 -4
- package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-1I9KZT1Y.mjs} +20 -5
- package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-BwNEtIrP.mjs} +1 -1
- package/dist/{dev-client-DAWVIGBu.mjs → dev-client-BSDR5h3F.mjs} +2 -2
- package/dist/{device-BECOiufl.mjs → device-B-L3Fbxy.mjs} +91 -34
- package/dist/device-DklWZLqb.mjs +1068 -0
- package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-DK5_EwRS.mjs} +42 -13
- package/dist/device-host-worker.mjs +76 -79
- package/dist/{device-ios-COSi6oS1.mjs → device-ios-DoB6KFCO.mjs} +77 -51
- package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-xJPQ_QQG.mjs} +14 -26
- package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-BMkdsefq.mjs} +5 -5
- package/dist/{doctor-kfMBnUw6.mjs → doctor-Bo7BXLux.mjs} +271 -320
- package/dist/{doctor-CB8oZKCk.mjs → doctor-D5_EzwfA.mjs} +186 -91
- package/dist/doctor-fingerprint-DZLoYFVb.mjs +16 -0
- package/dist/doctor-fingerprint.mjs +19 -0
- package/dist/doctor-thjWAV0z.mjs +2 -0
- package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-N2wDotwQ.mjs} +40 -21
- package/dist/{eas-build-JyfqyHfC.mjs → eas-build-CwknaQYj.mjs} +53 -20
- package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-CSgAulr5.mjs} +41 -214
- package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-DlY_serQ.mjs} +230 -11
- package/dist/{error-diagnostics-BR677IDM.mjs → error-diagnostics-DBWO2rxE.mjs} +172 -82
- package/dist/exec-DEoAhcze.mjs +858 -0
- package/dist/exec-DnYc4HGH.d.mts +78 -0
- package/dist/{gc-qWOMdnER.mjs → gc-CXxN-4SE.mjs} +1091 -1029
- package/dist/gc-DnNDQyaP.mjs +3 -0
- package/dist/{guide-G9cAbVAc.mjs → guide-Br0LEfKy.mjs} +1165 -297
- package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-B-9f-jkd.mjs} +10 -8
- package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DZAPrcro.mjs} +34 -19
- package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CsCS21hn.mjs} +1 -1
- package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-FIRx9X2f.mjs} +77 -43
- package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-_awYSpfv.mjs} +35 -22
- package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-BdzE668-.mjs} +49 -27
- package/dist/idle-C4cZ757K.d.mts +24 -0
- package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DDg3SdvY.mjs} +11 -10
- package/dist/ios-CDvlmUs7.d.mts +24 -0
- package/dist/{ios-BwVCF7oA.mjs → ios-Ds1clbIt.mjs} +8 -8
- package/dist/{ios-device-D7pi2Sca.mjs → ios-device--h_-8ENa.mjs} +51 -26
- package/dist/{ios-device-B5veSDDQ.mjs → ios-device-BXZ0c7Kb.mjs} +1 -1
- package/dist/{ios-RkW4pnQf.mjs → ios-hcBpnEGk.mjs} +200 -93
- package/dist/{ios-Ce7bc7br.mjs → ios-pm4nL6By.mjs} +160 -108
- package/dist/{ios-project-K9hY_Jab.mjs → ios-project-CZhKODF3.mjs} +13 -13
- package/dist/ios-signing-BtAffm0A.mjs +489 -0
- package/dist/{ios-state-CBLe1xYw.mjs → ios-state-Dtw5K2aI.mjs} +1 -1
- package/dist/{ios-nOLJGVdy.mjs → ios-xtlRHaeB.mjs} +1 -1
- package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Bwhh4S7V.mjs} +30 -25
- package/dist/{launch-C3qJ6Agb.mjs → launch-BjxemNpK.mjs} +85 -543
- package/dist/{launch-F4sOqAhB.mjs → launch-CCzXlc8r.mjs} +91 -90
- package/dist/logs-BfwwadsZ.mjs +479 -0
- package/dist/logs-jTS_lHSo.mjs +248 -0
- package/dist/{macos-D7uDvO-z.mjs → macos-DVlSSyUg.mjs} +1 -1
- package/dist/macos-NfV2D7dO.mjs +694 -0
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +123 -248
- package/dist/{metro-DnCEjCxs.mjs → metro-DiXtA3Ty.mjs} +107 -30
- package/dist/metro-gateway-CKZqKqx7.mjs +209 -0
- package/dist/{named-ports-4WopRPg-.mjs → named-ports-DkEzOfzO.mjs} +42 -90
- package/dist/native-android-CqgnOgsT.mjs +645 -0
- package/dist/native-gradle-artifact-inputs-DHFnmrVf.mjs +270 -0
- package/dist/native-gradle-inputs-Dnh84Zbd.mjs +211 -0
- package/dist/native-inputs-TRTTTRxt.mjs +91 -0
- package/dist/native-run-NwUuxbkg.mjs +276 -0
- package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-B7KIafpM.mjs} +11 -9
- package/dist/native-source-Y0yLhFyQ.mjs +133 -0
- package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-D_VOfFL7.mjs} +26 -18
- package/dist/{native-xcode-ios-Bbf30Gm0.mjs → native-xcode-ios-BYDOHWLN.mjs} +104 -60
- package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
- package/dist/offload-worker.d.mts +59 -41
- package/dist/offload-worker.mjs +478 -115
- package/dist/operation-exec-BW0em61G.mjs +171 -0
- package/dist/{ownership-DCtw_2IA.mjs → ownership-C5fo5Edb.mjs} +3 -3
- package/dist/{page-DRHy329N.mjs → page-DBL2PiUU.mjs} +12 -5
- package/dist/paths-BsJMoPP2.mjs +12 -0
- package/dist/paths-DQtTgsBf.mjs +42 -0
- package/dist/{placement-log-MOfPVgaM.mjs → placement-log-BnGgJRRZ.mjs} +5 -5
- package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-DIsMtN-d.mjs} +15 -11
- package/dist/{ports-DdSUicVo.mjs → ports-Cy1RkmuQ.mjs} +3 -3
- package/dist/prebuild-D4JoEAEs.mjs +484 -0
- package/dist/{project-_phNIJfs.mjs → project-wM_XFTvE.mjs} +65 -37
- package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-W1IuLXDt.mjs} +102 -20
- package/dist/pull-request-eODyIqZF.d.mts +124 -0
- package/dist/pull-requests.d.mts +2 -120
- package/dist/pull-requests.mjs +2 -2
- package/dist/{react-native-android-CM1XRDwv.mjs → react-native-android-6OZ7MSM7.mjs} +121 -72
- package/dist/{gradle-DSrXb6lG.mjs → react-native-build-Dvd8hC21.mjs} +292 -15
- package/dist/react-native-doctor-DsoSF1Y9.mjs +234 -0
- package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-4u1Rn-GR.mjs} +71 -39
- package/dist/{recordings-D0d5aQt0.mjs → recordings-CQmfzAh7.mjs} +12 -9
- package/dist/registration-BcRgF6Ox.mjs +51 -0
- package/dist/{reload-C8JhxjSh.mjs → reload-BzkYabB-.mjs} +94 -47
- package/dist/reload-D7AVlb8N.mjs +2 -0
- package/dist/{remote-BiR6aYjy.mjs → remote-DjGDmlTZ.mjs} +26 -18
- package/dist/result-D2Ykz_iD.mjs +435 -0
- package/dist/{run-BtPgpKks.mjs → run-DidHghD1.mjs} +5 -5
- package/dist/selection-DSMbWEX2.mjs +620 -0
- package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CafzuyFB.mjs} +3 -4
- package/dist/{server-command-CTtCkmcQ.mjs → server-command-C6QjeupS.mjs} +14 -7
- package/dist/{server-expo-DsguMGUF.mjs → server-expo-CrjB29pq.mjs} +54 -11
- package/dist/server-expo-D58c9L0M.mjs +2 -0
- package/dist/{settings-B717odTD.mjs → settings-C7O8A6ZI.mjs} +309 -119
- package/dist/settings-DpR-1Wnn.mjs +114 -0
- package/dist/settings-write-CzD60rOD.mjs +360 -0
- package/dist/settings.schema.json +176 -16
- package/dist/{simslim-CCr3rE-A.mjs → simslim-BNckWpXi.mjs} +14 -12
- package/dist/{slot-launch-DPt0m9Nd.mjs → slot-launch-CbfmNgM6.mjs} +15 -20
- package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
- package/dist/stage-Bps5oius.mjs +200 -0
- package/dist/{start-TXeMmmO2.mjs → start-Br-oxqMD.mjs} +1 -1
- package/dist/start-EojN4WFz.mjs +1364 -0
- package/dist/{state-D1Icyjlu.mjs → state--smjFSTL.mjs} +55 -13
- package/dist/{state-CG_OFoaA.mjs → state-08I3hw3_.mjs} +3 -2
- package/dist/{stats-BoY5sEPU.mjs → stats-D3GerlFW.mjs} +7 -13
- package/dist/stats-report-BzaPrRm6.mjs +16 -0
- package/dist/{status-BTA7kKiQ.mjs → status-BRROykC8.mjs} +7 -5
- package/dist/status-EvrK72L2.mjs +2 -0
- package/dist/{status-WgFbkRzj.mjs → status-WBDajew2.mjs} +554 -452
- package/dist/{status-watch-C23ILtf9.mjs → status-watch-Bg_u-pwR.mjs} +222 -25
- package/dist/status-worker.d.mts +1 -0
- package/dist/status-worker.mjs +19 -0
- package/dist/stim-desktop-D5OGpYZM.mjs +112 -0
- package/dist/{stop-DR6VoDIk.mjs → stop-DTZ9uTw3.mjs} +2 -2
- package/dist/{stop-DPEhunlw.mjs → stop-Dky10AEJ.mjs} +33 -23
- package/dist/{stop-BNmBMi1F.mjs → stop-Mv6W9FAk.mjs} +137 -98
- package/dist/supervisor-run.d.mts +8 -17
- package/dist/supervisor-run.mjs +56 -28
- package/dist/{support-CwjbFs9H.mjs → support-CNioewsd.mjs} +14 -14
- package/dist/{support-DMTqj3Hm.mjs → support-yUiOjnVY.mjs} +20 -13
- package/dist/swiftpm-artifact-inputs-DFcGsXDP.mjs +153 -0
- package/dist/swiftpm-macos-BIak-Rxv.mjs +532 -0
- package/dist/toolchain-BY8X8HXx.mjs +2 -0
- package/dist/toolchain-DpJMHq0n.mjs +876 -0
- package/dist/{trigger-CigAYjeL.mjs → trigger-Cbyc41d_.mjs} +21 -6
- package/dist/trigger-yb_nFzPF.mjs +2 -0
- package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-CA3TgT3-.mjs} +263 -156
- package/dist/web-CZ07gd77.mjs +2 -0
- package/dist/{web-BDBMxDpx.mjs → web-DKx6yoFA.mjs} +20 -14
- package/dist/web-run.mjs +13 -12
- package/dist/windows-report.d.mts +1 -0
- package/dist/windows-report.mjs +18 -0
- package/dist/windows-report.ps1 +43 -0
- package/dist/{workspace-state-DJt_MMvf.mjs → workspace-state-U08dEzhG.mjs} +62 -58
- package/dist/{workspaces-C36s2jb9.mjs → workspaces-CpANmBlq.mjs} +1723 -1286
- package/dist/{worktree-CgvJYJ-Q.mjs → worktree-CHecZ4Oq.mjs} +1097 -547
- package/dist/worktree-ZqZVjD9K.mjs +2 -0
- package/dist/xcode-BXn9-xYx.mjs +896 -0
- package/package.json +7 -5
- package/shim/android-audio/Main.java +24 -0
- package/shim/android-audio/README.md +17 -0
- package/shim/android-audio.jar +0 -0
- package/shim/android-optimizations.gradle +7 -5
- package/dist/activity-BSV745Kz.mjs +0 -629
- package/dist/api-qvOzWyfO.mjs +0 -154
- package/dist/api-run.mjs +0 -294
- package/dist/app-install-BIKtMfPq.mjs +0 -896
- package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
- package/dist/budget-f7516Zk0.mjs +0 -4106
- package/dist/build-facts-DcLv2HSd.d.mts +0 -111
- package/dist/cancellation-C_22VQTH.mjs +0 -24
- package/dist/client-qQAaXSUs.mjs +0 -1771
- package/dist/config-BYDxlMY3.mjs +0 -562
- package/dist/device-DuiPJQSn.mjs +0 -290
- package/dist/device-lease-BX1sJQ2E.mjs +0 -1224
- package/dist/device-remote-xRT0Vmo9.mjs +0 -1272
- package/dist/eas-session-ledger-Cm0Gwq2F.mjs +0 -207
- package/dist/exec-DqKo9GKJ.mjs +0 -268
- package/dist/git-DDfFzkMm.mjs +0 -45
- package/dist/launch-verify-B6Q8hZP-.mjs +0 -428
- package/dist/logs-BGrEUaEs.mjs +0 -383
- package/dist/macos-Ch5VJmcS.mjs +0 -584
- package/dist/metro-gateway-CX9Xlkq2.mjs +0 -103
- package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
- package/dist/native-android-D5qc3-_v.mjs +0 -226
- package/dist/native-gradle-inputs-BsLRrl7u.mjs +0 -349
- package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
- package/dist/plan-C4TjdPsR.mjs +0 -260
- package/dist/prebuild-DYbucPXy.mjs +0 -212
- package/dist/preview-78a9kR_-.mjs +0 -1011
- package/dist/react-native-build-CtCccJtb.mjs +0 -239
- package/dist/react-native-doctor-CfRnFfjs.mjs +0 -78
- package/dist/remote-cache-OyOyVIS3.mjs +0 -526
- package/dist/result-CaJg5Iat.mjs +0 -186
- package/dist/server-expo-Bigriskl.mjs +0 -2
- package/dist/settings-BORNaaCO.mjs +0 -402
- package/dist/settings-vk3mJGSm.d.mts +0 -13
- package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
- package/dist/stage-KNTQopqv.mjs +0 -157
- package/dist/start-BWqzODpb.mjs +0 -1116
- package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
- package/dist/swiftpm-macos-DRNVJWlb.mjs +0 -119
- package/dist/tailnet-Dh-qiYzG.mjs +0 -265
- package/dist/toolchain-BFkAcstd.mjs +0 -2
- package/dist/toolchain-DxSsNssu.mjs +0 -1657
- package/dist/trigger-9_USgmxz.mjs +0 -2
- package/dist/web-Dq-i3wzJ.mjs +0 -2
- package/dist/worktree-DpLdCHga.mjs +0 -2
- package/dist/{api-run.d.mts → doctor-fingerprint.d.mts} +0 -0
- package/dist/{errors-DzkMYh8Q.mjs → errors-ccaPc4ox.mjs} +2 -2
package/dist/offload-worker.mjs
CHANGED
|
@@ -1,26 +1,200 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { d as androidLayoutSetting, y as iosProjectDirSetting } from "./settings-B717odTD.mjs";
|
|
5
|
-
import { D as fingerprintProject, M as refingerprintAfterMutation } from "./device-lease-BX1sJQ2E.mjs";
|
|
6
|
-
import { w as workspaceLogsDir, x as workspaceDir } from "./workspace-state-DJt_MMvf.mjs";
|
|
1
|
+
import { t as getExecutor } from "./exec-DEoAhcze.mjs";
|
|
2
|
+
import { d as workspaceDir, m as workspaceLogsDir$1 } from "./paths-DQtTgsBf.mjs";
|
|
3
|
+
import { k as writeConfigSetting } from "./config-DlrsduwG.mjs";
|
|
7
4
|
import { n as stripAnsi } from "./process-output-Fpl8PYi8.mjs";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { n as
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { t as
|
|
20
|
-
import { r as
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
5
|
+
import { o as git, s as gitAsync } from "./operation-exec-BW0em61G.mjs";
|
|
6
|
+
import { d as androidLayoutSetting, y as iosProjectDirSetting } from "./settings-C7O8A6ZI.mjs";
|
|
7
|
+
import { f as projectRegistry, g as selectNativeXcodeProject } from "./project-wM_XFTvE.mjs";
|
|
8
|
+
import { o as parseNdjsonText } from "./ndjson-CgE_o3Dl.mjs";
|
|
9
|
+
import { Fn as processContext } from "./budget-Cvwn54qV.mjs";
|
|
10
|
+
import { l as fingerprintProject, m as refingerprintAfterMutation } from "./build-cache-Dv7RN200.mjs";
|
|
11
|
+
import { n as CCACHE_UNAVAILABLE, o as resolveCcache } from "./ccache-Btwc36-I.mjs";
|
|
12
|
+
import { _ as clearCorruptCompilationCache, f as reactNativeArtifactReceipt, g as COMPILATION_CACHE_CORRUPT, m as reactNativeBuildQuery, p as reactNativeArtifactToolchain } from "./client-OyRoEuSr.mjs";
|
|
13
|
+
import { f as workerToolchain, h as readPodState, i as availableIphone, m as podsAreStale, v as runPodInstall } from "./toolchain-DpJMHq0n.mjs";
|
|
14
|
+
import { n as fingerprintNativeInputs, r as manifestDigest } from "./native-inputs-TRTTTRxt.mjs";
|
|
15
|
+
import { a as sourceManifest, o as verifyNativeTransfer } from "./native-source-Y0yLhFyQ.mjs";
|
|
16
|
+
import { i as nativeGradleOutputs, n as gradleStateDirectories, o as validateGradleManifest, s as verifyGradleTransfer, t as gradleOffloadInputs } from "./native-gradle-inputs-Dnh84Zbd.mjs";
|
|
17
|
+
import { n as buildAndroid, o as gradlewPath, r as buildIos, u as assembleTaskFor } from "./react-native-build-Dvd8hC21.mjs";
|
|
18
|
+
import { f as podAction } from "./support-CNioewsd.mjs";
|
|
19
|
+
import { i as runPrebuild, r as recordPrebuild, t as planPrebuild } from "./prebuild-D4JoEAEs.mjs";
|
|
20
|
+
import { g as dumpApkManifest, p as apkPackage } from "./support-yUiOjnVY.mjs";
|
|
21
|
+
import { n as buildAndroidOperation, t as buildIosOperation } from "./build-CabC3G23.mjs";
|
|
22
|
+
import { i as stageBundle, n as resolveBundleExtras } from "./stage-Bps5oius.mjs";
|
|
23
|
+
import { t as logLines } from "./run-DidHghD1.mjs";
|
|
24
|
+
import { r as nativeXcodeMetadataDirectories } from "./native-xcode-inputs-D_VOfFL7.mjs";
|
|
25
|
+
import { n as swiftpmArtifactInputs, r as swiftpmArtifactSnapshot, t as readSwiftpmArtifactToolchain } from "./swiftpm-artifact-inputs-DFcGsXDP.mjs";
|
|
26
|
+
import { a as nativeGradleWorkerArtifactIdentity, i as nativeGradleArtifactSnapshotFromReceipt, o as nativeGradleWorkerScope } from "./native-gradle-artifact-inputs-DHFnmrVf.mjs";
|
|
23
27
|
import { createHash } from "node:crypto";
|
|
28
|
+
import { chmodSync, constants, copyFileSync, cpSync, createReadStream, createWriteStream, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync } from "node:fs";
|
|
29
|
+
import { isDeepStrictEqual } from "node:util";
|
|
30
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
31
|
+
import { dependencyInstall, withAmbientContext } from "@stim-cli/core";
|
|
32
|
+
import { isJsonObject, windowsShortDir, windowsShortDirKey } from "@stim-cli/core/state";
|
|
33
|
+
import { realpath } from "node:fs/promises";
|
|
34
|
+
import { pipeline } from "node:stream/promises";
|
|
35
|
+
import { createGzip } from "node:zlib";
|
|
36
|
+
//#region src/offload/swiftpm-artifact.ts
|
|
37
|
+
async function readSwiftpmWorkerToolchain(context, cwd) {
|
|
38
|
+
const commandPath = async (name) => {
|
|
39
|
+
const path = getExecutor().findExecutable(name, {
|
|
40
|
+
cwd,
|
|
41
|
+
env: context.env
|
|
42
|
+
});
|
|
43
|
+
if (!path) throw new Error(`The SwiftPM tool ${name} is unavailable.`);
|
|
44
|
+
return realpath(path);
|
|
45
|
+
};
|
|
46
|
+
const [selected, xcrun, xcodebuild] = await Promise.all([
|
|
47
|
+
commandPath("swift"),
|
|
48
|
+
commandPath("xcrun"),
|
|
49
|
+
commandPath("xcodebuild")
|
|
50
|
+
]);
|
|
51
|
+
const compiler = await realpath(await getExecutor().runFileAsync("/usr/bin/xcrun", ["--find", "swift"], {
|
|
52
|
+
cwd,
|
|
53
|
+
timeoutMs: 3e4
|
|
54
|
+
}));
|
|
55
|
+
const sdk = await realpath(context.env.SDKROOT ?? context.env.SWIFTPM_SDKROOT_macosx ?? await getExecutor().runFileAsync("/usr/bin/xcrun", [
|
|
56
|
+
"--sdk",
|
|
57
|
+
"macosx",
|
|
58
|
+
"--show-sdk-path"
|
|
59
|
+
], {
|
|
60
|
+
cwd,
|
|
61
|
+
timeoutMs: 3e4
|
|
62
|
+
}));
|
|
63
|
+
const overrides = {};
|
|
64
|
+
for (const variable of ["SWIFT_EXEC", "SWIFT_EXEC_MANIFEST"]) {
|
|
65
|
+
const command = context.env[variable];
|
|
66
|
+
if (!command) continue;
|
|
67
|
+
const version = await getExecutor().runFileAsync(command, ["--version"], {
|
|
68
|
+
cwd,
|
|
69
|
+
timeoutMs: 3e4,
|
|
70
|
+
declareFor: context
|
|
71
|
+
});
|
|
72
|
+
if (!version.trim()) throw new Error(`The SwiftPM ${variable} compiler identity is unavailable.`);
|
|
73
|
+
overrides[variable] = {
|
|
74
|
+
command: await commandPath(command),
|
|
75
|
+
version
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const checkoutRequired = Object.keys(overrides).length > 0 || selected !== await realpath("/usr/bin/swift") && selected !== compiler || xcrun !== await realpath("/usr/bin/xcrun") || xcodebuild !== await realpath("/usr/bin/xcodebuild");
|
|
79
|
+
return {
|
|
80
|
+
...await readSwiftpmArtifactToolchain(context, void 0, cwd),
|
|
81
|
+
selection: {
|
|
82
|
+
command: selected,
|
|
83
|
+
compiler,
|
|
84
|
+
sdk,
|
|
85
|
+
xcrun,
|
|
86
|
+
xcodebuild,
|
|
87
|
+
overrides,
|
|
88
|
+
checkoutRequired
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
async function privateSnapshot(root, query, privateLockfile, toolchain, env, signal) {
|
|
93
|
+
const repository = resolve(root, ...query.project.split("/").filter(Boolean).map(() => ".."));
|
|
94
|
+
const declaration = swiftpmArtifactInputs(query.inputs);
|
|
95
|
+
return (await fingerprintNativeInputs([
|
|
96
|
+
...declaration.ignored.map((path) => ({
|
|
97
|
+
name: `ignored/${path}`,
|
|
98
|
+
path: join(repository, path)
|
|
99
|
+
})),
|
|
100
|
+
...declaration.localFiles.map((path, index) => ({
|
|
101
|
+
name: `local/${index}`,
|
|
102
|
+
path: resolve(root, path),
|
|
103
|
+
optional: true
|
|
104
|
+
})),
|
|
105
|
+
...privateLockfile ? [{
|
|
106
|
+
name: "package-resolved",
|
|
107
|
+
path: join(root, "Package.resolved"),
|
|
108
|
+
optional: true
|
|
109
|
+
}] : []
|
|
110
|
+
], {
|
|
111
|
+
parameters: {
|
|
112
|
+
toolchain,
|
|
113
|
+
environment: Object.fromEntries([.../* @__PURE__ */ new Set([
|
|
114
|
+
...declaration.environment,
|
|
115
|
+
"DEVELOPER_DIR",
|
|
116
|
+
"TOOLCHAINS",
|
|
117
|
+
"SDKROOT",
|
|
118
|
+
"SWIFT_EXEC",
|
|
119
|
+
"MACOSX_DEPLOYMENT_TARGET"
|
|
120
|
+
])].toSorted().map((name) => [name, env[name] ?? null]))
|
|
121
|
+
},
|
|
122
|
+
signal
|
|
123
|
+
})).hash;
|
|
124
|
+
}
|
|
125
|
+
/** Certifies actual worker inputs, not the client's transfer digest or cache identity. */
|
|
126
|
+
async function swiftpmWorkerArtifactSnapshot(root, query, toolchain, env, signal) {
|
|
127
|
+
signal?.throwIfAborted();
|
|
128
|
+
root = await realpath(root);
|
|
129
|
+
const repository = await realpath(await gitAsync(root, ["rev-parse", "--show-toplevel"], { signal }));
|
|
130
|
+
const project = relative(repository, await realpath(root)).split(sep).join("/");
|
|
131
|
+
const visible = await sourceManifest(repository, true, signal);
|
|
132
|
+
if (query.project !== project || manifestDigest(visible) !== query.sourceDigest) throw new Error("The SwiftPM worker source does not match its completed transfer.");
|
|
133
|
+
const declaration = swiftpmArtifactInputs(query.inputs);
|
|
134
|
+
const build = {
|
|
135
|
+
...query.build,
|
|
136
|
+
resources: Object.fromEntries(Object.entries(query.build.resources).map(([name, path]) => [name, relative(root, resolve(repository, path))])),
|
|
137
|
+
assetCatalog: query.build.assetCatalog ? relative(root, resolve(repository, query.build.assetCatalog)) : null
|
|
138
|
+
};
|
|
139
|
+
const snapshot = await swiftpmArtifactSnapshot(root, declaration, build, {
|
|
140
|
+
swift: toolchain.swift,
|
|
141
|
+
sdk: toolchain.sdk,
|
|
142
|
+
xcode: toolchain.xcode,
|
|
143
|
+
arch: toolchain.arch
|
|
144
|
+
}, env, signal);
|
|
145
|
+
const sourcePaths = new Set(visible.map((file) => file.path));
|
|
146
|
+
const privatePaths = /* @__PURE__ */ new Set([...declaration.ignored.map((path) => resolve(repository, path)), ...declaration.localFiles.map((path) => resolve(root, path))]);
|
|
147
|
+
for (const path of [
|
|
148
|
+
build.infoPlist,
|
|
149
|
+
...Object.values(build.resources),
|
|
150
|
+
build.assetCatalog
|
|
151
|
+
]) {
|
|
152
|
+
if (path === null) continue;
|
|
153
|
+
const absolute = resolve(root, path);
|
|
154
|
+
const bundled = await fingerprintNativeInputs([{
|
|
155
|
+
name: "bundle",
|
|
156
|
+
path: absolute
|
|
157
|
+
}], {
|
|
158
|
+
parameters: null,
|
|
159
|
+
signal
|
|
160
|
+
});
|
|
161
|
+
for (const entry of bundled.entries) {
|
|
162
|
+
if (entry.kind === "directory") continue;
|
|
163
|
+
const file = join(absolute, entry.path === "bundle" ? "" : entry.path.slice(7));
|
|
164
|
+
const name = relative(repository, file).split(sep).join("/");
|
|
165
|
+
if (!entry.kind.startsWith("file:") || !sourcePaths.has(name) && !privatePaths.has(file)) throw new Error("SwiftPM peer caching requires every ignored bundle file in the private input declaration.");
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const privateLockfile = !sourcePaths.has([project, "Package.resolved"].filter(Boolean).join("/"));
|
|
169
|
+
const privateHash = await privateSnapshot(root, query, privateLockfile, toolchain, env, signal);
|
|
170
|
+
const hash = createHash("sha256").update(JSON.stringify([
|
|
171
|
+
"stim-swiftpm-worker-v1",
|
|
172
|
+
snapshot.hash,
|
|
173
|
+
query,
|
|
174
|
+
privateHash
|
|
175
|
+
])).digest("hex");
|
|
176
|
+
const identity = {
|
|
177
|
+
hash,
|
|
178
|
+
key: `swiftpm-peer-${hash}`
|
|
179
|
+
};
|
|
180
|
+
return {
|
|
181
|
+
identity,
|
|
182
|
+
receipt: {
|
|
183
|
+
query: structuredClone(query),
|
|
184
|
+
identity,
|
|
185
|
+
privateHash,
|
|
186
|
+
privateLockfile,
|
|
187
|
+
checkoutRequired: toolchain.selection.checkoutRequired
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/** Revalidates private inputs of a receipt bound to a verified completed source transfer. */
|
|
192
|
+
async function swiftpmArtifactFromReceipt(root, query, receipt, toolchain, env, signal) {
|
|
193
|
+
signal?.throwIfAborted();
|
|
194
|
+
if (!isDeepStrictEqual(query, receipt.query) || typeof receipt.checkoutRequired !== "boolean" || receipt.checkoutRequired !== toolchain.selection.checkoutRequired || !/^[a-f0-9]{64}$/.test(receipt.identity.hash) || receipt.identity.key !== `swiftpm-peer-${receipt.identity.hash}`) return null;
|
|
195
|
+
return await privateSnapshot(root, query, receipt.privateLockfile, toolchain, env, signal) === receipt.privateHash ? receipt.identity : null;
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
24
198
|
//#region src/offload/worker.ts
|
|
25
199
|
function emit(value) {
|
|
26
200
|
process.stdout.write(`${JSON.stringify(value)}\n`);
|
|
@@ -90,13 +264,85 @@ function ensureParents(root, path) {
|
|
|
90
264
|
mkdirSync(current);
|
|
91
265
|
}
|
|
92
266
|
}
|
|
93
|
-
|
|
267
|
+
const PRIVATE_DIRS = [
|
|
268
|
+
"$ErrorActionPreference = 'Stop'",
|
|
269
|
+
"$me = [Security.Principal.WindowsIdentity]::GetCurrent().User",
|
|
270
|
+
"$acl = New-Object Security.AccessControl.DirectorySecurity",
|
|
271
|
+
"$acl.SetAccessRuleProtection($true, $false)",
|
|
272
|
+
"foreach ($sid in @($me, (New-Object Security.Principal.SecurityIdentifier 'S-1-5-18'))) {",
|
|
273
|
+
" $acl.AddAccessRule((New-Object Security.AccessControl.FileSystemAccessRule($sid, 'FullControl', 'ContainerInherit,ObjectInherit', 'None', 'Allow')))",
|
|
274
|
+
"}",
|
|
275
|
+
"foreach ($line in [Console]::In.ReadToEnd().Split([char]10) | ForEach-Object { $_.Trim() } | Where-Object { $_ }) {",
|
|
276
|
+
" $dir, $key = $line.Split([char]9)",
|
|
277
|
+
" [void][IO.Directory]::CreateDirectory($dir, $acl)",
|
|
278
|
+
" $current = Get-Acl -LiteralPath $dir",
|
|
279
|
+
" $owner = $current.GetOwner([Security.Principal.SecurityIdentifier]).Value",
|
|
280
|
+
" if ($owner -notin @($me.Value, 'S-1-5-32-544', 'S-1-5-18')) { [Console]::Error.WriteLine(\"$dir is owned by $owner\"); exit 3 }",
|
|
281
|
+
" $foreign = $current.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier]) | Where-Object { $_.IdentityReference.Value -notin @($me.Value, 'S-1-5-18') }",
|
|
282
|
+
" if (-not $current.AreAccessRulesProtected -or $foreign) { Set-Acl -LiteralPath $dir -AclObject $acl }",
|
|
283
|
+
" if ($key) {",
|
|
284
|
+
" $marker = \"$dir.owner\"",
|
|
285
|
+
" if (-not (Test-Path -LiteralPath $marker)) { Set-Content -NoNewline -LiteralPath $marker -Value $key }",
|
|
286
|
+
" elseif ((Get-Content -Raw -LiteralPath $marker) -ne $key) { [Console]::Error.WriteLine(\"$dir belongs to another build area\"); exit 4 }",
|
|
287
|
+
" }",
|
|
288
|
+
"}"
|
|
289
|
+
].join("\n");
|
|
290
|
+
/**
|
|
291
|
+
* Creates each directory, in order, with access for this user and SYSTEM only, and gives an existing one that ACL.
|
|
292
|
+
* A directory at the drive root inherits the root's ACL, which lets every authenticated user modify it, so another
|
|
293
|
+
* account could plant code in a build; one that another account owns could hold such code, so it is refused. A
|
|
294
|
+
* directory with a key records it in `<dir>.owner` and is refused when another key is recorded there, since the
|
|
295
|
+
* short names of different areas can collide.
|
|
296
|
+
*/
|
|
297
|
+
function makePrivateWindowsDirs(dirs) {
|
|
298
|
+
try {
|
|
299
|
+
getExecutor().runFile("powershell.exe", [
|
|
300
|
+
"-NoProfile",
|
|
301
|
+
"-NonInteractive",
|
|
302
|
+
"-Command",
|
|
303
|
+
PRIVATE_DIRS
|
|
304
|
+
], {
|
|
305
|
+
input: dirs.map((entry) => entry.join(" ")).join("\n"),
|
|
306
|
+
timeoutMs: 6e4
|
|
307
|
+
});
|
|
308
|
+
} catch (error) {
|
|
309
|
+
const reason = (error instanceof Error ? error.message : String(error)).trim().split("\n").at(-1);
|
|
310
|
+
throw new Error(`Could not prepare the private Windows build directories: ${reason}`, { cause: error });
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Creates the checkout directory `src` of `area`. On Windows it is a junction to a private `windowsShortDir`, and the
|
|
315
|
+
* client's Gradle home is made private too; an area whose `src` is a directory keeps it.
|
|
316
|
+
*/
|
|
317
|
+
function ensureCheckout(area, src) {
|
|
318
|
+
const stat = lstatSync(src, { throwIfNoEntry: false });
|
|
319
|
+
if (process.platform === "win32") {
|
|
320
|
+
const linked = !stat || stat.isSymbolicLink();
|
|
321
|
+
const realArea = realpathSync(area);
|
|
322
|
+
const target = windowsShortDir(realArea);
|
|
323
|
+
const gradleHome = process.env.GRADLE_USER_HOME;
|
|
324
|
+
const dirs = [[dirname(target)]];
|
|
325
|
+
if (linked) dirs.push([target, windowsShortDirKey("checkout", realArea)]);
|
|
326
|
+
if (gradleHome) dirs.push([gradleHome, windowsShortDirKey("gradle", dirname(dirname(area)))]);
|
|
327
|
+
makePrivateWindowsDirs(dirs);
|
|
328
|
+
if (!linked) return;
|
|
329
|
+
let current = null;
|
|
330
|
+
try {
|
|
331
|
+
current = realpathSync(src);
|
|
332
|
+
} catch {}
|
|
333
|
+
if (current?.toLowerCase() === target.toLowerCase()) return;
|
|
334
|
+
if (stat) rmSync(src, { force: true });
|
|
335
|
+
symlinkSync(target, src, "junction");
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
mkdirSync(src, { recursive: true });
|
|
339
|
+
}
|
|
340
|
+
async function materialize(job, src) {
|
|
94
341
|
const recordFile = join(job.area, "mirror.json");
|
|
95
342
|
let previous = {};
|
|
96
343
|
try {
|
|
97
344
|
previous = JSON.parse(readFileSync(recordFile, "utf8"));
|
|
98
345
|
} catch {}
|
|
99
|
-
mkdirSync(src, { recursive: true });
|
|
100
346
|
if (!existsSync(join(src, ".git"))) {
|
|
101
347
|
git(src, ["init", "--quiet"], {
|
|
102
348
|
write: true,
|
|
@@ -126,7 +372,7 @@ function materialize(job, src) {
|
|
|
126
372
|
} catch {}
|
|
127
373
|
const allowed = [...declaration.outputs, ...gradleStateDirectories(job.project)];
|
|
128
374
|
if (receipt.project === job.project && Array.isArray(receipt.directories)) retained = allowed.filter((path) => receipt.directories.includes(path));
|
|
129
|
-
retained = nativeGradleOutputs(src, {
|
|
375
|
+
retained = await nativeGradleOutputs(src, {
|
|
130
376
|
complete: true,
|
|
131
377
|
ignored: [],
|
|
132
378
|
outputs: retained
|
|
@@ -238,42 +484,18 @@ function materialize(job, src) {
|
|
|
238
484
|
removed
|
|
239
485
|
};
|
|
240
486
|
}
|
|
241
|
-
function lockfileOf(src) {
|
|
242
|
-
if (existsSync(join(src, "pnpm-lock.yaml"))) return {
|
|
243
|
-
file: "pnpm-lock.yaml",
|
|
244
|
-
command: "pnpm",
|
|
245
|
-
args: (pkg) => [
|
|
246
|
-
"install",
|
|
247
|
-
"--frozen-lockfile",
|
|
248
|
-
...pkg ? ["--filter", `${pkg}...`] : []
|
|
249
|
-
]
|
|
250
|
-
};
|
|
251
|
-
if (existsSync(join(src, "yarn.lock"))) return {
|
|
252
|
-
file: "yarn.lock",
|
|
253
|
-
command: "yarn",
|
|
254
|
-
args: () => ["install", "--frozen-lockfile"]
|
|
255
|
-
};
|
|
256
|
-
if (existsSync(join(src, "package-lock.json"))) return {
|
|
257
|
-
file: "package-lock.json",
|
|
258
|
-
command: "npm",
|
|
259
|
-
args: () => ["ci"]
|
|
260
|
-
};
|
|
261
|
-
return null;
|
|
262
|
-
}
|
|
263
487
|
/** Installs JavaScript dependencies when the lockfile, or the install command, changed since the last install. */
|
|
264
488
|
async function ensureDependencies(job, src) {
|
|
265
|
-
const
|
|
266
|
-
if (!
|
|
267
|
-
const args =
|
|
268
|
-
const lockfile = readFileSync(join(src, lock.file));
|
|
269
|
-
const digest = createHash("sha256").update(lockfile).update(JSON.stringify(args)).digest("hex");
|
|
489
|
+
const install = dependencyInstall(src, job.packageName);
|
|
490
|
+
if (!install) return;
|
|
491
|
+
const { command, args, digest, lockfile } = install;
|
|
270
492
|
const marker = join(job.area, "dependencies");
|
|
271
|
-
const installed = () => writeFileSync(join(job.area, "lockfile"),
|
|
493
|
+
const installed = () => writeFileSync(join(job.area, "lockfile"), lockfile);
|
|
272
494
|
if (existsSync(join(src, job.project, "node_modules")) && existsSync(marker)) {
|
|
273
495
|
if (readFileSync(marker, "utf8") === digest) return installed();
|
|
274
496
|
}
|
|
275
|
-
note("deps", `${
|
|
276
|
-
const child = getExecutor().spawn(
|
|
497
|
+
note("deps", `${command} ${args.join(" ")}`);
|
|
498
|
+
const child = getExecutor().spawn(command, args, {
|
|
277
499
|
cwd: src,
|
|
278
500
|
env: {
|
|
279
501
|
...process.env,
|
|
@@ -296,7 +518,7 @@ async function ensureDependencies(job, src) {
|
|
|
296
518
|
child.on("error", reject);
|
|
297
519
|
child.on("exit", resolve);
|
|
298
520
|
});
|
|
299
|
-
if (code !== 0) throw new Error(`${
|
|
521
|
+
if (code !== 0) throw new Error(`${command} ${args.join(" ")} exited with ${code}: ${tail.join(" | ")}`);
|
|
300
522
|
writeFileSync(marker, digest);
|
|
301
523
|
installed();
|
|
302
524
|
}
|
|
@@ -312,12 +534,55 @@ function destination(runtime) {
|
|
|
312
534
|
"devices",
|
|
313
535
|
"available",
|
|
314
536
|
"-j"
|
|
315
|
-
], { timeoutMs: 2e4 }) ?? "{}").devices?.[runtime] ?? []).find(
|
|
537
|
+
], { timeoutMs: 2e4 }) ?? "{}").devices?.[runtime] ?? []).find(availableIphone);
|
|
316
538
|
return device ? `id=${device.udid}` : null;
|
|
317
539
|
} catch {
|
|
318
540
|
return null;
|
|
319
541
|
}
|
|
320
542
|
}
|
|
543
|
+
/**
|
|
544
|
+
* Writes `name` under `dir` to `archive` as a gzip tarball at compression level 1. Node does the gzip because tar's
|
|
545
|
+
* compression-level flags differ between bsdtar (macOS, Windows) and GNU tar (Linux).
|
|
546
|
+
*/
|
|
547
|
+
async function packArchive(archive, dir, name) {
|
|
548
|
+
const child = getExecutor().spawn("tar", [
|
|
549
|
+
"-cf",
|
|
550
|
+
"-",
|
|
551
|
+
"-C",
|
|
552
|
+
dir,
|
|
553
|
+
name
|
|
554
|
+
], { stdio: [
|
|
555
|
+
"ignore",
|
|
556
|
+
"pipe",
|
|
557
|
+
"pipe"
|
|
558
|
+
] });
|
|
559
|
+
const tarball = child.stdout;
|
|
560
|
+
if (!tarball) throw new Error("tar opened no output stream.");
|
|
561
|
+
const stderr = [];
|
|
562
|
+
child.stderr?.on("data", (chunk) => stderr.push(String(chunk)));
|
|
563
|
+
let spawnError = null;
|
|
564
|
+
const exited = new Promise((resolve) => {
|
|
565
|
+
child.once("error", (error) => {
|
|
566
|
+
spawnError = error;
|
|
567
|
+
resolve(null);
|
|
568
|
+
});
|
|
569
|
+
child.once("close", resolve);
|
|
570
|
+
});
|
|
571
|
+
const timeout = new AbortController();
|
|
572
|
+
const timer = setTimeout(() => timeout.abort(), 6e5);
|
|
573
|
+
try {
|
|
574
|
+
await pipeline(tarball, createGzip({ level: 1 }), createWriteStream(archive), { signal: timeout.signal });
|
|
575
|
+
} catch (error) {
|
|
576
|
+
child.kill("SIGKILL");
|
|
577
|
+
await exited;
|
|
578
|
+
throw timeout.signal.aborted ? /* @__PURE__ */ new Error("Packing the artifact did not finish within 10 minutes.") : error;
|
|
579
|
+
} finally {
|
|
580
|
+
clearTimeout(timer);
|
|
581
|
+
}
|
|
582
|
+
const code = await exited;
|
|
583
|
+
if (spawnError) throw spawnError;
|
|
584
|
+
if (code !== 0) throw new Error(`tar exited with ${code}: ${stderr.join("").trim().slice(-500)}`);
|
|
585
|
+
}
|
|
321
586
|
async function sha256Of(path) {
|
|
322
587
|
const hash = createHash("sha256");
|
|
323
588
|
for await (const chunk of createReadStream(path)) hash.update(chunk);
|
|
@@ -347,13 +612,14 @@ async function build(job) {
|
|
|
347
612
|
message,
|
|
348
613
|
timings
|
|
349
614
|
});
|
|
350
|
-
|
|
615
|
+
ensureCheckout(job.area, join(job.area, "src"));
|
|
616
|
+
const src = realpathSync(join(job.area, "src"));
|
|
351
617
|
const root = join(src, job.project);
|
|
352
618
|
const log = relayWriter(join(job.area, "build.ndjson"));
|
|
353
619
|
const mirrored = await time("syncMs", () => materialize(job, src));
|
|
354
620
|
const realSrc = realpathSync(src);
|
|
355
621
|
const realRoot = realpathSync(root);
|
|
356
|
-
if (realRoot !== realSrc && !realRoot.startsWith(`${realSrc}
|
|
622
|
+
if (realRoot !== realSrc && !realRoot.startsWith(`${realSrc}${sep}`)) return failed("bad-project", `${job.project} leaves the checkout.`);
|
|
357
623
|
note("sync", `${job.manifest.length} files, ${mirrored.written} written, ${mirrored.removed} removed`);
|
|
358
624
|
let fingerprint;
|
|
359
625
|
let compiled;
|
|
@@ -361,21 +627,11 @@ async function build(job) {
|
|
|
361
627
|
if (job.platform !== "android" || job.expectedFingerprint !== null) return failed("unsupported-provider", "Native Gradle needs an Android request with no reusable artifact identity.");
|
|
362
628
|
const selected = projectRegistry.selectAndroid(root);
|
|
363
629
|
if ("problem" in selected || selected.id !== "native-android") return failed("provider-mismatch", "The transferred project did not select the native Android integration.");
|
|
364
|
-
if (!verifyGradleTransfer(src, job.project, job.native.inputs, job.manifest, job.native.sourceDigest)) return failed("source-mismatch", "The materialized native inputs do not match the source transfer.");
|
|
630
|
+
if (!await verifyGradleTransfer(src, job.project, job.native.inputs, job.manifest, job.native.sourceDigest)) return failed("source-mismatch", "The materialized native inputs do not match the source transfer.");
|
|
365
631
|
compiled = await compileNativeAndroid(job, root, log, time);
|
|
366
632
|
if (!compiled.ok) return failed(compiled.code, compiled.message);
|
|
367
633
|
try {
|
|
368
|
-
|
|
369
|
-
const outputs = nativeGradleOutputs(src, job.native.inputs, model.buildDirectories);
|
|
370
|
-
if (!verifyGradleTransfer(src, job.project, job.native.inputs, job.manifest, job.native.sourceDigest)) throw new Error("The native source changed while the worker compiled it.");
|
|
371
|
-
const directories = [...outputs, ...gradleStateDirectories(job.project).filter((path) => lstatSync(join(src, path), { throwIfNoEntry: false })?.isDirectory())];
|
|
372
|
-
const receipt = join(job.area, "gradle-outputs.json");
|
|
373
|
-
const tmp = `${receipt}.${process.pid}.tmp`;
|
|
374
|
-
writeFileSync(tmp, JSON.stringify({
|
|
375
|
-
project: job.project,
|
|
376
|
-
directories
|
|
377
|
-
}));
|
|
378
|
-
renameSync(tmp, receipt);
|
|
634
|
+
if (!await verifyGradleTransfer(src, job.project, job.native.inputs, job.manifest, job.native.sourceDigest)) throw new Error("The native source changed while the worker compiled it.");
|
|
379
635
|
} catch (error) {
|
|
380
636
|
if (compiled.temporary) rmSync(compiled.temporary, {
|
|
381
637
|
recursive: true,
|
|
@@ -391,7 +647,7 @@ async function build(job) {
|
|
|
391
647
|
let metadataDirectories;
|
|
392
648
|
try {
|
|
393
649
|
metadataDirectories = nativeXcodeMetadataDirectories(selectNativeXcodeProject(root, job.scheme ?? void 0, job.configuration ?? void 0));
|
|
394
|
-
if (!verifyNativeTransfer(src, job.manifest, job.native.sourceDigest, metadataDirectories)) return failed("source-mismatch", "The materialized native inputs do not match the source transfer.");
|
|
650
|
+
if (!await verifyNativeTransfer(src, job.manifest, job.native.sourceDigest, metadataDirectories)) return failed("source-mismatch", "The materialized native inputs do not match the source transfer.");
|
|
395
651
|
} catch (error) {
|
|
396
652
|
return failed("source-mismatch", error.message);
|
|
397
653
|
}
|
|
@@ -401,7 +657,7 @@ async function build(job) {
|
|
|
401
657
|
compiled = await compileNativeIos(job, root, log, time);
|
|
402
658
|
if (!compiled.ok) return failed(compiled.code, compiled.message);
|
|
403
659
|
try {
|
|
404
|
-
if (!verifyNativeTransfer(src, job.manifest, job.native.sourceDigest, metadataDirectories)) throw new Error("The native source changed while the worker compiled it.");
|
|
660
|
+
if (!await verifyNativeTransfer(src, job.manifest, job.native.sourceDigest, metadataDirectories)) throw new Error("The native source changed while the worker compiled it.");
|
|
405
661
|
} catch (error) {
|
|
406
662
|
if (compiled.temporary) rmSync(compiled.temporary, {
|
|
407
663
|
recursive: true,
|
|
@@ -413,7 +669,7 @@ async function build(job) {
|
|
|
413
669
|
} else if (job.platform === "macos") {
|
|
414
670
|
fingerprint = await time("fingerprintMs", () => manifestDigest(job.manifest));
|
|
415
671
|
if (fingerprint !== job.expectedFingerprint) return failed("fingerprint-mismatch", `the manifest there fingerprints ${fingerprint.slice(0, 12)}, here ${job.expectedFingerprint?.slice(0, 12)}`);
|
|
416
|
-
compiled = await compileMacos(job, root, log, time);
|
|
672
|
+
compiled = await workerOperation(root, (context) => compileMacos(context, job, root, log, time));
|
|
417
673
|
if (!compiled.ok) return failed(compiled.code, compiled.message);
|
|
418
674
|
} else {
|
|
419
675
|
try {
|
|
@@ -424,7 +680,7 @@ async function build(job) {
|
|
|
424
680
|
const platform = job.platform;
|
|
425
681
|
let iosProject;
|
|
426
682
|
try {
|
|
427
|
-
iosProject = iosProjectDirSetting({ ios: { projectPath: job.iosProjectPath ?? void 0 } },
|
|
683
|
+
iosProject = iosProjectDirSetting({ ios: { projectPath: job.iosProjectPath ?? void 0 } }, realRoot);
|
|
428
684
|
} catch (error) {
|
|
429
685
|
return failed("bad-request", error.message);
|
|
430
686
|
}
|
|
@@ -433,17 +689,17 @@ async function build(job) {
|
|
|
433
689
|
androidLayout = androidLayoutSetting({ android: {
|
|
434
690
|
gradleRoot: job.android?.gradleRoot ?? void 0,
|
|
435
691
|
module: job.android?.module ?? void 0
|
|
436
|
-
} },
|
|
692
|
+
} }, realRoot, realSrc);
|
|
437
693
|
} catch (error) {
|
|
438
694
|
return failed("bad-request", error.message);
|
|
439
695
|
}
|
|
440
|
-
const initial = await time("fingerprintMs", () => fingerprintProject(
|
|
696
|
+
const initial = await time("fingerprintMs", () => fingerprintProject(realRoot, {
|
|
441
697
|
platform,
|
|
442
698
|
iosProjectPath: iosProject.relative,
|
|
443
699
|
androidLayout
|
|
444
700
|
}));
|
|
445
|
-
if (!initial) return failed("no-fingerprint", "The remote
|
|
446
|
-
const plan = planPrebuild(
|
|
701
|
+
if (!initial) return failed("no-fingerprint", "The remote machine could not fingerprint the project.");
|
|
702
|
+
const plan = planPrebuild(realRoot, platform, {
|
|
447
703
|
isExpo: job.isExpo,
|
|
448
704
|
fingerprint: initial.hash,
|
|
449
705
|
sources: initial.sources
|
|
@@ -452,17 +708,17 @@ async function build(job) {
|
|
|
452
708
|
const mutations = [];
|
|
453
709
|
if (plan === "generate" || plan === "regenerate") {
|
|
454
710
|
note("prebuild", plan === "generate" ? `generating ${platform}/` : `regenerating ${platform}/ with --clean`);
|
|
455
|
-
recordPrebuild(
|
|
456
|
-
const result = await time("prebuildMs", () => runPrebuild(
|
|
711
|
+
recordPrebuild(realRoot, platform, null);
|
|
712
|
+
const result = await time("prebuildMs", () => runPrebuild(realRoot, platform, log, { clean: plan === "regenerate" }));
|
|
457
713
|
if (result?.failed) return failed("prebuild-failed", result.reason ?? "expo prebuild failed.");
|
|
458
714
|
mutations.push("prebuild");
|
|
459
715
|
}
|
|
460
716
|
if (platform === "ios") {
|
|
461
|
-
const podState = readPodState(
|
|
717
|
+
const podState = readPodState(realRoot, iosProject.dir);
|
|
462
718
|
const pods = podAction(podState, podsAreStale(podState.lockText, podState.manifestText, podState.dir));
|
|
463
719
|
if (pods.install) {
|
|
464
720
|
note("pods", `${pods.reason ?? "Pods are stale"} -> pod install`);
|
|
465
|
-
const result = await time("podsMs", () => runPodInstall(
|
|
721
|
+
const result = await time("podsMs", () => runPodInstall(realRoot, log, {
|
|
466
722
|
directory: iosProject.dir,
|
|
467
723
|
onHeartbeat: (line) => note("pods", line)
|
|
468
724
|
}));
|
|
@@ -473,7 +729,7 @@ async function build(job) {
|
|
|
473
729
|
fingerprint = initial.hash;
|
|
474
730
|
if (mutations.length) {
|
|
475
731
|
const after = await time("fingerprintMs", () => refingerprintAfterMutation({
|
|
476
|
-
projectRoot:
|
|
732
|
+
projectRoot: realRoot,
|
|
477
733
|
platform,
|
|
478
734
|
previousHash: initial.hash,
|
|
479
735
|
iosProjectPath: iosProject.relative,
|
|
@@ -481,20 +737,25 @@ async function build(job) {
|
|
|
481
737
|
}));
|
|
482
738
|
if (!after) return failed("no-fingerprint", `No fingerprint after ${mutations.join(", ")}.`);
|
|
483
739
|
fingerprint = after.hash;
|
|
484
|
-
if (mutations.includes("prebuild")) recordPrebuild(
|
|
740
|
+
if (mutations.includes("prebuild")) recordPrebuild(realRoot, platform, after.hash);
|
|
485
741
|
}
|
|
486
742
|
if (fingerprint !== job.expectedFingerprint) return failed("fingerprint-mismatch", `the checkout there fingerprints ${fingerprint.slice(0, 12)}, here ${job.expectedFingerprint?.slice(0, 12)}`);
|
|
487
|
-
|
|
743
|
+
const tools = job.cacheArtifact ? await reactNativeArtifactToolchain(platform, realRoot) : null;
|
|
744
|
+
const query = tools ? reactNativeBuildQuery(job, fingerprint, job.project, tools) : null;
|
|
745
|
+
const receipt = query ? reactNativeArtifactReceipt(query, tools) : null;
|
|
746
|
+
compiled = platform === "android" ? await compileAndroid(job, realRoot, log, time, androidLayout) : await compileIos(job, realRoot, log, time);
|
|
488
747
|
if (!compiled.ok) return failed(compiled.code, compiled.message);
|
|
489
748
|
const builtFingerprint = fingerprint;
|
|
490
749
|
const settled = await time("fingerprintMs", () => refingerprintAfterMutation({
|
|
491
|
-
projectRoot:
|
|
750
|
+
projectRoot: realRoot,
|
|
492
751
|
platform,
|
|
493
752
|
previousHash: builtFingerprint,
|
|
494
753
|
iosProjectPath: iosProject.relative,
|
|
495
754
|
androidLayout
|
|
496
755
|
}));
|
|
497
756
|
if (!settled || settled.moved) return failed("fingerprint-moved", "The inputs changed during the build there.");
|
|
757
|
+
const after = query && receipt ? reactNativeArtifactReceipt(query, await reactNativeArtifactToolchain(platform, realRoot)) : null;
|
|
758
|
+
if (receipt && after && isDeepStrictEqual(receipt, after)) compiled.reactNativeArtifact = receipt;
|
|
498
759
|
}
|
|
499
760
|
try {
|
|
500
761
|
const out = join(job.area, "out", job.job);
|
|
@@ -510,15 +771,7 @@ async function build(job) {
|
|
|
510
771
|
verbatimSymlinks: true,
|
|
511
772
|
mode: constants.COPYFILE_FICLONE
|
|
512
773
|
});
|
|
513
|
-
await time("packageMs", () =>
|
|
514
|
-
"-czf",
|
|
515
|
-
archive,
|
|
516
|
-
"--options",
|
|
517
|
-
"gzip:compression-level=1",
|
|
518
|
-
"-C",
|
|
519
|
-
dirname(compiled.path),
|
|
520
|
-
name
|
|
521
|
-
], { timeoutMs: 6e5 }));
|
|
774
|
+
await time("packageMs", () => packArchive(archive, dirname(compiled.path), name));
|
|
522
775
|
const sha256 = await time("packageMs", () => sha256Of(archive));
|
|
523
776
|
return {
|
|
524
777
|
ok: true,
|
|
@@ -531,6 +784,9 @@ async function build(job) {
|
|
|
531
784
|
fingerprint,
|
|
532
785
|
...compiled.androidPackage ? { androidPackage: compiled.androidPackage } : {},
|
|
533
786
|
...job.native ? { sourceDigest: job.native.sourceDigest } : {},
|
|
787
|
+
...compiled.cacheArtifact ? { cacheArtifact: compiled.cacheArtifact } : {},
|
|
788
|
+
...compiled.reactNativeArtifact ? { reactNativeArtifact: compiled.reactNativeArtifact } : {},
|
|
789
|
+
...compiled.swiftpmArtifact ? { swiftpmArtifact: compiled.swiftpmArtifact } : {},
|
|
534
790
|
compilationCache: compiled.cache,
|
|
535
791
|
timings
|
|
536
792
|
};
|
|
@@ -541,12 +797,9 @@ async function build(job) {
|
|
|
541
797
|
});
|
|
542
798
|
}
|
|
543
799
|
}
|
|
544
|
-
function isRecord(value) {
|
|
545
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
546
|
-
}
|
|
547
800
|
function differingParameters(here, there, path) {
|
|
548
801
|
if (JSON.stringify(here) === JSON.stringify(there)) return [];
|
|
549
|
-
if (!
|
|
802
|
+
if (!isJsonObject(here) || !isJsonObject(there)) return [path];
|
|
550
803
|
return [.../* @__PURE__ */ new Set([...Object.keys(here), ...Object.keys(there)])].toSorted().flatMap((key) => differingParameters(here[key], there[key], `${path}.${key}`));
|
|
551
804
|
}
|
|
552
805
|
function unused() {
|
|
@@ -593,6 +846,10 @@ async function nativeIdentityRefusal(job, native, root, load) {
|
|
|
593
846
|
return `This Mac cannot key the native build: ${error.message}`;
|
|
594
847
|
}
|
|
595
848
|
}
|
|
849
|
+
function workerOperation(root, fn) {
|
|
850
|
+
const context = processContext(root, new AbortController().signal);
|
|
851
|
+
return withAmbientContext(context, () => fn(context));
|
|
852
|
+
}
|
|
596
853
|
async function compileNativeIos(job, root, log, time) {
|
|
597
854
|
if (job.native?.provider !== "xcode" || !job.optimizations) return {
|
|
598
855
|
ok: false,
|
|
@@ -612,15 +869,15 @@ async function compileNativeIos(job, root, log, time) {
|
|
|
612
869
|
}, `optimizations.ios.${key}`, value ?? void 0);
|
|
613
870
|
}
|
|
614
871
|
note("build", `native Xcode ${job.configuration ?? "Debug"}`);
|
|
615
|
-
const logFile = join(workspaceLogsDir(root), "build-ios.ndjson");
|
|
872
|
+
const logFile = join(workspaceLogsDir$1(root), "build-ios.ndjson");
|
|
616
873
|
try {
|
|
617
874
|
rmSync(logFile, { force: true });
|
|
618
|
-
const built = await time("buildMs", () => buildIosOperation(root, {
|
|
875
|
+
const built = await time("buildMs", () => workerOperation(root, (context) => buildIosOperation(context, root, {
|
|
619
876
|
scheme: job.scheme ?? void 0,
|
|
620
877
|
configuration: job.configuration ?? void 0,
|
|
621
878
|
arch: native.arch ?? "all",
|
|
622
879
|
remoteBuild: "local"
|
|
623
|
-
}));
|
|
880
|
+
})));
|
|
624
881
|
if (built.cacheKey !== native.cacheKey || built.cacheSkipped) {
|
|
625
882
|
rmSync(dirname(built.appPath), {
|
|
626
883
|
recursive: true,
|
|
@@ -639,6 +896,14 @@ async function compileNativeIos(job, root, log, time) {
|
|
|
639
896
|
temporary: dirname(built.appPath)
|
|
640
897
|
};
|
|
641
898
|
} catch (error) {
|
|
899
|
+
if (error instanceof Error && "code" in error && error.code === "STIM_COMPILATION_CACHE_CORRUPT") {
|
|
900
|
+
const remedy = "remedy" in error && typeof error.remedy === "string" ? ` ${error.remedy}` : "";
|
|
901
|
+
return {
|
|
902
|
+
ok: false,
|
|
903
|
+
code: COMPILATION_CACHE_CORRUPT,
|
|
904
|
+
message: `${error.message}${remedy}`
|
|
905
|
+
};
|
|
906
|
+
}
|
|
642
907
|
return {
|
|
643
908
|
ok: false,
|
|
644
909
|
code: "native-build-failed",
|
|
@@ -648,6 +913,25 @@ async function compileNativeIos(job, root, log, time) {
|
|
|
648
913
|
if (existsSync(logFile)) for (const record of parseNdjsonText(readFileSync(logFile, "utf8"))) log.write(record);
|
|
649
914
|
}
|
|
650
915
|
}
|
|
916
|
+
async function validateNativeAndroidOutputs(job, root) {
|
|
917
|
+
if (job.native?.provider !== "gradle") throw new Error("A native Gradle source declaration is required.");
|
|
918
|
+
try {
|
|
919
|
+
const src = realpathSync(join(job.area, "src"));
|
|
920
|
+
const model = JSON.parse(readFileSync(join(workspaceDir(root), "gradle-build", `native-apk-${encodeURIComponent(job.android?.variant ?? "debug")}.json`), "utf8"));
|
|
921
|
+
const outputs = await nativeGradleOutputs(src, job.native.inputs, model.buildDirectories);
|
|
922
|
+
if (!await verifyGradleTransfer(src, job.project, job.native.inputs, job.manifest, job.native.sourceDigest)) throw new Error("The native source changed while the worker compiled it.");
|
|
923
|
+
const directories = [...outputs, ...gradleStateDirectories(job.project).filter((path) => lstatSync(join(src, path), { throwIfNoEntry: false })?.isDirectory())];
|
|
924
|
+
const receipt = join(job.area, "gradle-outputs.json");
|
|
925
|
+
const tmp = `${receipt}.${process.pid}.tmp`;
|
|
926
|
+
writeFileSync(tmp, JSON.stringify({
|
|
927
|
+
project: job.project,
|
|
928
|
+
directories
|
|
929
|
+
}));
|
|
930
|
+
renameSync(tmp, receipt);
|
|
931
|
+
} catch (error) {
|
|
932
|
+
throw Object.assign(new Error(error.message), { code: "source-moved" });
|
|
933
|
+
}
|
|
934
|
+
}
|
|
651
935
|
async function compileNativeAndroid(job, root, log, time) {
|
|
652
936
|
const options = job.android;
|
|
653
937
|
if (!options) return {
|
|
@@ -671,24 +955,41 @@ async function compileNativeAndroid(job, root, log, time) {
|
|
|
671
955
|
process.exit(143);
|
|
672
956
|
};
|
|
673
957
|
process.once("SIGTERM", stop);
|
|
674
|
-
const logFile = join(workspaceLogsDir(root), "build-android.ndjson");
|
|
958
|
+
const logFile = join(workspaceLogsDir$1(root), "build-android.ndjson");
|
|
959
|
+
let cacheArtifact;
|
|
675
960
|
note("build", `native Gradle ${options.variant ?? "debug"}`);
|
|
676
961
|
try {
|
|
677
962
|
rmSync(logFile, { force: true });
|
|
678
|
-
const built = await time("buildMs", () => buildAndroidOperation(root, {
|
|
963
|
+
const built = await time("buildMs", () => workerOperation(root, (context) => buildAndroidOperation(context, root, {
|
|
679
964
|
variant: options.variant ?? void 0,
|
|
680
965
|
abi: options.abi ?? "all",
|
|
681
966
|
remoteBuild: "local"
|
|
682
|
-
}
|
|
683
|
-
|
|
967
|
+
}, {
|
|
968
|
+
cachePolicy: job.native?.provider === "gradle" && job.native.cache ? job.native.cache : {
|
|
969
|
+
read: false,
|
|
970
|
+
write: false,
|
|
971
|
+
remote: false
|
|
972
|
+
},
|
|
973
|
+
artifactScope: {
|
|
974
|
+
key: job.native?.provider === "gradle" ? nativeGradleWorkerScope(job.native.sourceDigest, job.native.inputs) : "null",
|
|
975
|
+
validate: () => validateNativeAndroidOutputs(job, root),
|
|
976
|
+
record: (identity, receipt) => {
|
|
977
|
+
cacheArtifact = {
|
|
978
|
+
identity,
|
|
979
|
+
receipt
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
})));
|
|
984
|
+
if (!built.androidPackage) {
|
|
684
985
|
rmSync(dirname(built.apkPath), {
|
|
685
986
|
recursive: true,
|
|
686
987
|
force: true
|
|
687
988
|
});
|
|
688
989
|
return {
|
|
689
990
|
ok: false,
|
|
690
|
-
code: "
|
|
691
|
-
message: "The native Gradle worker returned
|
|
991
|
+
code: "invalid-package",
|
|
992
|
+
message: "The native Gradle worker returned no verified APK package."
|
|
692
993
|
};
|
|
693
994
|
}
|
|
694
995
|
return {
|
|
@@ -696,12 +997,13 @@ async function compileNativeAndroid(job, root, log, time) {
|
|
|
696
997
|
path: built.apkPath,
|
|
697
998
|
temporary: dirname(built.apkPath),
|
|
698
999
|
cache: built.ccache,
|
|
699
|
-
androidPackage: built.androidPackage
|
|
1000
|
+
androidPackage: built.androidPackage,
|
|
1001
|
+
...cacheArtifact && cacheArtifact.identity.key === built.cacheKey ? { cacheArtifact } : {}
|
|
700
1002
|
};
|
|
701
1003
|
} catch (error) {
|
|
702
1004
|
return {
|
|
703
1005
|
ok: false,
|
|
704
|
-
code: "native-build-failed",
|
|
1006
|
+
code: error instanceof Error && "code" in error && error.code === "source-moved" ? "source-moved" : "native-build-failed",
|
|
705
1007
|
message: error.message
|
|
706
1008
|
};
|
|
707
1009
|
} finally {
|
|
@@ -710,7 +1012,7 @@ async function compileNativeAndroid(job, root, log, time) {
|
|
|
710
1012
|
if (existsSync(logFile)) for (const record of parseNdjsonText(readFileSync(logFile, "utf8"))) log.write(record);
|
|
711
1013
|
}
|
|
712
1014
|
}
|
|
713
|
-
async function compileMacos(job, root, log, time) {
|
|
1015
|
+
async function compileMacos(context, job, root, log, time) {
|
|
714
1016
|
const options = job.macos;
|
|
715
1017
|
if (!options) return {
|
|
716
1018
|
ok: false,
|
|
@@ -757,6 +1059,26 @@ async function compileMacos(job, root, log, time) {
|
|
|
757
1059
|
};
|
|
758
1060
|
try {
|
|
759
1061
|
const extras = resolveBundleExtras(src, src, options.resources, options.assetCatalog);
|
|
1062
|
+
const query = job.cacheArtifact && options.artifactInputs && job.expectedFingerprint && job.stimBuild ? {
|
|
1063
|
+
project: job.project,
|
|
1064
|
+
sourceDigest: job.expectedFingerprint,
|
|
1065
|
+
stimBuild: job.stimBuild,
|
|
1066
|
+
inputs: options.artifactInputs,
|
|
1067
|
+
build: {
|
|
1068
|
+
product: options.product,
|
|
1069
|
+
infoPlist: options.infoPlist,
|
|
1070
|
+
resources: options.resources ?? {},
|
|
1071
|
+
assetCatalog: options.assetCatalog ?? null
|
|
1072
|
+
}
|
|
1073
|
+
} : null;
|
|
1074
|
+
const snapshot = async () => query ? swiftpmWorkerArtifactSnapshot(root, query, await readSwiftpmWorkerToolchain(context, root), context.env) : null;
|
|
1075
|
+
let before = null;
|
|
1076
|
+
try {
|
|
1077
|
+
before = await snapshot();
|
|
1078
|
+
} catch (error) {
|
|
1079
|
+
context.signal.throwIfAborted();
|
|
1080
|
+
note("build", `SwiftPM artifact inventory unavailable: ${String(error)}`);
|
|
1081
|
+
}
|
|
760
1082
|
return await time("buildMs", async () => {
|
|
761
1083
|
await run([
|
|
762
1084
|
"build",
|
|
@@ -780,11 +1102,21 @@ async function compileMacos(job, root, log, time) {
|
|
|
780
1102
|
"--show-bin-path"
|
|
781
1103
|
], true);
|
|
782
1104
|
const bundle = join(job.area, "out", job.job, `${options.product}.app`);
|
|
783
|
-
stageBundle(root, options.product, options.infoPlist, bin, bundle, options.bundleId, extras);
|
|
1105
|
+
await stageBundle(context, root, options.product, options.infoPlist, bin, bundle, options.bundleId, extras);
|
|
1106
|
+
let swiftpmArtifact = null;
|
|
1107
|
+
if (before) try {
|
|
1108
|
+
const after = await snapshot();
|
|
1109
|
+
if (after?.identity.hash === before.identity.hash) swiftpmArtifact = after;
|
|
1110
|
+
else note("build", "SwiftPM inputs changed during the build; not retaining its artifact.");
|
|
1111
|
+
} catch (error) {
|
|
1112
|
+
context.signal.throwIfAborted();
|
|
1113
|
+
note("build", `SwiftPM artifact inventory skipped: ${String(error)}`);
|
|
1114
|
+
}
|
|
784
1115
|
return {
|
|
785
1116
|
ok: true,
|
|
786
1117
|
path: bundle,
|
|
787
|
-
cache: {}
|
|
1118
|
+
cache: {},
|
|
1119
|
+
...swiftpmArtifact ? { swiftpmArtifact } : {}
|
|
788
1120
|
};
|
|
789
1121
|
});
|
|
790
1122
|
} catch (error) {
|
|
@@ -816,6 +1148,14 @@ async function compileIos(job, root, log, time) {
|
|
|
816
1148
|
onNote: (line) => note("build", line)
|
|
817
1149
|
}));
|
|
818
1150
|
if (!built.ok) {
|
|
1151
|
+
if (built.compilationCacheCorruption) {
|
|
1152
|
+
const report = await clearCorruptCompilationCache(built.compilationCacheCorruption, root);
|
|
1153
|
+
return {
|
|
1154
|
+
ok: false,
|
|
1155
|
+
code: report.code,
|
|
1156
|
+
message: `${report.message} ${report.remedy}`
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
819
1159
|
const first = built.diagnostics[0]?.message;
|
|
820
1160
|
return {
|
|
821
1161
|
ok: false,
|
|
@@ -899,10 +1239,12 @@ async function compileAndroid(job, root, log, time, layout) {
|
|
|
899
1239
|
message: first ?? (built.lastLines.slice(-3).join(" | ") || built.reason)
|
|
900
1240
|
};
|
|
901
1241
|
}
|
|
1242
|
+
const androidPackage = built.androidPackage ?? apkPackage(await dumpApkManifest(built.apkPath));
|
|
902
1243
|
return {
|
|
903
1244
|
ok: true,
|
|
904
1245
|
path: built.apkPath,
|
|
905
|
-
cache: built.ccache ?? CCACHE_UNAVAILABLE
|
|
1246
|
+
cache: built.ccache ?? CCACHE_UNAVAILABLE,
|
|
1247
|
+
...androidPackage ? { androidPackage } : {}
|
|
906
1248
|
};
|
|
907
1249
|
} finally {
|
|
908
1250
|
process.off("SIGTERM", stop);
|
|
@@ -914,6 +1256,27 @@ async function main() {
|
|
|
914
1256
|
if (mode === "offer") return emit(workerToolchain(process.argv[3] ?? null));
|
|
915
1257
|
if (mode === "offer-native-xcode") return emit(workerToolchain(null, "xcode"));
|
|
916
1258
|
if (mode === "offer-native-gradle") return emit(workerToolchain(null, "gradle"));
|
|
1259
|
+
if (mode === "native-gradle-artifact") {
|
|
1260
|
+
const chunks = [];
|
|
1261
|
+
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
1262
|
+
const input = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
1263
|
+
if (!/^[a-f0-9]{64}$/.test(input.sourceDigest)) throw new Error("The completed transfer identity is invalid.");
|
|
1264
|
+
gradleOffloadInputs(input.inputs);
|
|
1265
|
+
if (input.android) {
|
|
1266
|
+
const { android, receipt } = input;
|
|
1267
|
+
if (android.variant !== null && android.variant !== receipt.build.variant || (android.abi === "all" ? null : android.abi) !== receipt.abi || android.compilerCache !== receipt.build.compilerCache || android.gradleBuildCache !== receipt.build.gradleBuildCache || android.pch !== receipt.build.pch || receipt.build.cas !== null) throw new Error("The completed Gradle build choices do not match this artifact request.");
|
|
1268
|
+
}
|
|
1269
|
+
const snapshot = await workerOperation(input.root, (context) => nativeGradleArtifactSnapshotFromReceipt(input.root, input.receipt, context.env, context.signal));
|
|
1270
|
+
return emit({ identity: nativeGradleWorkerArtifactIdentity(snapshot.hash, nativeGradleWorkerScope(input.sourceDigest, input.inputs), input.receipt.build.variant ?? "debug", input.receipt.abi) });
|
|
1271
|
+
}
|
|
1272
|
+
if (mode === "swiftpm-artifact") {
|
|
1273
|
+
const chunks = [];
|
|
1274
|
+
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
1275
|
+
const input = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
1276
|
+
const checkout = existsSync(input.root);
|
|
1277
|
+
if (!checkout && input.receipt.checkoutRequired !== false) return emit({ identity: null });
|
|
1278
|
+
return emit({ identity: await workerOperation(input.root, async (context) => swiftpmArtifactFromReceipt(input.root, input.query, input.receipt, await readSwiftpmWorkerToolchain(context, checkout ? input.root : process.cwd()), context.env)) });
|
|
1279
|
+
}
|
|
917
1280
|
if (mode === "build") {
|
|
918
1281
|
const chunks = [];
|
|
919
1282
|
for await (const chunk of process.stdin) chunks.push(chunk);
|
|
@@ -922,7 +1285,7 @@ async function main() {
|
|
|
922
1285
|
...await build(JSON.parse(Buffer.concat(chunks).toString("utf8")))
|
|
923
1286
|
});
|
|
924
1287
|
}
|
|
925
|
-
process.stderr.write("usage: offload-worker offer | offer-native-xcode | offer-native-gradle | build < job.json\n");
|
|
1288
|
+
process.stderr.write("usage: offload-worker offer | offer-native-xcode | offer-native-gradle | native-gradle-artifact | build < job.json\n");
|
|
926
1289
|
process.exitCode = 2;
|
|
927
1290
|
}
|
|
928
1291
|
main().catch((error) => {
|