trigger.dev 0.0.0-v3-prerelease-20250108141813 → 0.0.0-v4-prerelease-20250916125920

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.
Files changed (292) hide show
  1. package/README.md +28 -1
  2. package/dist/esm/apiClient.d.ts +158 -74
  3. package/dist/esm/apiClient.js +341 -76
  4. package/dist/esm/apiClient.js.map +1 -1
  5. package/dist/esm/build/buildWorker.d.ts +10 -6
  6. package/dist/esm/build/buildWorker.js +22 -38
  7. package/dist/esm/build/buildWorker.js.map +1 -1
  8. package/dist/esm/build/bundle.d.ts +18 -1
  9. package/dist/esm/build/bundle.js +142 -52
  10. package/dist/esm/build/bundle.js.map +1 -1
  11. package/dist/esm/build/entryPoints.d.ts +12 -0
  12. package/dist/esm/build/entryPoints.js +127 -0
  13. package/dist/esm/build/entryPoints.js.map +1 -0
  14. package/dist/esm/build/extensions.js +17 -0
  15. package/dist/esm/build/extensions.js.map +1 -1
  16. package/dist/esm/build/externals.js +184 -2
  17. package/dist/esm/build/externals.js.map +1 -1
  18. package/dist/esm/build/packageModules.d.ts +15 -5
  19. package/dist/esm/build/packageModules.js +154 -36
  20. package/dist/esm/build/packageModules.js.map +1 -1
  21. package/dist/esm/cli/common.d.ts +1 -1
  22. package/dist/esm/cli/common.js +38 -45
  23. package/dist/esm/cli/common.js.map +1 -1
  24. package/dist/esm/cli/index.js +19 -3
  25. package/dist/esm/cli/index.js.map +1 -1
  26. package/dist/esm/commands/analyze.d.ts +23 -0
  27. package/dist/esm/commands/analyze.js +122 -0
  28. package/dist/esm/commands/analyze.js.map +1 -0
  29. package/dist/esm/commands/deploy.d.ts +5 -2
  30. package/dist/esm/commands/deploy.js +271 -160
  31. package/dist/esm/commands/deploy.js.map +1 -1
  32. package/dist/esm/commands/dev.d.ts +36 -6
  33. package/dist/esm/commands/dev.js +71 -2
  34. package/dist/esm/commands/dev.js.map +1 -1
  35. package/dist/esm/commands/env.d.ts +2 -0
  36. package/dist/esm/commands/env.js +298 -0
  37. package/dist/esm/commands/env.js.map +1 -0
  38. package/dist/esm/commands/init.d.ts +9 -1
  39. package/dist/esm/commands/init.js +132 -65
  40. package/dist/esm/commands/init.js.map +1 -1
  41. package/dist/esm/commands/install-mcp.d.ts +50 -0
  42. package/dist/esm/commands/install-mcp.js +497 -0
  43. package/dist/esm/commands/install-mcp.js.map +1 -0
  44. package/dist/esm/commands/install-rules.d.ts +11 -0
  45. package/dist/esm/commands/install-rules.js +381 -0
  46. package/dist/esm/commands/install-rules.js.map +1 -0
  47. package/dist/esm/commands/list-profiles.d.ts +3 -7
  48. package/dist/esm/commands/list-profiles.js +7 -4
  49. package/dist/esm/commands/list-profiles.js.map +1 -1
  50. package/dist/esm/commands/login.d.ts +9 -5
  51. package/dist/esm/commands/login.js +40 -7
  52. package/dist/esm/commands/login.js.map +1 -1
  53. package/dist/esm/commands/logout.d.ts +1 -1
  54. package/dist/esm/commands/mcp.d.ts +38 -0
  55. package/dist/esm/commands/mcp.js +82 -0
  56. package/dist/esm/commands/mcp.js.map +1 -0
  57. package/dist/esm/commands/preview.d.ts +5 -0
  58. package/dist/esm/commands/preview.js +93 -0
  59. package/dist/esm/commands/preview.js.map +1 -0
  60. package/dist/esm/commands/promote.d.ts +3 -0
  61. package/dist/esm/commands/promote.js +86 -0
  62. package/dist/esm/commands/promote.js.map +1 -0
  63. package/dist/esm/commands/switch.d.ts +19 -0
  64. package/dist/esm/commands/switch.js +93 -0
  65. package/dist/esm/commands/switch.js.map +1 -0
  66. package/dist/esm/commands/trigger.d.ts +33 -0
  67. package/dist/esm/commands/trigger.js +88 -0
  68. package/dist/esm/commands/trigger.js.map +1 -0
  69. package/dist/esm/commands/update.d.ts +3 -2
  70. package/dist/esm/commands/update.js +23 -9
  71. package/dist/esm/commands/update.js.map +1 -1
  72. package/dist/esm/commands/whoami.d.ts +12 -1
  73. package/dist/esm/commands/whoami.js +36 -6
  74. package/dist/esm/commands/whoami.js.map +1 -1
  75. package/dist/esm/commands/workers/build.d.ts +4 -0
  76. package/dist/esm/commands/workers/build.js +345 -0
  77. package/dist/esm/commands/workers/build.js.map +1 -0
  78. package/dist/esm/commands/workers/create.d.ts +2 -0
  79. package/dist/esm/commands/workers/create.js +91 -0
  80. package/dist/esm/commands/workers/create.js.map +1 -0
  81. package/dist/esm/commands/workers/index.d.ts +2 -0
  82. package/dist/esm/commands/workers/index.js +13 -0
  83. package/dist/esm/commands/workers/index.js.map +1 -0
  84. package/dist/esm/commands/workers/list.d.ts +2 -0
  85. package/dist/esm/commands/workers/list.js +80 -0
  86. package/dist/esm/commands/workers/list.js.map +1 -0
  87. package/dist/esm/commands/workers/run.d.ts +2 -0
  88. package/dist/esm/commands/workers/run.js +105 -0
  89. package/dist/esm/commands/workers/run.js.map +1 -0
  90. package/dist/esm/config.d.ts +2 -1
  91. package/dist/esm/config.js +35 -8
  92. package/dist/esm/config.js.map +1 -1
  93. package/dist/esm/deploy/buildImage.d.ts +12 -11
  94. package/dist/esm/deploy/buildImage.js +360 -115
  95. package/dist/esm/deploy/buildImage.js.map +1 -1
  96. package/dist/esm/dev/backgroundWorker.d.ts +6 -245
  97. package/dist/esm/dev/backgroundWorker.js +11 -320
  98. package/dist/esm/dev/backgroundWorker.js.map +1 -1
  99. package/dist/esm/dev/devOutput.js +48 -9
  100. package/dist/esm/dev/devOutput.js.map +1 -1
  101. package/dist/esm/dev/devSession.d.ts +2 -1
  102. package/dist/esm/dev/devSession.js +68 -65
  103. package/dist/esm/dev/devSession.js.map +1 -1
  104. package/dist/esm/dev/devSupervisor.d.ts +12 -0
  105. package/dist/esm/dev/devSupervisor.js +568 -0
  106. package/dist/esm/dev/devSupervisor.js.map +1 -0
  107. package/dist/esm/dev/lock.d.ts +1 -0
  108. package/dist/esm/dev/lock.js +80 -0
  109. package/dist/esm/dev/lock.js.map +1 -0
  110. package/dist/esm/dev/mcpServer.d.ts +10 -0
  111. package/dist/esm/dev/mcpServer.js +201 -0
  112. package/dist/esm/dev/mcpServer.js.map +1 -0
  113. package/dist/esm/dev/taskRunProcessPool.d.ts +39 -0
  114. package/dist/esm/dev/taskRunProcessPool.js +220 -0
  115. package/dist/esm/dev/taskRunProcessPool.js.map +1 -0
  116. package/dist/esm/dev/workerRuntime.d.ts +2 -2
  117. package/dist/esm/dev/workerRuntime.js +1 -265
  118. package/dist/esm/dev/workerRuntime.js.map +1 -1
  119. package/dist/esm/entryPoints/dev-index-worker.js +45 -8
  120. package/dist/esm/entryPoints/dev-index-worker.js.map +1 -1
  121. package/dist/esm/entryPoints/dev-run-controller.d.ts +58 -0
  122. package/dist/esm/entryPoints/dev-run-controller.js +652 -0
  123. package/dist/esm/entryPoints/dev-run-controller.js.map +1 -0
  124. package/dist/esm/entryPoints/dev-run-worker.js +394 -199
  125. package/dist/esm/entryPoints/dev-run-worker.js.map +1 -1
  126. package/dist/esm/entryPoints/managed/controller.d.ts +63 -0
  127. package/dist/esm/entryPoints/managed/controller.js +482 -0
  128. package/dist/esm/entryPoints/managed/controller.js.map +1 -0
  129. package/dist/esm/entryPoints/managed/env.d.ts +170 -0
  130. package/dist/esm/entryPoints/managed/env.js +199 -0
  131. package/dist/esm/entryPoints/managed/env.js.map +1 -0
  132. package/dist/esm/entryPoints/managed/execution.d.ts +141 -0
  133. package/dist/esm/entryPoints/managed/execution.js +869 -0
  134. package/dist/esm/entryPoints/managed/execution.js.map +1 -0
  135. package/dist/esm/entryPoints/managed/logger.d.ts +30 -0
  136. package/dist/esm/entryPoints/managed/logger.js +47 -0
  137. package/dist/esm/entryPoints/managed/logger.js.map +1 -0
  138. package/dist/esm/entryPoints/managed/notifier.d.ts +30 -0
  139. package/dist/esm/entryPoints/managed/notifier.js +63 -0
  140. package/dist/esm/entryPoints/managed/notifier.js.map +1 -0
  141. package/dist/esm/entryPoints/managed/overrides.d.ts +18 -0
  142. package/dist/esm/entryPoints/managed/overrides.js +19 -0
  143. package/dist/esm/entryPoints/managed/overrides.js.map +1 -0
  144. package/dist/esm/entryPoints/managed/poller.d.ts +31 -0
  145. package/dist/esm/entryPoints/managed/poller.js +89 -0
  146. package/dist/esm/entryPoints/managed/poller.js.map +1 -0
  147. package/dist/esm/entryPoints/managed/snapshot.d.ts +54 -0
  148. package/dist/esm/entryPoints/managed/snapshot.js +293 -0
  149. package/dist/esm/entryPoints/managed/snapshot.js.map +1 -0
  150. package/dist/esm/entryPoints/managed/taskRunProcessProvider.d.ts +62 -0
  151. package/dist/esm/entryPoints/managed/taskRunProcessProvider.js +252 -0
  152. package/dist/esm/entryPoints/managed/taskRunProcessProvider.js.map +1 -0
  153. package/dist/esm/entryPoints/{deploy-index-controller.js → managed-index-controller.js} +27 -3
  154. package/dist/esm/entryPoints/managed-index-controller.js.map +1 -0
  155. package/dist/esm/entryPoints/{deploy-index-worker.js → managed-index-worker.js} +50 -21
  156. package/dist/esm/entryPoints/managed-index-worker.js.map +1 -0
  157. package/dist/esm/entryPoints/managed-run-controller.js +13 -0
  158. package/dist/esm/entryPoints/managed-run-controller.js.map +1 -0
  159. package/dist/esm/entryPoints/managed-run-worker.js +512 -0
  160. package/dist/esm/entryPoints/managed-run-worker.js.map +1 -0
  161. package/dist/esm/executions/taskRunProcess.d.ts +28 -82
  162. package/dist/esm/executions/taskRunProcess.js +130 -74
  163. package/dist/esm/executions/taskRunProcess.js.map +1 -1
  164. package/dist/esm/indexing/indexWorkerManifest.d.ts +21 -5
  165. package/dist/esm/indexing/indexWorkerManifest.js +4 -4
  166. package/dist/esm/indexing/indexWorkerManifest.js.map +1 -1
  167. package/dist/esm/indexing/registerResources.d.ts +5 -0
  168. package/dist/esm/indexing/registerResources.js +44 -0
  169. package/dist/esm/indexing/registerResources.js.map +1 -0
  170. package/dist/esm/mcp/auth.d.ts +12 -0
  171. package/dist/esm/mcp/auth.js +152 -0
  172. package/dist/esm/mcp/auth.js.map +1 -0
  173. package/dist/esm/mcp/capabilities.d.ts +4 -0
  174. package/dist/esm/mcp/capabilities.js +22 -0
  175. package/dist/esm/mcp/capabilities.js.map +1 -0
  176. package/dist/esm/mcp/config.d.ts +82 -0
  177. package/dist/esm/mcp/config.js +87 -0
  178. package/dist/esm/mcp/config.js.map +1 -0
  179. package/dist/esm/mcp/context.d.ts +45 -0
  180. package/dist/esm/mcp/context.js +129 -0
  181. package/dist/esm/mcp/context.js.map +1 -0
  182. package/dist/esm/mcp/formatters.d.ts +7 -0
  183. package/dist/esm/mcp/formatters.js +330 -0
  184. package/dist/esm/mcp/formatters.js.map +1 -0
  185. package/dist/esm/mcp/logger.d.ts +11 -0
  186. package/dist/esm/mcp/logger.js +34 -0
  187. package/dist/esm/mcp/logger.js.map +1 -0
  188. package/dist/esm/mcp/mintlifyClient.d.ts +1 -0
  189. package/dist/esm/mcp/mintlifyClient.js +65 -0
  190. package/dist/esm/mcp/mintlifyClient.js.map +1 -0
  191. package/dist/esm/mcp/schemas.d.ts +324 -0
  192. package/dist/esm/mcp/schemas.js +144 -0
  193. package/dist/esm/mcp/schemas.js.map +1 -0
  194. package/dist/esm/mcp/tools/deploys.d.ts +174 -0
  195. package/dist/esm/mcp/tools/deploys.js +161 -0
  196. package/dist/esm/mcp/tools/deploys.js.map +1 -0
  197. package/dist/esm/mcp/tools/docs.d.ts +77 -0
  198. package/dist/esm/mcp/tools/docs.js +18 -0
  199. package/dist/esm/mcp/tools/docs.js.map +1 -0
  200. package/dist/esm/mcp/tools/orgs.d.ts +172 -0
  201. package/dist/esm/mcp/tools/orgs.js +172 -0
  202. package/dist/esm/mcp/tools/orgs.js.map +1 -0
  203. package/dist/esm/mcp/tools/previewBranches.d.ts +78 -0
  204. package/dist/esm/mcp/tools/previewBranches.js +28 -0
  205. package/dist/esm/mcp/tools/previewBranches.js.map +1 -0
  206. package/dist/esm/mcp/tools/runs.d.ts +335 -0
  207. package/dist/esm/mcp/tools/runs.js +160 -0
  208. package/dist/esm/mcp/tools/runs.js.map +1 -0
  209. package/dist/esm/mcp/tools/tasks.d.ts +200 -0
  210. package/dist/esm/mcp/tools/tasks.js +117 -0
  211. package/dist/esm/mcp/tools/tasks.js.map +1 -0
  212. package/dist/esm/mcp/tools.d.ts +2 -0
  213. package/dist/esm/mcp/tools.js +40 -0
  214. package/dist/esm/mcp/tools.js.map +1 -0
  215. package/dist/esm/mcp/types.d.ts +6 -0
  216. package/dist/esm/mcp/types.js +2 -0
  217. package/dist/esm/mcp/types.js.map +1 -0
  218. package/dist/esm/mcp/utils.d.ts +89 -0
  219. package/dist/esm/mcp/utils.js +95 -0
  220. package/dist/esm/mcp/utils.js.map +1 -0
  221. package/dist/esm/rules/install.d.ts +1 -0
  222. package/dist/esm/rules/install.js +2 -0
  223. package/dist/esm/rules/install.js.map +1 -0
  224. package/dist/esm/rules/manifest.d.ts +145 -0
  225. package/dist/esm/rules/manifest.js +110 -0
  226. package/dist/esm/rules/manifest.js.map +1 -0
  227. package/dist/esm/rules/types.d.ts +3 -0
  228. package/dist/esm/rules/types.js +3 -0
  229. package/dist/esm/rules/types.js.map +1 -0
  230. package/dist/esm/utilities/accessTokens.d.ts +12 -0
  231. package/dist/esm/utilities/accessTokens.js +30 -0
  232. package/dist/esm/utilities/accessTokens.js.map +1 -0
  233. package/dist/esm/utilities/analyze.d.ts +13 -0
  234. package/dist/esm/utilities/analyze.js +463 -0
  235. package/dist/esm/utilities/analyze.js.map +1 -0
  236. package/dist/esm/utilities/cliOutput.d.ts +6 -1
  237. package/dist/esm/utilities/cliOutput.js +11 -2
  238. package/dist/esm/utilities/cliOutput.js.map +1 -1
  239. package/dist/esm/utilities/configFiles.d.ts +65 -15
  240. package/dist/esm/utilities/configFiles.js +124 -26
  241. package/dist/esm/utilities/configFiles.js.map +1 -1
  242. package/dist/esm/utilities/eventBus.d.ts +7 -3
  243. package/dist/esm/utilities/eventBus.js.map +1 -1
  244. package/dist/esm/utilities/fileSystem.d.ts +7 -1
  245. package/dist/esm/utilities/fileSystem.js +42 -4
  246. package/dist/esm/utilities/fileSystem.js.map +1 -1
  247. package/dist/esm/utilities/gitMeta.d.ts +2 -0
  248. package/dist/esm/utilities/gitMeta.js +220 -0
  249. package/dist/esm/utilities/gitMeta.js.map +1 -0
  250. package/dist/esm/utilities/githubActions.d.ts +4 -0
  251. package/dist/esm/utilities/githubActions.js +18 -0
  252. package/dist/esm/utilities/githubActions.js.map +1 -0
  253. package/dist/esm/utilities/initialBanner.js +18 -6
  254. package/dist/esm/utilities/initialBanner.js.map +1 -1
  255. package/dist/esm/utilities/localEnvVars.d.ts +3 -0
  256. package/dist/esm/utilities/localEnvVars.js +19 -0
  257. package/dist/esm/utilities/localEnvVars.js.map +1 -0
  258. package/dist/esm/utilities/sanitizeEnvVars.d.ts +16 -3
  259. package/dist/esm/utilities/sanitizeEnvVars.js +15 -0
  260. package/dist/esm/utilities/sanitizeEnvVars.js.map +1 -1
  261. package/dist/esm/utilities/session.d.ts +14 -0
  262. package/dist/esm/utilities/session.js +44 -47
  263. package/dist/esm/utilities/session.js.map +1 -1
  264. package/dist/esm/utilities/supportsHyperlinks.d.ts +15 -0
  265. package/dist/esm/utilities/supportsHyperlinks.js +122 -0
  266. package/dist/esm/utilities/supportsHyperlinks.js.map +1 -0
  267. package/dist/esm/utilities/tempDirectories.d.ts +1 -0
  268. package/dist/esm/utilities/tempDirectories.js +19 -2
  269. package/dist/esm/utilities/tempDirectories.js.map +1 -1
  270. package/dist/esm/utilities/terminalLink.d.ts +56 -0
  271. package/dist/esm/utilities/terminalLink.js +76 -0
  272. package/dist/esm/utilities/terminalLink.js.map +1 -0
  273. package/dist/esm/utilities/windows.js +51 -1
  274. package/dist/esm/utilities/windows.js.map +1 -1
  275. package/dist/esm/version.js +1 -1
  276. package/package.json +44 -25
  277. package/dist/esm/entryPoints/deploy-index-controller.js.map +0 -1
  278. package/dist/esm/entryPoints/deploy-index-worker.js.map +0 -1
  279. package/dist/esm/entryPoints/deploy-run-controller.js +0 -1099
  280. package/dist/esm/entryPoints/deploy-run-controller.js.map +0 -1
  281. package/dist/esm/entryPoints/deploy-run-worker.js +0 -366
  282. package/dist/esm/entryPoints/deploy-run-worker.js.map +0 -1
  283. package/dist/esm/indexing/registerTasks.d.ts +0 -2
  284. package/dist/esm/indexing/registerTasks.js +0 -62
  285. package/dist/esm/indexing/registerTasks.js.map +0 -1
  286. package/dist/esm/telemetry/tracing.d.ts +0 -3
  287. package/dist/esm/telemetry/tracing.js +0 -58
  288. package/dist/esm/telemetry/tracing.js.map +0 -1
  289. /package/dist/esm/entryPoints/{deploy-index-controller.d.ts → managed-index-controller.d.ts} +0 -0
  290. /package/dist/esm/entryPoints/{deploy-index-worker.d.ts → managed-index-worker.d.ts} +0 -0
  291. /package/dist/esm/entryPoints/{deploy-run-controller.d.ts → managed-run-controller.d.ts} +0 -0
  292. /package/dist/esm/entryPoints/{deploy-run-worker.d.ts → managed-run-worker.d.ts} +0 -0
@@ -1,38 +1,43 @@
1
- import { join } from "node:path";
2
- import { createTempDir, writeJSONFile } from "../utilities/fileSystem.js";
3
1
  import { logger } from "../utilities/logger.js";
4
2
  import { depot } from "@depot/cli";
5
3
  import { x } from "tinyexec";
4
+ import { networkInterfaces } from "os";
5
+ import { join } from "path";
6
+ import { safeReadJSONFile } from "../utilities/fileSystem.js";
7
+ import { readFileSync } from "fs";
8
+ import { isLinux } from "std-env";
9
+ import { z } from "zod";
10
+ import { assertExhaustive } from "../utilities/assertExhaustive.js";
6
11
  export async function buildImage(options) {
7
- const { selfHosted, buildPlatform, noCache, push, registry, loadImage, registryHost, authAccessToken, imageTag, deploymentId, deploymentVersion, contentHash, externalBuildId, externalBuildToken, externalBuildProjectId, compilationPath, projectId, projectRef, extraCACerts, apiUrl, apiKey, buildEnvVars, } = options;
8
- if (selfHosted) {
9
- return selfHostedBuildImage({
10
- registryHost: registryHost,
11
- imageTag: imageTag,
12
+ const { isLocalBuild, imagePlatform, noCache, push, load, authAccessToken, imageTag, deploymentId, deploymentVersion, contentHash, externalBuildId, externalBuildToken, externalBuildProjectId, compilationPath, projectId, projectRef, extraCACerts, apiUrl, apiKey, branchName, buildEnvVars, network, builder, onLog, } = options;
13
+ if (isLocalBuild) {
14
+ return localBuildImage({
15
+ imageTag,
16
+ imagePlatform,
12
17
  cwd: compilationPath,
13
- projectId: projectId,
14
- deploymentId: deploymentId,
15
- deploymentVersion: deploymentVersion,
16
- contentHash: contentHash,
17
- projectRef: projectRef,
18
- buildPlatform: buildPlatform,
19
- pushImage: push,
20
- selfHostedRegistry: !!registry,
21
- noCache: noCache,
22
- extraCACerts: extraCACerts,
18
+ projectId,
19
+ deploymentId,
20
+ deploymentVersion,
21
+ contentHash,
22
+ projectRef,
23
+ push,
24
+ load,
25
+ noCache,
26
+ extraCACerts,
23
27
  apiUrl,
24
28
  apiKey,
29
+ branchName,
25
30
  buildEnvVars,
26
- network: options.network,
31
+ network,
32
+ builder,
33
+ onLog,
27
34
  });
28
35
  }
29
36
  if (!externalBuildId || !externalBuildToken || !externalBuildProjectId) {
30
37
  throw new Error("Failed to initialize deployment. The deployment does not have any external build data. To deploy this project, you must use the --self-hosted flag to build and push the image yourself.");
31
38
  }
32
- return depotBuildImage({
33
- registryHost,
39
+ return remoteBuildImage({
34
40
  auth: authAccessToken,
35
- imageTag,
36
41
  buildId: externalBuildId,
37
42
  buildToken: externalBuildToken,
38
43
  buildProjectId: externalBuildProjectId,
@@ -42,22 +47,18 @@ export async function buildImage(options) {
42
47
  deploymentVersion,
43
48
  contentHash,
44
49
  projectRef,
45
- loadImage,
46
- buildPlatform,
50
+ load,
51
+ imagePlatform,
47
52
  noCache,
48
53
  extraCACerts,
49
54
  apiUrl,
50
55
  apiKey,
56
+ branchName,
51
57
  buildEnvVars,
58
+ onLog,
52
59
  });
53
60
  }
54
- async function depotBuildImage(options) {
55
- // Step 3: Ensure we are "logged in" to our registry by writing to $HOME/.docker/config.json
56
- // TODO: make sure this works on windows
57
- const dockerConfigDir = await ensureLoggedIntoDockerRegistry(options.registryHost, {
58
- username: "trigger",
59
- password: options.auth,
60
- });
61
+ async function remoteBuildImage(options) {
61
62
  const buildArgs = Object.entries(options.buildEnvVars || {})
62
63
  .filter(([key, value]) => value)
63
64
  .flatMap(([key, value]) => ["--build-arg", `${key}=${value}`]);
@@ -67,9 +68,12 @@ async function depotBuildImage(options) {
67
68
  "Containerfile",
68
69
  options.noCache ? "--no-cache" : undefined,
69
70
  "--platform",
70
- options.buildPlatform,
71
+ options.imagePlatform,
72
+ options.load ? "--load" : undefined,
71
73
  "--provenance",
72
74
  "false",
75
+ "--metadata-file",
76
+ "metadata.json",
73
77
  "--build-arg",
74
78
  `TRIGGER_PROJECT_ID=${options.projectId}`,
75
79
  "--build-arg",
@@ -83,18 +87,17 @@ async function depotBuildImage(options) {
83
87
  "--build-arg",
84
88
  `TRIGGER_API_URL=${options.apiUrl}`,
85
89
  "--build-arg",
90
+ `TRIGGER_PREVIEW_BRANCH=${options.branchName ?? ""}`,
91
+ "--build-arg",
86
92
  `TRIGGER_SECRET_KEY=${options.apiKey}`,
87
93
  ...(buildArgs || []),
88
94
  ...(options.extraCACerts ? ["--build-arg", `NODE_EXTRA_CA_CERTS=${options.extraCACerts}`] : []),
89
95
  "--progress",
90
96
  "plain",
91
- "-t",
92
- `${options.registryHost}/${options.imageTag}`,
93
97
  ".",
94
- "--push",
95
- options.loadImage ? "--load" : undefined,
98
+ "--save",
96
99
  ].filter(Boolean);
97
- logger.debug(`depot ${args.join(" ")}`);
100
+ logger.debug(`depot ${args.join(" ")}`, { cwd: options.cwd });
98
101
  // Step 4: Build and push the image
99
102
  const childProcess = depot(args, {
100
103
  cwd: options.cwd,
@@ -104,7 +107,6 @@ async function depotBuildImage(options) {
104
107
  DEPOT_PROJECT_ID: options.buildProjectId,
105
108
  DEPOT_NO_SUMMARY_LINK: "1",
106
109
  DEPOT_NO_UPDATE_NOTIFIER: "1",
107
- DOCKER_CONFIG: dockerConfigDir,
108
110
  },
109
111
  });
110
112
  const errors = [];
@@ -115,6 +117,9 @@ async function depotBuildImage(options) {
115
117
  const text = data.toString();
116
118
  // Emitted data chunks can contain multiple lines. Remove empty lines.
117
119
  const lines = text.split("\n").filter(Boolean);
120
+ for (const line of lines) {
121
+ options.onLog?.(line);
122
+ }
118
123
  errors.push(...lines);
119
124
  logger.debug(text);
120
125
  });
@@ -129,10 +134,23 @@ async function depotBuildImage(options) {
129
134
  logs,
130
135
  };
131
136
  }
132
- const digest = extractImageDigest(errors);
137
+ const metadataPath = join(options.cwd, "metadata.json");
138
+ const rawMetadata = await safeReadJSONFile(metadataPath);
139
+ const meta = BuildKitMetadata.safeParse(rawMetadata);
140
+ let digest;
141
+ if (!meta.success) {
142
+ logger.error("Failed to parse metadata.json", {
143
+ errors: meta.error.message,
144
+ path: metadataPath,
145
+ });
146
+ }
147
+ else {
148
+ logger.debug("Parsed metadata.json", { metadata: meta.data, path: metadataPath });
149
+ digest = meta.data["containerimage.digest"];
150
+ }
133
151
  return {
134
152
  ok: true,
135
- image: options.imageTag,
153
+ imageSizeBytes: 0,
136
154
  logs,
137
155
  digest,
138
156
  };
@@ -145,19 +163,114 @@ async function depotBuildImage(options) {
145
163
  };
146
164
  }
147
165
  }
148
- async function selfHostedBuildImage(options) {
149
- const imageRef = `${options.registryHost ? `${options.registryHost}/` : ""}${options.imageTag}`;
166
+ async function localBuildImage(options) {
167
+ const { builder, imageTag } = options;
168
+ // Ensure multi-platform build is supported on the local machine
169
+ let builderExists = false;
170
+ const lsLogs = [];
171
+ // List existing builders
172
+ const lsProcess = x("docker", ["buildx", "ls", "--format", "{{.Name}}"]);
173
+ for await (const line of lsProcess) {
174
+ lsLogs.push(line);
175
+ logger.debug(line);
176
+ if (line === builder) {
177
+ builderExists = true;
178
+ }
179
+ }
180
+ if (lsProcess.exitCode !== 0) {
181
+ return {
182
+ ok: false,
183
+ error: `Failed to list buildx builders`,
184
+ logs: lsLogs.join("\n"),
185
+ };
186
+ }
187
+ if (builderExists && options.network) {
188
+ // We need to ensure the current builder network matches
189
+ const inspectProcess = x("docker", ["buildx", "inspect", builder]);
190
+ const inspectLogs = [];
191
+ let hasCorrectNetwork = false;
192
+ for await (const line of inspectProcess) {
193
+ inspectLogs.push(line);
194
+ if (line.match(/Driver Options:\s+network="([^"]+)"/)?.at(1) === options.network) {
195
+ hasCorrectNetwork = true;
196
+ }
197
+ }
198
+ if (inspectProcess.exitCode !== 0) {
199
+ return {
200
+ ok: false,
201
+ error: `Failed to inspect buildx builder '${builder}'`,
202
+ logs: inspectLogs.join("\n"),
203
+ };
204
+ }
205
+ if (!hasCorrectNetwork) {
206
+ // Delete the existing builder and signal to create a new one
207
+ const deleteProcess = x("docker", ["buildx", "rm", builder]);
208
+ const deleteLogs = [];
209
+ for await (const line of deleteProcess) {
210
+ deleteLogs.push(line);
211
+ }
212
+ if (deleteProcess.exitCode !== 0) {
213
+ return {
214
+ ok: false,
215
+ error: `Failed to delete buildx builder '${builder}'`,
216
+ logs: deleteLogs.join("\n"),
217
+ };
218
+ }
219
+ builderExists = false;
220
+ }
221
+ }
222
+ // If the builder does not exist, create it and is compatible with multi-platform builds
223
+ if (!builderExists) {
224
+ const createLogs = [];
225
+ const args = [
226
+ "buildx",
227
+ "create",
228
+ "--name",
229
+ builder,
230
+ "--driver",
231
+ "docker-container",
232
+ options.network ? `--driver-opt=network=${options.network}` : undefined,
233
+ ].filter(Boolean);
234
+ const createProcess = x("docker", args);
235
+ for await (const line of createProcess) {
236
+ createLogs.push(line);
237
+ logger.debug(line);
238
+ options.onLog?.(line);
239
+ }
240
+ if (createProcess.exitCode !== 0) {
241
+ return {
242
+ ok: false,
243
+ error: `Failed to create buildx builder '${builder}'`,
244
+ logs: [...lsLogs, ...createLogs].join("\n"),
245
+ };
246
+ }
247
+ }
150
248
  const buildArgs = Object.entries(options.buildEnvVars || {})
151
249
  .filter(([key, value]) => value)
152
250
  .flatMap(([key, value]) => ["--build-arg", `${key}=${value}`]);
251
+ const apiUrl = normalizeApiUrlForBuild(options.apiUrl);
252
+ const addHost = getAddHost(apiUrl);
253
+ const push = shouldPush(options.imageTag, options.push);
254
+ const load = shouldLoad(options.load, push);
255
+ await ensureQemuRegistered(options.imagePlatform);
153
256
  const args = [
257
+ "buildx",
154
258
  "build",
259
+ "--builder",
260
+ builder,
155
261
  "-f",
156
262
  "Containerfile",
157
263
  options.noCache ? "--no-cache" : undefined,
158
264
  "--platform",
159
- options.buildPlatform,
160
- ...(options.network ? ["--network", options.network] : []),
265
+ options.imagePlatform,
266
+ options.network ? `--network=${options.network}` : undefined,
267
+ addHost ? `--add-host=${addHost}` : undefined,
268
+ push ? "--push" : undefined,
269
+ load ? "--load" : undefined,
270
+ "--provenance",
271
+ "false",
272
+ "--metadata-file",
273
+ "metadata.json",
161
274
  "--build-arg",
162
275
  `TRIGGER_PROJECT_ID=${options.projectId}`,
163
276
  "--build-arg",
@@ -169,7 +282,9 @@ async function selfHostedBuildImage(options) {
169
282
  "--build-arg",
170
283
  `TRIGGER_PROJECT_REF=${options.projectRef}`,
171
284
  "--build-arg",
172
- `TRIGGER_API_URL=${options.apiUrl}`,
285
+ `TRIGGER_API_URL=${apiUrl}`,
286
+ "--build-arg",
287
+ `TRIGGER_PREVIEW_BRANCH=${options.branchName ?? ""}`,
173
288
  "--build-arg",
174
289
  `TRIGGER_SECRET_KEY=${options.apiKey}`,
175
290
  ...(buildArgs || []),
@@ -177,14 +292,11 @@ async function selfHostedBuildImage(options) {
177
292
  "--progress",
178
293
  "plain",
179
294
  "-t",
180
- imageRef,
295
+ options.imageTag,
181
296
  ".", // The build context
182
297
  ].filter(Boolean);
183
- logger.debug(`docker ${args.join(" ")}`, {
184
- cwd: options.cwd,
185
- });
298
+ logger.debug(`docker ${args.join(" ")}`, { cwd: options.cwd });
186
299
  const errors = [];
187
- let digest;
188
300
  // Build the image
189
301
  const buildProcess = x("docker", args, {
190
302
  nodeOptions: { cwd: options.cwd },
@@ -193,6 +305,7 @@ async function selfHostedBuildImage(options) {
193
305
  // line will be from stderr/stdout in the order you'd see it in a term
194
306
  errors.push(line);
195
307
  logger.debug(line);
308
+ options.onLog?.(line);
196
309
  }
197
310
  if (buildProcess.exitCode !== 0) {
198
311
  return {
@@ -201,67 +314,59 @@ async function selfHostedBuildImage(options) {
201
314
  logs: extractLogs(errors),
202
315
  };
203
316
  }
204
- digest = extractImageDigest(errors);
205
- if (options.selfHostedRegistry || options.pushImage) {
206
- const pushArgs = ["push", imageRef].filter(Boolean);
207
- logger.debug(`docker ${pushArgs.join(" ")}`);
208
- // Push the image
209
- const pushProcess = x("docker", pushArgs, {
210
- nodeOptions: { cwd: options.cwd },
317
+ const metadataPath = join(options.cwd, "metadata.json");
318
+ const rawMetadata = await safeReadJSONFile(metadataPath);
319
+ const meta = BuildKitMetadata.safeParse(rawMetadata);
320
+ let digest;
321
+ if (!meta.success) {
322
+ logger.error("Failed to parse metadata.json", {
323
+ errors: meta.error.message,
324
+ path: metadataPath,
211
325
  });
212
- for await (const line of pushProcess) {
213
- logger.debug(line);
214
- errors.push(line);
215
- }
216
- if (pushProcess.exitCode !== 0) {
217
- return {
218
- ok: false,
219
- error: "Error pushing image",
220
- logs: extractLogs(errors),
221
- };
326
+ }
327
+ else {
328
+ logger.debug("Parsed metadata.json", { metadata: meta.data, path: metadataPath });
329
+ // Always use the manifest (list) digest
330
+ digest = meta.data["containerimage.digest"];
331
+ }
332
+ // Get the image size
333
+ const sizeProcess = x("docker", ["image", "inspect", options.imageTag, "--format={{.Size}}"], {
334
+ nodeOptions: { cwd: options.cwd },
335
+ });
336
+ let imageSizeBytes = 0;
337
+ for await (const line of sizeProcess) {
338
+ if (line.trim() === "") {
339
+ continue;
222
340
  }
341
+ imageSizeBytes = parseInt(line, 10);
342
+ break;
343
+ }
344
+ if (imageSizeBytes) {
345
+ // Convert to MB and log
346
+ options.onLog?.(`Image size: ${(imageSizeBytes / (1024 * 1024)).toFixed(2)} MB`);
223
347
  }
224
348
  return {
225
349
  ok: true,
226
- image: options.imageTag,
350
+ imageSizeBytes,
227
351
  digest,
228
352
  logs: extractLogs(errors),
229
353
  };
230
354
  }
231
- async function ensureLoggedIntoDockerRegistry(registryHost, auth) {
232
- const tmpDir = await createTempDir();
233
- // Read the current docker config
234
- const dockerConfigPath = join(tmpDir, "config.json");
235
- await writeJSONFile(dockerConfigPath, {
236
- auths: {
237
- [registryHost]: {
238
- auth: Buffer.from(`${auth.username}:${auth.password}`).toString("base64"),
239
- },
240
- },
241
- });
242
- logger.debug(`Writing docker config to ${dockerConfigPath}`);
243
- return tmpDir;
244
- }
245
355
  function extractLogs(outputs) {
246
356
  // Remove empty lines
247
357
  const cleanedOutputs = outputs.map((line) => line.trim()).filter((line) => line !== "");
248
358
  return cleanedOutputs.map((line) => line.trim()).join("\n");
249
359
  }
250
- function extractImageDigest(outputs) {
251
- const imageDigestRegex = /pushing manifest for .+(?<digest>sha256:[a-f0-9]{64})/;
252
- for (const line of outputs) {
253
- const imageDigestMatch = line.match(imageDigestRegex);
254
- const digest = imageDigestMatch?.groups?.digest;
255
- if (digest) {
256
- return digest;
257
- }
258
- }
259
- return;
260
- }
360
+ const BASE_IMAGE = {
361
+ bun: "imbios/bun-node:1.2.20-20-slim@sha256:a20d1f90ee079b80dffc0041cf8a73aa05cdb135e3b3aff1ba3eba91608dba22",
362
+ node: "node:21.7.3-bookworm-slim@sha256:dfc05dee209a1d7adf2ef189bd97396daad4e97c6eaa85778d6f75205ba1b0fb",
363
+ "node-22": "node:22.16.0-bookworm-slim@sha256:048ed02c5fd52e86fda6fbd2f6a76cf0d4492fd6c6fee9e2c463ed5108da0e34",
364
+ };
261
365
  const DEFAULT_PACKAGES = ["busybox", "ca-certificates", "dumb-init", "git", "openssl"];
262
366
  export async function generateContainerfile(options) {
263
367
  switch (options.runtime) {
264
- case "node": {
368
+ case "node":
369
+ case "node-22": {
265
370
  return await generateNodeContainerfile(options);
266
371
  }
267
372
  case "bun": {
@@ -269,7 +374,7 @@ export async function generateContainerfile(options) {
269
374
  }
270
375
  }
271
376
  }
272
- async function generateBunContainerfile(options) {
377
+ const parseGenerateOptions = (options) => {
273
378
  const buildArgs = Object.entries(options.build.env || {})
274
379
  .flatMap(([key]) => `ARG ${key}`)
275
380
  .join("\n");
@@ -279,19 +384,35 @@ async function generateBunContainerfile(options) {
279
384
  const postInstallCommands = (options.build.commands || []).map((cmd) => `RUN ${cmd}`).join("\n");
280
385
  const baseInstructions = (options.image?.instructions || []).join("\n");
281
386
  const packages = Array.from(new Set(DEFAULT_PACKAGES.concat(options.image?.pkgs || []))).join(" ");
387
+ return {
388
+ baseImage: BASE_IMAGE[options.runtime],
389
+ baseInstructions,
390
+ buildArgs,
391
+ buildEnvVars,
392
+ packages,
393
+ postInstallCommands,
394
+ };
395
+ };
396
+ async function generateBunContainerfile(options) {
397
+ const { baseImage, buildArgs, buildEnvVars, postInstallCommands, baseInstructions, packages } = parseGenerateOptions(options);
282
398
  return `# syntax=docker/dockerfile:1
283
- FROM imbios/bun-node:1.1.24-22-slim@sha256:9cfb7cd87529261c482fe17d8894c0986263f3a5ccf84ad65c00ec0e1ed539c6 AS base
399
+ FROM ${baseImage} AS base
284
400
 
285
401
  ${baseInstructions}
286
402
 
287
403
  ENV DEBIAN_FRONTEND=noninteractive
288
- RUN apt-get update && apt-get --fix-broken install -y && apt-get install -y --no-install-recommends ${packages} && apt-get clean && rm -rf /var/lib/apt/lists/*
404
+ RUN apt-get update && \
405
+ apt-get --fix-broken install -y && \
406
+ apt-get install -y --no-install-recommends ${packages} && \
407
+ apt-get clean && \
408
+ rm -rf /var/lib/apt/lists/*
289
409
 
290
410
  FROM base AS build
291
411
 
292
- RUN apt-get update && apt-get install -y --no-install-recommends \
293
- python3 make g++ && \
294
- apt-get clean && rm -rf /var/lib/apt/lists/*
412
+ RUN apt-get update && \
413
+ apt-get install -y --no-install-recommends python3 make g++ && \
414
+ apt-get clean && \
415
+ rm -rf /var/lib/apt/lists/*
295
416
 
296
417
  USER bun
297
418
  WORKDIR /app
@@ -322,6 +443,7 @@ ARG TRIGGER_PROJECT_REF
322
443
  ARG NODE_EXTRA_CA_CERTS
323
444
  ARG TRIGGER_SECRET_KEY
324
445
  ARG TRIGGER_API_URL
446
+ ARG TRIGGER_PREVIEW_BRANCH
325
447
 
326
448
  ENV TRIGGER_PROJECT_ID=\${TRIGGER_PROJECT_ID} \
327
449
  TRIGGER_DEPLOYMENT_ID=\${TRIGGER_DEPLOYMENT_ID} \
@@ -330,9 +452,14 @@ ENV TRIGGER_PROJECT_ID=\${TRIGGER_PROJECT_ID} \
330
452
  TRIGGER_CONTENT_HASH=\${TRIGGER_CONTENT_HASH} \
331
453
  TRIGGER_SECRET_KEY=\${TRIGGER_SECRET_KEY} \
332
454
  TRIGGER_API_URL=\${TRIGGER_API_URL} \
455
+ TRIGGER_PREVIEW_BRANCH=\${TRIGGER_PREVIEW_BRANCH} \
333
456
  NODE_EXTRA_CA_CERTS=\${NODE_EXTRA_CA_CERTS} \
334
457
  NODE_ENV=production
335
458
 
459
+ ARG TARGETPLATFORM
460
+ ARG BUILDPLATFORM
461
+ ENV BUILDPLATFORM=$BUILDPLATFORM TARGETPLATFORM=$TARGETPLATFORM
462
+
336
463
  # Run the indexer
337
464
  RUN bun run ${options.indexScript}
338
465
 
@@ -354,6 +481,7 @@ ENV TRIGGER_PROJECT_ID=\${TRIGGER_PROJECT_ID} \
354
481
  TRIGGER_DEPLOYMENT_VERSION=\${TRIGGER_DEPLOYMENT_VERSION} \
355
482
  TRIGGER_CONTENT_HASH=\${TRIGGER_CONTENT_HASH} \
356
483
  TRIGGER_PROJECT_REF=\${TRIGGER_PROJECT_REF} \
484
+ UV_USE_IO_URING=0 \
357
485
  NODE_EXTRA_CA_CERTS=\${NODE_EXTRA_CA_CERTS} \
358
486
  NODE_ENV=production
359
487
 
@@ -368,29 +496,25 @@ CMD []
368
496
  `;
369
497
  }
370
498
  async function generateNodeContainerfile(options) {
371
- const buildArgs = Object.entries(options.build.env || {})
372
- .flatMap(([key]) => `ARG ${key}`)
373
- .join("\n");
374
- const buildEnvVars = Object.entries(options.build.env || {})
375
- .flatMap(([key]) => `ENV ${key}=$${key}`)
376
- .join("\n");
377
- const postInstallCommands = (options.build.commands || []).map((cmd) => `RUN ${cmd}`).join("\n");
378
- const baseInstructions = (options.image?.instructions || []).join("\n");
379
- const packages = Array.from(new Set(DEFAULT_PACKAGES.concat(options.image?.pkgs || []))).join(" ");
499
+ const { baseImage, buildArgs, buildEnvVars, postInstallCommands, baseInstructions, packages } = parseGenerateOptions(options);
380
500
  return `# syntax=docker/dockerfile:1
381
- FROM node:21-bookworm-slim@sha256:99afef5df7400a8d118e0504576d32ca700de5034c4f9271d2ff7c91cc12d170 AS base
501
+ FROM ${baseImage} AS base
382
502
 
383
503
  ${baseInstructions}
384
504
 
385
505
  ENV DEBIAN_FRONTEND=noninteractive
386
- RUN apt-get update && apt-get --fix-broken install -y && apt-get install -y --no-install-recommends ${packages} && apt-get clean && rm -rf /var/lib/apt/lists/*
506
+ RUN apt-get update && \
507
+ apt-get --fix-broken install -y && \
508
+ apt-get install -y --no-install-recommends ${packages} && \
509
+ apt-get clean && rm -rf /var/lib/apt/lists/*
387
510
 
388
511
  FROM base AS build
389
512
 
390
513
  # Install build dependencies
391
- RUN apt-get update && apt-get install -y --no-install-recommends \
392
- python3 make g++ && \
393
- apt-get clean && rm -rf /var/lib/apt/lists/*
514
+ RUN apt-get update && \
515
+ apt-get install -y --no-install-recommends python3 make g++ && \
516
+ apt-get clean && \
517
+ rm -rf /var/lib/apt/lists/*
394
518
 
395
519
  USER node
396
520
  WORKDIR /app
@@ -427,6 +551,7 @@ ARG TRIGGER_PROJECT_REF
427
551
  ARG NODE_EXTRA_CA_CERTS
428
552
  ARG TRIGGER_SECRET_KEY
429
553
  ARG TRIGGER_API_URL
554
+ ARG TRIGGER_PREVIEW_BRANCH
430
555
 
431
556
  ENV TRIGGER_PROJECT_ID=\${TRIGGER_PROJECT_ID} \
432
557
  TRIGGER_DEPLOYMENT_ID=\${TRIGGER_DEPLOYMENT_ID} \
@@ -435,11 +560,16 @@ ENV TRIGGER_PROJECT_ID=\${TRIGGER_PROJECT_ID} \
435
560
  TRIGGER_CONTENT_HASH=\${TRIGGER_CONTENT_HASH} \
436
561
  TRIGGER_SECRET_KEY=\${TRIGGER_SECRET_KEY} \
437
562
  TRIGGER_API_URL=\${TRIGGER_API_URL} \
563
+ TRIGGER_PREVIEW_BRANCH=\${TRIGGER_PREVIEW_BRANCH} \
438
564
  TRIGGER_LOG_LEVEL=debug \
439
565
  NODE_EXTRA_CA_CERTS=\${NODE_EXTRA_CA_CERTS} \
440
566
  NODE_ENV=production \
441
567
  NODE_OPTIONS="--max_old_space_size=8192"
442
568
 
569
+ ARG TARGETPLATFORM
570
+ ARG BUILDPLATFORM
571
+ ENV BUILDPLATFORM=$BUILDPLATFORM TARGETPLATFORM=$TARGETPLATFORM
572
+
443
573
  # Run the indexer
444
574
  RUN node ${options.indexScript}
445
575
 
@@ -461,9 +591,9 @@ ENV TRIGGER_PROJECT_ID=\${TRIGGER_PROJECT_ID} \
461
591
  TRIGGER_DEPLOYMENT_VERSION=\${TRIGGER_DEPLOYMENT_VERSION} \
462
592
  TRIGGER_CONTENT_HASH=\${TRIGGER_CONTENT_HASH} \
463
593
  TRIGGER_PROJECT_REF=\${TRIGGER_PROJECT_REF} \
594
+ UV_USE_IO_URING=0 \
464
595
  NODE_EXTRA_CA_CERTS=\${NODE_EXTRA_CA_CERTS} \
465
- NODE_ENV=production \
466
- NODE_OPTIONS="--max_old_space_size=8192"
596
+ NODE_ENV=production
467
597
 
468
598
  # Copy the files from the install stage
469
599
  COPY --from=build --chown=node:node /app ./
@@ -475,4 +605,119 @@ ENTRYPOINT [ "dumb-init", "node", "${options.entrypoint}" ]
475
605
  CMD []
476
606
  `;
477
607
  }
608
+ // If apiUrl is something like http://localhost:3030, we need to convert it to http://host.docker.internal:3030
609
+ // this way the indexing will work because the docker image can reach the local server
610
+ function normalizeApiUrlForBuild(apiUrl) {
611
+ return apiUrl.replace("localhost", "host.docker.internal");
612
+ }
613
+ function getHostIP() {
614
+ const interfaces = networkInterfaces();
615
+ for (const [name, iface] of Object.entries(interfaces)) {
616
+ if (!iface) {
617
+ continue;
618
+ }
619
+ for (const net of iface) {
620
+ // Skip internal/loopback and non-IPv4 addresses
621
+ if (!net.internal && net.family === "IPv4") {
622
+ return net.address;
623
+ }
624
+ }
625
+ }
626
+ return "127.0.0.1";
627
+ }
628
+ function getAddHost(apiUrl) {
629
+ if (apiUrl.includes("host.docker.internal")) {
630
+ return `host.docker.internal:${getHostIP()}`;
631
+ }
632
+ return;
633
+ }
634
+ function isQemuRegistered() {
635
+ try {
636
+ // Check a single QEMU handler
637
+ const binfmt = readFileSync("/proc/sys/fs/binfmt_misc/qemu-aarch64", "utf8");
638
+ return binfmt.includes("enabled");
639
+ }
640
+ catch (e) {
641
+ return false;
642
+ }
643
+ }
644
+ function isMultiPlatform(imagePlatform) {
645
+ return imagePlatform.split(",").length > 1;
646
+ }
647
+ async function ensureQemuRegistered(imagePlatform) {
648
+ if (isLinux && isMultiPlatform(imagePlatform) && !isQemuRegistered()) {
649
+ logger.debug("Registering QEMU for multi-platform build...");
650
+ const ensureQemuProcess = x("docker", [
651
+ "run",
652
+ "--rm",
653
+ "--privileged",
654
+ "multiarch/qemu-user-static",
655
+ "--reset",
656
+ "-p",
657
+ "yes",
658
+ ]);
659
+ const logs = [];
660
+ for await (const line of ensureQemuProcess) {
661
+ logger.debug(line);
662
+ logs.push(line);
663
+ }
664
+ if (ensureQemuProcess.exitCode !== 0) {
665
+ logger.error("Failed to register QEMU for multi-platform build", {
666
+ exitCode: ensureQemuProcess.exitCode,
667
+ logs: logs.join("\n"),
668
+ });
669
+ }
670
+ }
671
+ }
672
+ const BuildKitMetadata = z.object({
673
+ "buildx.build.ref": z.string().optional(),
674
+ "containerimage.descriptor": z
675
+ .object({
676
+ mediaType: z.string(),
677
+ digest: z.string(),
678
+ size: z.number(),
679
+ })
680
+ .optional(),
681
+ "containerimage.digest": z.string().optional(),
682
+ "containerimage.config.digest": z.string().optional(),
683
+ "image.name": z.string().optional(),
684
+ });
685
+ // Don't push if the image tag is a local address, unless the user explicitly wants to push
686
+ function shouldPush(imageTag, push) {
687
+ switch (push) {
688
+ case true: {
689
+ return true;
690
+ }
691
+ case false: {
692
+ return false;
693
+ }
694
+ case undefined: {
695
+ return imageTag.startsWith("localhost") ||
696
+ imageTag.startsWith("127.0.0.1") ||
697
+ imageTag.startsWith("0.0.0.0")
698
+ ? false
699
+ : true;
700
+ }
701
+ default: {
702
+ assertExhaustive(push);
703
+ }
704
+ }
705
+ }
706
+ // Don't load if we're pushing, unless the user explicitly wants to load
707
+ function shouldLoad(load, push) {
708
+ switch (load) {
709
+ case true: {
710
+ return true;
711
+ }
712
+ case false: {
713
+ return false;
714
+ }
715
+ case undefined: {
716
+ return push ? false : true;
717
+ }
718
+ default: {
719
+ assertExhaustive(load);
720
+ }
721
+ }
722
+ }
478
723
  //# sourceMappingURL=buildImage.js.map