@geekmidas/cli 10.0.0-alpha.74 → 10.0.0-alpha.75
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/dist/{LegacyStateStore-D_78eaHM.cjs → LegacyStateStore-BFnXUFlx.cjs} +2 -2
- package/dist/{LegacyStateStore-D_78eaHM.cjs.map → LegacyStateStore-BFnXUFlx.cjs.map} +1 -1
- package/dist/{LegacyStateStore-DTo7z924.mjs → LegacyStateStore-cpt3K1vx.mjs} +2 -2
- package/dist/{LegacyStateStore-DTo7z924.mjs.map → LegacyStateStore-cpt3K1vx.mjs.map} +1 -1
- package/dist/{LocalStateStore-CNjgkRk4.mjs → LocalStateStore-RH9F2ZEy.mjs} +2 -2
- package/dist/{LocalStateStore-CNjgkRk4.mjs.map → LocalStateStore-RH9F2ZEy.mjs.map} +1 -1
- package/dist/{LocalStateStore-BhrlQIXD.cjs → LocalStateStore-zQGZ9b4J.cjs} +2 -2
- package/dist/{LocalStateStore-BhrlQIXD.cjs.map → LocalStateStore-zQGZ9b4J.cjs.map} +1 -1
- package/dist/{S3StateStore-oCxRs6HM.cjs → S3StateStore-CT-ZMlQY.cjs} +2 -2
- package/dist/{S3StateStore-oCxRs6HM.cjs.map → S3StateStore-CT-ZMlQY.cjs.map} +1 -1
- package/dist/{S3StateStore-g2P7T_Mo.mjs → S3StateStore-DBeBc0c0.mjs} +2 -2
- package/dist/{S3StateStore-g2P7T_Mo.mjs.map → S3StateStore-DBeBc0c0.mjs.map} +1 -1
- package/dist/{SSMStateStore-DXp0m7XI.cjs → SSMStateStore-HmsH3c4v.cjs} +2 -2
- package/dist/{SSMStateStore-DXp0m7XI.cjs.map → SSMStateStore-HmsH3c4v.cjs.map} +1 -1
- package/dist/{SSMStateStore-CYenunmK.mjs → SSMStateStore-rnzNfOaV.mjs} +2 -2
- package/dist/{SSMStateStore-CYenunmK.mjs.map → SSMStateStore-rnzNfOaV.mjs.map} +1 -1
- package/dist/{add-Djrr12Xc.cjs → add-CHBin8TF.cjs} +2 -2
- package/dist/{add-Djrr12Xc.cjs.map → add-CHBin8TF.cjs.map} +1 -1
- package/dist/{add-BTH7WaH3.mjs → add-Cvzdw8cf.mjs} +2 -2
- package/dist/{add-BTH7WaH3.mjs.map → add-Cvzdw8cf.mjs.map} +1 -1
- package/dist/{bundler-utHuESvL.cjs → bundler-_8AEZhrs.cjs} +5 -5
- package/dist/{bundler-utHuESvL.cjs.map → bundler-_8AEZhrs.cjs.map} +1 -1
- package/dist/{bundler-BUojOkof.mjs → bundler-xjp5RwRS.mjs} +5 -5
- package/dist/{bundler-BUojOkof.mjs.map → bundler-xjp5RwRS.mjs.map} +1 -1
- package/dist/{cli-Bx0sUzxH.cjs → cli-B4ktxAsM.cjs} +3 -3
- package/dist/{cli-Bx0sUzxH.cjs.map → cli-B4ktxAsM.cjs.map} +1 -1
- package/dist/{cli-CyYceKTS.mjs → cli-BTGfA0B7.mjs} +3 -3
- package/dist/{cli-CyYceKTS.mjs.map → cli-BTGfA0B7.mjs.map} +1 -1
- package/dist/{compose-DZp8DJ0A.mjs → compose-DdH2JQJD.mjs} +219 -152
- package/dist/compose-DdH2JQJD.mjs.map +1 -0
- package/dist/{compose-iuw8wfHk.cjs → compose-UKyv_1yU.cjs} +241 -150
- package/dist/compose-UKyv_1yU.cjs.map +1 -0
- package/dist/deploy/public.cjs +7 -6
- package/dist/deploy/public.d.cts +11 -0
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts +11 -0
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +7 -7
- package/dist/{deploy-C17K7Imy.mjs → deploy-CuSsiFIc.mjs} +21 -5
- package/dist/deploy-CuSsiFIc.mjs.map +1 -0
- package/dist/{deploy-eWorhvQp.cjs → deploy-XUZoA1us.cjs} +26 -4
- package/dist/deploy-XUZoA1us.cjs.map +1 -0
- package/dist/{dokploy-DKzcI-RL.cjs → dokploy-Cvgg_pID.cjs} +2 -2
- package/dist/{dokploy-DKzcI-RL.cjs.map → dokploy-Cvgg_pID.cjs.map} +1 -1
- package/dist/{dokploy-DKa49Nqm.mjs → dokploy-DZXTQX10.mjs} +2 -2
- package/dist/{dokploy-DKa49Nqm.mjs.map → dokploy-DZXTQX10.mjs.map} +1 -1
- package/dist/{encryption-sTMz3aWi.mjs → encryption-JkeMPugf.mjs} +2 -2
- package/dist/{encryption-sTMz3aWi.mjs.map → encryption-JkeMPugf.mjs.map} +1 -1
- package/dist/{encryption-DSkJdoyk.cjs → encryption-w-Ehh9DW.cjs} +2 -2
- package/dist/{encryption-DSkJdoyk.cjs.map → encryption-w-Ehh9DW.cjs.map} +1 -1
- package/dist/{engine-B1b4I34Z.mjs → engine-CmozkHxq.mjs} +192 -4
- package/dist/engine-CmozkHxq.mjs.map +1 -0
- package/dist/{engine-Bh76sAHy.cjs → engine-zpWBMsQq.cjs} +195 -7
- package/dist/engine-zpWBMsQq.cjs.map +1 -0
- package/dist/{github-BvN3CfxM.cjs → github-BGdJ-Lnm.cjs} +2 -2
- package/dist/{github-BvN3CfxM.cjs.map → github-BGdJ-Lnm.cjs.map} +1 -1
- package/dist/{github-C9ODoyZU.mjs → github-BNngHoId.mjs} +2 -2
- package/dist/{github-C9ODoyZU.mjs.map → github-BNngHoId.mjs.map} +1 -1
- package/dist/index.cjs +70 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +69 -44
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-CTtJhGV9.mjs → migrate-BLL1RTAj.mjs} +2 -2
- package/dist/{migrate-CTtJhGV9.mjs.map → migrate-BLL1RTAj.mjs.map} +1 -1
- package/dist/{migrate-B0FCZNkp.cjs → migrate-CgjlYeun.cjs} +2 -2
- package/dist/{migrate-B0FCZNkp.cjs.map → migrate-CgjlYeun.cjs.map} +1 -1
- package/dist/{resolve-DSAXj_47.mjs → resolve-DZNx7rLy.mjs} +3 -3
- package/dist/{resolve-DSAXj_47.mjs.map → resolve-DZNx7rLy.mjs.map} +1 -1
- package/dist/{resolve-D_BU-wKA.cjs → resolve-fevXn-wZ.cjs} +3 -3
- package/dist/{resolve-D_BU-wKA.cjs.map → resolve-fevXn-wZ.cjs.map} +1 -1
- package/dist/{rollback-CWYTUhfW.mjs → rollback-CLi5Pln_.mjs} +4 -4
- package/dist/{rollback-CWYTUhfW.mjs.map → rollback-CLi5Pln_.mjs.map} +1 -1
- package/dist/{rollback-DJy3t696.cjs → rollback-Dw-FW3X2.cjs} +4 -4
- package/dist/{rollback-DJy3t696.cjs.map → rollback-Dw-FW3X2.cjs.map} +1 -1
- package/dist/{sniffer-BFmdZpZ2.mjs → sniffer-BmCvVyhq.mjs} +59 -7
- package/dist/sniffer-BmCvVyhq.mjs.map +1 -0
- package/dist/{sniffer-C-T7dSMN.cjs → sniffer-bMzrX4cO.cjs} +75 -5
- package/dist/{sniffer-C-T7dSMN.cjs.map → sniffer-bMzrX4cO.cjs.map} +1 -1
- package/dist/{state-DpkxSwzI.mjs → state-BrWIOce_.mjs} +46 -284
- package/dist/state-BrWIOce_.mjs.map +1 -0
- package/dist/{state-DCwRWyh-.cjs → state-kA4Fkufx.cjs} +56 -312
- package/dist/state-kA4Fkufx.cjs.map +1 -0
- package/dist/target/public.cjs +1 -1
- package/dist/target/public.mjs +1 -1
- package/package.json +17 -17
- package/dist/compose-DZp8DJ0A.mjs.map +0 -1
- package/dist/compose-iuw8wfHk.cjs.map +0 -1
- package/dist/deploy-C17K7Imy.mjs.map +0 -1
- package/dist/deploy-eWorhvQp.cjs.map +0 -1
- package/dist/engine-B1b4I34Z.mjs.map +0 -1
- package/dist/engine-Bh76sAHy.cjs.map +0 -1
- package/dist/sniffer-BFmdZpZ2.mjs.map +0 -1
- package/dist/state-DCwRWyh-.cjs.map +0 -1
- package/dist/state-DpkxSwzI.mjs.map +0 -1
|
@@ -4,7 +4,7 @@ const require_discover = require("./discover-D1It5r_h.cjs");
|
|
|
4
4
|
const require_derive = require("./derive-DAbo49sm.cjs");
|
|
5
5
|
const require_workspace = require("./workspace-vdrcRI-m.cjs");
|
|
6
6
|
const require_define = require("./define-DzRz8FgH.cjs");
|
|
7
|
-
const require_state = require("./state-
|
|
7
|
+
const require_state = require("./state-kA4Fkufx.cjs");
|
|
8
8
|
const require_SubscriberGenerator = require("./SubscriberGenerator-CajwOa5W.cjs");
|
|
9
9
|
const require_drivers = require("./drivers-BdvtCKc7.cjs");
|
|
10
10
|
const require_databases = require("./databases-C2p5LGAp.cjs");
|
|
@@ -64,6 +64,33 @@ var ServicePortUnknown = class extends Error {
|
|
|
64
64
|
this.name = "ServicePortUnknown";
|
|
65
65
|
}
|
|
66
66
|
};
|
|
67
|
+
/**
|
|
68
|
+
* Whether `ref` names a registry on this machine's loopback — which the
|
|
69
|
+
* daemon pulls from and pushes to over plain HTTP by default, and `docker
|
|
70
|
+
* manifest inspect` reaches only when told `--insecure` (without it, a local
|
|
71
|
+
* registry's image is reported as no such manifest).
|
|
72
|
+
*/
|
|
73
|
+
function isLoopbackRegistry(ref) {
|
|
74
|
+
const first = ref.split("/")[0];
|
|
75
|
+
if (!ref.includes("/") || !/[.:]|^localhost$/.test(first)) return false;
|
|
76
|
+
const host = first.replace(/:\d+$/, "");
|
|
77
|
+
return host === "localhost" || /^127(?:\.\d{1,3}){3}$/.test(host);
|
|
78
|
+
}
|
|
79
|
+
/** `docker push` finished without saying what digest the registry stored. */
|
|
80
|
+
var PushDigestUnknown = class extends Error {
|
|
81
|
+
ref;
|
|
82
|
+
output;
|
|
83
|
+
constructor(ref, output) {
|
|
84
|
+
super(`Pushed ${ref}, but docker did not say which digest the registry stored (it said: ${output.trim().split("\n").slice(-3).join(" / ") || "nothing"}). Check the push with \`docker buildx imagetools inspect ${ref}\`.`);
|
|
85
|
+
this.ref = ref;
|
|
86
|
+
this.output = output;
|
|
87
|
+
this.name = "PushDigestUnknown";
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
/** The digest `docker push` reports last: `<tag>: digest: sha256:… size: …`. */
|
|
91
|
+
function pushedDigest(output) {
|
|
92
|
+
return [...output.matchAll(/digest: (sha256:[0-9a-f]{64})/g)].at(-1)?.[1];
|
|
93
|
+
}
|
|
67
94
|
function compose(stack, args) {
|
|
68
95
|
return [
|
|
69
96
|
"compose",
|
|
@@ -127,6 +154,7 @@ const dockerCompose = {
|
|
|
127
154
|
const { code, stdout, stderr } = await capture("docker", [
|
|
128
155
|
"manifest",
|
|
129
156
|
"inspect",
|
|
157
|
+
...isLoopbackRegistry(ref) ? ["--insecure"] : [],
|
|
130
158
|
ref
|
|
131
159
|
]);
|
|
132
160
|
if (code === 0) return {
|
|
@@ -196,6 +224,15 @@ const dockerCompose = {
|
|
|
196
224
|
to
|
|
197
225
|
]), runOptions(stack));
|
|
198
226
|
},
|
|
227
|
+
async push(stack, ref) {
|
|
228
|
+
const output = await require_run.runOutput("docker", ["push", ref], {
|
|
229
|
+
cwd: stack.cwd,
|
|
230
|
+
...stack.signal ? { signal: stack.signal } : {}
|
|
231
|
+
});
|
|
232
|
+
const digest = pushedDigest(output);
|
|
233
|
+
if (!digest) throw new PushDigestUnknown(ref, output);
|
|
234
|
+
return digest;
|
|
235
|
+
},
|
|
199
236
|
async digest(ref) {
|
|
200
237
|
const { code, stdout } = await capture("docker", [
|
|
201
238
|
"image",
|
|
@@ -266,6 +303,92 @@ async function assertImagesExist(docker, tag, images) {
|
|
|
266
303
|
const missing = lookups.filter((lookup) => lookup.status === "missing").map((lookup) => lookup.ref);
|
|
267
304
|
if (missing.length > 0) throw new ImageTagNotFound(tag, missing);
|
|
268
305
|
}
|
|
306
|
+
/**
|
|
307
|
+
* A push or a pull with no `deploy.registry` to push to or pull from.
|
|
308
|
+
*
|
|
309
|
+
* Without one an image is named `<namespace>/<project>-<app>:<tag>`, which
|
|
310
|
+
* Docker resolves to Docker Hub — so a release would be pushed to, or pulled
|
|
311
|
+
* from, somebody else's account. It is never a fallback.
|
|
312
|
+
*/
|
|
313
|
+
var RegistryRequired = class extends Error {
|
|
314
|
+
operation;
|
|
315
|
+
ref;
|
|
316
|
+
constructor(operation, ref) {
|
|
317
|
+
super(`${operation === "push" ? "Pushing" : "Pulling"} images needs a registry, and gkm.config.ts sets no deploy.registry: '${ref}' would be ${operation === "push" ? "pushed to" : "pulled from"} Docker Hub. Set deploy.registry (e.g. registry: 'ghcr.io/acme') in gkm.config.ts.` + (operation === "pull" ? " To run images built here instead, pass --build." : ""));
|
|
318
|
+
this.operation = operation;
|
|
319
|
+
this.ref = ref;
|
|
320
|
+
this.name = "RegistryRequired";
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
/** An image pinned to its digest: `<ref>@sha256:…`. */
|
|
324
|
+
function pinnedRef(ref, digest) {
|
|
325
|
+
return `${ref.split("@")[0]}@${digest}`;
|
|
326
|
+
}
|
|
327
|
+
/** A digests file with no entry for an app the stack runs. */
|
|
328
|
+
var ImageDigestMissing = class extends Error {
|
|
329
|
+
file;
|
|
330
|
+
apps;
|
|
331
|
+
constructor(file, apps) {
|
|
332
|
+
super(`${file} pins no digest for ${apps.join(", ")}. Use the file the same release's \`gkm compose --build --push --digests-file\` wrote, or run without --digests-file to pull by tag.`);
|
|
333
|
+
this.file = file;
|
|
334
|
+
this.apps = apps;
|
|
335
|
+
this.name = "ImageDigestMissing";
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
/** A digests file entry that is not this app's image. */
|
|
339
|
+
var ImageDigestMismatch = class extends Error {
|
|
340
|
+
app;
|
|
341
|
+
expected;
|
|
342
|
+
found;
|
|
343
|
+
constructor(app, expected, found) {
|
|
344
|
+
super(`The digests file pins '${app}' to ${found}, but this release runs ${expected}. It was written for another registry, project, stage or tag; use the file this stage's push of this tag wrote.`);
|
|
345
|
+
this.app = app;
|
|
346
|
+
this.expected = expected;
|
|
347
|
+
this.found = found;
|
|
348
|
+
this.name = "ImageDigestMismatch";
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
/** A digests file that is not a JSON object of app to pinned ref. */
|
|
352
|
+
var ImageDigestsInvalid = class extends Error {
|
|
353
|
+
file;
|
|
354
|
+
detail;
|
|
355
|
+
constructor(file, detail) {
|
|
356
|
+
super(`${file} is not a digests file (${detail}). It should be the JSON object \`gkm compose --build --push --digests-file\` writes: { "api": "<registry>/<image>:<tag>@sha256:…" }.`);
|
|
357
|
+
this.file = file;
|
|
358
|
+
this.detail = detail;
|
|
359
|
+
this.name = "ImageDigestsInvalid";
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
/** Parse a digests file's content, checking its shape. */
|
|
363
|
+
function parseDigests(file, content) {
|
|
364
|
+
let parsed;
|
|
365
|
+
try {
|
|
366
|
+
parsed = JSON.parse(content);
|
|
367
|
+
} catch (error) {
|
|
368
|
+
throw new ImageDigestsInvalid(file, error instanceof Error ? error.message : String(error));
|
|
369
|
+
}
|
|
370
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new ImageDigestsInvalid(file, "not a JSON object");
|
|
371
|
+
for (const [app, value] of Object.entries(parsed)) if (typeof value !== "string" || !/@sha256:[0-9a-f]{64}$/.test(value)) throw new ImageDigestsInvalid(file, `'${app}' is not an <image>:<tag>@sha256:… ref`);
|
|
372
|
+
return parsed;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Each image pinned to the digest the file names for it.
|
|
376
|
+
*
|
|
377
|
+
* @throws {ImageDigestMissing} naming every app the file has no entry for
|
|
378
|
+
* @throws {ImageDigestMismatch} when an entry is another image or tag
|
|
379
|
+
*/
|
|
380
|
+
function pinImages(file, digests, images) {
|
|
381
|
+
const missing = images.filter((image) => !digests[image.app]).map((image) => image.app);
|
|
382
|
+
if (missing.length > 0) throw new ImageDigestMissing(file, missing);
|
|
383
|
+
return images.map((image) => {
|
|
384
|
+
const pinned = digests[image.app];
|
|
385
|
+
if (pinned.split("@")[0] !== image.ref) throw new ImageDigestMismatch(image.app, image.ref, pinned);
|
|
386
|
+
return {
|
|
387
|
+
...image,
|
|
388
|
+
ref: pinned
|
|
389
|
+
};
|
|
390
|
+
});
|
|
391
|
+
}
|
|
269
392
|
//#endregion
|
|
270
393
|
//#region src/compose/logs.ts
|
|
271
394
|
/**
|
|
@@ -950,6 +1073,7 @@ function composeStack(input) {
|
|
|
950
1073
|
if (app.build && Object.keys(args).length > 0) app.build.args = args;
|
|
951
1074
|
continue;
|
|
952
1075
|
}
|
|
1076
|
+
if (input.buildOnly) continue;
|
|
953
1077
|
const keys = require_state.appEnvKeys(manifest, app.name, input.runnables) ?? /* @__PURE__ */ new Set();
|
|
954
1078
|
const values = valuesFor(app, keys);
|
|
955
1079
|
const trusted = (0, _geekmidas_manifest.provideKey)(app.id, "trustedOrigins");
|
|
@@ -970,7 +1094,7 @@ function composeStack(input) {
|
|
|
970
1094
|
};
|
|
971
1095
|
for (const [key, value] of Object.entries(app.env)) if (/[\r\n]/.test(value)) throw new EnvValueMultiline(app.name, key);
|
|
972
1096
|
}
|
|
973
|
-
for (const worker of workers) {
|
|
1097
|
+
for (const worker of input.buildOnly ? [] : workers) {
|
|
974
1098
|
const keys = require_state.workerEnvKeys(manifest, worker.id, input.runnables) ?? /* @__PURE__ */ new Set();
|
|
975
1099
|
worker.env = {
|
|
976
1100
|
...valuesFor({
|
|
@@ -1003,7 +1127,8 @@ function composeStack(input) {
|
|
|
1003
1127
|
http,
|
|
1004
1128
|
composeDir: (0, node_path.join)(workspace.root, stackDir(stage)),
|
|
1005
1129
|
buildRoot: layout.buildRoot,
|
|
1006
|
-
workspaceRoot: workspace.root
|
|
1130
|
+
workspaceRoot: workspace.root,
|
|
1131
|
+
envFiles: !input.buildOnly
|
|
1007
1132
|
});
|
|
1008
1133
|
const caddyfile = edgeCaddyfile([
|
|
1009
1134
|
...apps.map((app) => ({
|
|
@@ -1254,10 +1379,13 @@ function stackFile(options) {
|
|
|
1254
1379
|
retries: 5
|
|
1255
1380
|
}
|
|
1256
1381
|
};
|
|
1257
|
-
for (const service of Object.values(services))
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1382
|
+
for (const service of Object.values(services)) {
|
|
1383
|
+
if (!options.envFiles) delete service.env_file;
|
|
1384
|
+
service.logging = {
|
|
1385
|
+
driver: LOG_ROTATION.driver,
|
|
1386
|
+
options: { ...LOG_ROTATION.options }
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1261
1389
|
return {
|
|
1262
1390
|
name: project,
|
|
1263
1391
|
services,
|
|
@@ -1280,93 +1408,6 @@ function defaultLayout(root) {
|
|
|
1280
1408
|
gkmPaths: ["gkm.config.*"]
|
|
1281
1409
|
};
|
|
1282
1410
|
}
|
|
1283
|
-
/** The id the stack's compose file names an app's build credentials by. */
|
|
1284
|
-
function credentialsSecret(app) {
|
|
1285
|
-
return `${app}_credentials`;
|
|
1286
|
-
}
|
|
1287
|
-
/** The file beside the compose file an app's build credentials are read from. */
|
|
1288
|
-
function credentialsFile(app) {
|
|
1289
|
-
return `${app}.credentials`;
|
|
1290
|
-
}
|
|
1291
|
-
/**
|
|
1292
|
-
* The stack with each backend's image built with its encrypted credentials:
|
|
1293
|
-
* a BuildKit secret per app — the file `credentialsFile` names, mounted as
|
|
1294
|
-
* `gkm_credentials` — and the hash naming them as a build arg, so a new key
|
|
1295
|
-
* rebuilds the layer that embeds them. Each backend's env file gains the
|
|
1296
|
-
* `GKM_MASTER_KEY` that decrypts them, the way a Dokploy deploy injects it.
|
|
1297
|
-
*
|
|
1298
|
-
* Pure: the caller encrypted them.
|
|
1299
|
-
*/
|
|
1300
|
-
function withBuildCredentials(stack, credentials) {
|
|
1301
|
-
const services = { ...stack.compose.services };
|
|
1302
|
-
const secrets = { ...stack.compose.secrets };
|
|
1303
|
-
const apps = stack.apps.map((app) => {
|
|
1304
|
-
const own = credentials[app.name];
|
|
1305
|
-
const service = services[app.name];
|
|
1306
|
-
if (!own || !service?.build) return app;
|
|
1307
|
-
const [key, value] = own.buildArg.split("=");
|
|
1308
|
-
services[app.name] = {
|
|
1309
|
-
...service,
|
|
1310
|
-
build: {
|
|
1311
|
-
...service.build,
|
|
1312
|
-
args: {
|
|
1313
|
-
...service.build.args,
|
|
1314
|
-
[key]: value
|
|
1315
|
-
},
|
|
1316
|
-
secrets: [{
|
|
1317
|
-
source: credentialsSecret(app.name),
|
|
1318
|
-
target: "gkm_credentials"
|
|
1319
|
-
}]
|
|
1320
|
-
}
|
|
1321
|
-
};
|
|
1322
|
-
secrets[credentialsSecret(app.name)] = { file: `./${credentialsFile(app.name)}` };
|
|
1323
|
-
return {
|
|
1324
|
-
...app,
|
|
1325
|
-
env: {
|
|
1326
|
-
...app.env,
|
|
1327
|
-
GKM_MASTER_KEY: own.masterKey
|
|
1328
|
-
}
|
|
1329
|
-
};
|
|
1330
|
-
});
|
|
1331
|
-
const workers = stack.workers.map((worker) => {
|
|
1332
|
-
const own = credentials[worker.name];
|
|
1333
|
-
const service = services[worker.name];
|
|
1334
|
-
if (!own || !service?.build) return worker;
|
|
1335
|
-
const [key, value] = own.buildArg.split("=");
|
|
1336
|
-
services[worker.name] = {
|
|
1337
|
-
...service,
|
|
1338
|
-
build: {
|
|
1339
|
-
...service.build,
|
|
1340
|
-
args: {
|
|
1341
|
-
...service.build.args,
|
|
1342
|
-
[key]: value
|
|
1343
|
-
},
|
|
1344
|
-
secrets: [{
|
|
1345
|
-
source: credentialsSecret(worker.name),
|
|
1346
|
-
target: "gkm_credentials"
|
|
1347
|
-
}]
|
|
1348
|
-
}
|
|
1349
|
-
};
|
|
1350
|
-
secrets[credentialsSecret(worker.name)] = { file: `./${credentialsFile(worker.name)}` };
|
|
1351
|
-
return {
|
|
1352
|
-
...worker,
|
|
1353
|
-
env: {
|
|
1354
|
-
...worker.env,
|
|
1355
|
-
GKM_MASTER_KEY: own.masterKey
|
|
1356
|
-
}
|
|
1357
|
-
};
|
|
1358
|
-
});
|
|
1359
|
-
return {
|
|
1360
|
-
...stack,
|
|
1361
|
-
apps,
|
|
1362
|
-
workers,
|
|
1363
|
-
compose: {
|
|
1364
|
-
...stack.compose,
|
|
1365
|
-
services,
|
|
1366
|
-
...Object.keys(secrets).length ? { secrets } : {}
|
|
1367
|
-
}
|
|
1368
|
-
};
|
|
1369
|
-
}
|
|
1370
1411
|
/** Render an app's env file: one `KEY=value` per line, read raw by compose. */
|
|
1371
1412
|
function envFile(env) {
|
|
1372
1413
|
return `${Object.entries(env).sort(([a], [b]) => a.localeCompare(b)).map(([key, value]) => `${key}=${value}`).join("\n")}\n`;
|
|
@@ -1462,6 +1503,20 @@ var ComposeAppsUnhealthy = class extends Error {
|
|
|
1462
1503
|
* injected, so the rules are asserted without a daemon; the defaults are the
|
|
1463
1504
|
* real ones.
|
|
1464
1505
|
*/
|
|
1506
|
+
/** `--push` without `--build`: there is nothing built here to push. */
|
|
1507
|
+
var ComposePushNeedsBuild = class extends Error {
|
|
1508
|
+
constructor() {
|
|
1509
|
+
super("--push pushes the images this checkout builds, so it needs --build (and never --pull): gkm compose --stage <stage> --build --push --tag <tag>.");
|
|
1510
|
+
this.name = "ComposePushNeedsBuild";
|
|
1511
|
+
}
|
|
1512
|
+
};
|
|
1513
|
+
/** Digests to run by, on a run that pulls nothing. */
|
|
1514
|
+
var ComposePinNeedsPull = class extends Error {
|
|
1515
|
+
constructor() {
|
|
1516
|
+
super("--digests-file pins the images a release pulls, so it needs --tag (or --pull) — or, with --build --push, it is where the pushed digests are written.");
|
|
1517
|
+
this.name = "ComposePinNeedsPull";
|
|
1518
|
+
}
|
|
1519
|
+
};
|
|
1465
1520
|
/** A port variable that does not hold a port. */
|
|
1466
1521
|
var EdgePortInvalid = class extends Error {
|
|
1467
1522
|
variable;
|
|
@@ -1540,10 +1595,15 @@ const defaultDeps = {
|
|
|
1540
1595
|
* every image it names exists. Nothing is written: a missing image stops the
|
|
1541
1596
|
* run here, before a file, a secret or a container is touched.
|
|
1542
1597
|
*/
|
|
1543
|
-
async function validateCompose(ctx, deps,
|
|
1598
|
+
async function validateCompose(ctx, deps, options = {}) {
|
|
1544
1599
|
const { workspace, stage, identity, tag } = ctx;
|
|
1545
1600
|
const root = workspace.root;
|
|
1546
|
-
const mode =
|
|
1601
|
+
const mode = options.mode ?? (ctx.tagGiven ? "pull" : "build");
|
|
1602
|
+
const push = options.push === true;
|
|
1603
|
+
if (push && mode !== "build") throw new ComposePushNeedsBuild();
|
|
1604
|
+
if (options.pin && mode !== "pull") throw new ComposePinNeedsPull();
|
|
1605
|
+
const registry = workspace.deploy?.registry;
|
|
1606
|
+
if (!registry && (push || mode === "pull")) throw new RegistryRequired(push ? "push" : "pull", require_state.imageRef(identity, ctx.apps[0] ?? workspace.name, void 0, tag));
|
|
1547
1607
|
const runnables = {};
|
|
1548
1608
|
const background = {};
|
|
1549
1609
|
const manifest = await require_discover.discover({
|
|
@@ -1553,14 +1613,13 @@ async function validateCompose(ctx, deps, forced) {
|
|
|
1553
1613
|
background
|
|
1554
1614
|
});
|
|
1555
1615
|
const { secrets, generated } = await stageSecrets(ctx, manifest);
|
|
1556
|
-
await require_credentialSchemas.assertStageCredentials({
|
|
1616
|
+
if (!push) await require_credentialSchemas.assertStageCredentials({
|
|
1557
1617
|
root,
|
|
1558
1618
|
patterns: require_state.constructGlobs(workspace),
|
|
1559
1619
|
manifest,
|
|
1560
1620
|
stage,
|
|
1561
1621
|
supplied: secrets?.custom ?? {}
|
|
1562
1622
|
});
|
|
1563
|
-
const masterKeys = {};
|
|
1564
1623
|
const layout = mode === "build" ? require_state.imageLayout(workspace) : void 0;
|
|
1565
1624
|
const composed = composeStack({
|
|
1566
1625
|
workspace,
|
|
@@ -1572,51 +1631,17 @@ async function validateCompose(ctx, deps, forced) {
|
|
|
1572
1631
|
images: {
|
|
1573
1632
|
mode,
|
|
1574
1633
|
tag,
|
|
1575
|
-
...
|
|
1634
|
+
...registry ? { registry } : {}
|
|
1576
1635
|
},
|
|
1577
1636
|
secrets,
|
|
1578
1637
|
allowDevServices: ctx.allowDevServices,
|
|
1579
1638
|
ports: edgePorts(deps.env),
|
|
1580
|
-
...layout ? { layout } : {}
|
|
1639
|
+
...layout ? { layout } : {},
|
|
1640
|
+
...push ? { buildOnly: true } : {}
|
|
1581
1641
|
});
|
|
1582
1642
|
require_state.reportDevServices(ctx, composed.devServices);
|
|
1583
1643
|
if (mode === "build") assertRedisClient(workspace, composed);
|
|
1584
|
-
const
|
|
1585
|
-
if (mode === "build") {
|
|
1586
|
-
for (const app of composed.apps) {
|
|
1587
|
-
if (app.kind !== "rest-api" || !app.env || !app.build) continue;
|
|
1588
|
-
const { encrypted, iv, masterKey } = require_state.encryptSecrets(app.env);
|
|
1589
|
-
credentials[app.name] = {
|
|
1590
|
-
encrypted,
|
|
1591
|
-
iv
|
|
1592
|
-
};
|
|
1593
|
-
ctx.secrets.mask(masterKey);
|
|
1594
|
-
masterKeys[app.name] = {
|
|
1595
|
-
masterKey,
|
|
1596
|
-
buildArg: require_state.credentialsBuildArg({
|
|
1597
|
-
encrypted,
|
|
1598
|
-
iv
|
|
1599
|
-
})
|
|
1600
|
-
};
|
|
1601
|
-
}
|
|
1602
|
-
for (const worker of composed.workers) {
|
|
1603
|
-
if (!worker.env || !worker.build) continue;
|
|
1604
|
-
const { encrypted, iv, masterKey } = require_state.encryptSecrets(worker.env);
|
|
1605
|
-
credentials[worker.name] = {
|
|
1606
|
-
encrypted,
|
|
1607
|
-
iv
|
|
1608
|
-
};
|
|
1609
|
-
ctx.secrets.mask(masterKey);
|
|
1610
|
-
masterKeys[worker.name] = {
|
|
1611
|
-
masterKey,
|
|
1612
|
-
buildArg: require_state.credentialsBuildArg({
|
|
1613
|
-
encrypted,
|
|
1614
|
-
iv
|
|
1615
|
-
})
|
|
1616
|
-
};
|
|
1617
|
-
}
|
|
1618
|
-
}
|
|
1619
|
-
const stack = withBuildCredentials(composed, masterKeys);
|
|
1644
|
+
const stack = options.pin ? withPinnedImages(composed, options.pin.file, options.pin.digests) : composed;
|
|
1620
1645
|
if (mode === "pull" && !ctx.dryRun) await assertImagesExist(deps.docker, tag, [...stack.apps, ...stack.workers]);
|
|
1621
1646
|
if (stack.redis && !stack.local) ctx.secrets.mask(stack.redis.password);
|
|
1622
1647
|
if (stack.logs && (!stack.local || stack.logs.passwordFromSecrets)) {
|
|
@@ -1627,7 +1652,8 @@ async function validateCompose(ctx, deps, forced) {
|
|
|
1627
1652
|
const override = stackOverrideFile(root, stage);
|
|
1628
1653
|
const overrides = (0, node_fs.existsSync)(override) ? [override] : [];
|
|
1629
1654
|
if (overrides.length > 0) ctx.logger.info(`🧩 Merging docker-compose.${stage}.yml over the generated stack`);
|
|
1630
|
-
const
|
|
1655
|
+
const recorded = push ? void 0 : await ctx.state.read(stage);
|
|
1656
|
+
const previous = Object.fromEntries(Object.entries(recorded?.state.releases ?? {}).map(([name, releases]) => {
|
|
1631
1657
|
const { ref, tag, digest } = releases.current;
|
|
1632
1658
|
return [name, {
|
|
1633
1659
|
ref,
|
|
@@ -1637,6 +1663,7 @@ async function validateCompose(ctx, deps, forced) {
|
|
|
1637
1663
|
}));
|
|
1638
1664
|
return {
|
|
1639
1665
|
mode,
|
|
1666
|
+
push,
|
|
1640
1667
|
stack,
|
|
1641
1668
|
dir,
|
|
1642
1669
|
ref: {
|
|
@@ -1651,7 +1678,6 @@ async function validateCompose(ctx, deps, forced) {
|
|
|
1651
1678
|
generated,
|
|
1652
1679
|
previous,
|
|
1653
1680
|
files: [],
|
|
1654
|
-
credentials,
|
|
1655
1681
|
images: {},
|
|
1656
1682
|
changes: []
|
|
1657
1683
|
};
|
|
@@ -1713,13 +1739,36 @@ async function stageSecrets(ctx, manifest) {
|
|
|
1713
1739
|
};
|
|
1714
1740
|
}
|
|
1715
1741
|
/**
|
|
1742
|
+
* The stack with each app's and worker's image pinned to the digest the file
|
|
1743
|
+
* names: the refs it is checked, pulled and recorded by, and the image each
|
|
1744
|
+
* compose service runs.
|
|
1745
|
+
*/
|
|
1746
|
+
function withPinnedImages(stack, file, digests) {
|
|
1747
|
+
const apps = pinImages(file, digests, stack.apps);
|
|
1748
|
+
const workers = pinImages(file, digests, stack.workers);
|
|
1749
|
+
const services = { ...stack.compose.services };
|
|
1750
|
+
for (const image of [...apps, ...workers]) services[image.name] = {
|
|
1751
|
+
...services[image.name],
|
|
1752
|
+
image: image.ref
|
|
1753
|
+
};
|
|
1754
|
+
return {
|
|
1755
|
+
...stack,
|
|
1756
|
+
apps,
|
|
1757
|
+
workers,
|
|
1758
|
+
compose: {
|
|
1759
|
+
...stack.compose,
|
|
1760
|
+
services
|
|
1761
|
+
}
|
|
1762
|
+
};
|
|
1763
|
+
}
|
|
1764
|
+
/**
|
|
1716
1765
|
* A dry run: the stack's files, written so they can be read, and what a real
|
|
1717
1766
|
* run would do — no image is built or pulled, no container touched, nothing
|
|
1718
1767
|
* recorded and no secret kept.
|
|
1719
1768
|
*/
|
|
1720
1769
|
async function planCompose(ctx, run) {
|
|
1721
1770
|
if (run.generated.length > 0) ctx.logger.info(`🔑 "${ctx.stage}" has no ${run.generated.join(", ")} yet; this dry run used values it did not keep.`);
|
|
1722
|
-
run.files = await writeStack(ctx.cwd, run.dir, run.stack
|
|
1771
|
+
run.files = await writeStack(ctx.cwd, run.dir, run.stack);
|
|
1723
1772
|
printPlan(ctx, run);
|
|
1724
1773
|
const planned = (change) => {
|
|
1725
1774
|
run.changes.push(change);
|
|
@@ -1728,7 +1777,7 @@ async function planCompose(ctx, run) {
|
|
|
1728
1777
|
...change
|
|
1729
1778
|
});
|
|
1730
1779
|
};
|
|
1731
|
-
for (const service of run.stack.infra) planned({
|
|
1780
|
+
for (const service of run.push ? [] : run.stack.infra) planned({
|
|
1732
1781
|
key: `service:${service}`,
|
|
1733
1782
|
resourceType: "service",
|
|
1734
1783
|
action: "ensure"
|
|
@@ -1740,6 +1789,7 @@ async function planCompose(ctx, run) {
|
|
|
1740
1789
|
action: run.mode === "build" ? "build" : "reuse",
|
|
1741
1790
|
id: app.ref
|
|
1742
1791
|
});
|
|
1792
|
+
if (run.push) continue;
|
|
1743
1793
|
planned({
|
|
1744
1794
|
key: `service:${app.name}`,
|
|
1745
1795
|
resourceType: "service",
|
|
@@ -1753,13 +1803,14 @@ async function planCompose(ctx, run) {
|
|
|
1753
1803
|
action: run.mode === "build" ? "build" : "reuse",
|
|
1754
1804
|
id: worker.ref
|
|
1755
1805
|
});
|
|
1806
|
+
if (run.push) continue;
|
|
1756
1807
|
planned({
|
|
1757
1808
|
key: `service:${worker.name}`,
|
|
1758
1809
|
resourceType: "service",
|
|
1759
1810
|
action: run.previous[worker.name] ? "reuse" : "create"
|
|
1760
1811
|
});
|
|
1761
1812
|
}
|
|
1762
|
-
planned({
|
|
1813
|
+
if (!run.push) planned({
|
|
1763
1814
|
key: "service:caddy",
|
|
1764
1815
|
resourceType: "service",
|
|
1765
1816
|
action: "ensure"
|
|
@@ -1772,11 +1823,12 @@ async function planCompose(ctx, run) {
|
|
|
1772
1823
|
*/
|
|
1773
1824
|
async function provisionCompose(ctx, run, deps) {
|
|
1774
1825
|
const { stack, ref } = run;
|
|
1826
|
+
if (run.push) return;
|
|
1775
1827
|
if (run.generated.length > 0 && run.secrets) {
|
|
1776
1828
|
await ctx.secrets.write(run.secrets);
|
|
1777
1829
|
ctx.logger.info(`🔑 Generated for "${ctx.stage}" (${ctx.secrets.store}): ${run.generated.join(", ")}`);
|
|
1778
1830
|
}
|
|
1779
|
-
run.files = await writeStack(ctx.cwd, run.dir, stack
|
|
1831
|
+
run.files = await writeStack(ctx.cwd, run.dir, stack);
|
|
1780
1832
|
printPlan(ctx, run);
|
|
1781
1833
|
if (stack.infra.length > 0) {
|
|
1782
1834
|
ctx.logger.info(`\n🗄️ Starting ${stack.infra.join(", ")}…`);
|
|
@@ -1844,6 +1896,10 @@ async function buildCompose(ctx, run, deps) {
|
|
|
1844
1896
|
const { stack, ref } = run;
|
|
1845
1897
|
const images = [...stack.apps, ...stack.workers];
|
|
1846
1898
|
const apps = images.map((image) => image.app);
|
|
1899
|
+
if (run.push) {
|
|
1900
|
+
run.files = await writeStack(ctx.cwd, run.dir, stack);
|
|
1901
|
+
printPlan(ctx, run);
|
|
1902
|
+
}
|
|
1847
1903
|
if (run.mode === "build") {
|
|
1848
1904
|
ctx.logger.info("\n🐳 Building images…");
|
|
1849
1905
|
await deps.docker.build(ref, apps);
|
|
@@ -1851,8 +1907,10 @@ async function buildCompose(ctx, run, deps) {
|
|
|
1851
1907
|
ctx.logger.info(`\n🐳 Pulling ${ctx.tag}…`);
|
|
1852
1908
|
await deps.docker.pull(ref, apps);
|
|
1853
1909
|
}
|
|
1910
|
+
if (run.push) ctx.logger.info("\n📤 Pushing images…");
|
|
1854
1911
|
for (const image of images) {
|
|
1855
|
-
const digest = await deps.docker.digest(image.ref);
|
|
1912
|
+
const digest = run.push ? await deps.docker.push(ref, image.ref) : await deps.docker.digest(image.ref);
|
|
1913
|
+
if (run.push) ctx.logger.info(` ${image.app.padEnd(12)} ${image.ref}@${digest}`);
|
|
1856
1914
|
run.images[image.app] = {
|
|
1857
1915
|
ref: image.ref,
|
|
1858
1916
|
tag: image.tag,
|
|
@@ -1878,6 +1936,7 @@ async function buildCompose(ctx, run, deps) {
|
|
|
1878
1936
|
*/
|
|
1879
1937
|
async function releaseCompose(ctx, run, deps) {
|
|
1880
1938
|
const { stack, ref } = run;
|
|
1939
|
+
if (run.push) return;
|
|
1881
1940
|
ctx.logger.info("\n🚀 Starting the stack…");
|
|
1882
1941
|
await deps.docker.up(ref);
|
|
1883
1942
|
if (stack.local) await deps.docker.copyOut(ref, "caddy", "/data/caddy/pki/authorities/local/root.crt", caFile(run)).catch(() => {});
|
|
@@ -1936,6 +1995,7 @@ async function recordImages(ctx, run) {
|
|
|
1936
1995
|
*/
|
|
1937
1996
|
async function verifyCompose(ctx, run, deps) {
|
|
1938
1997
|
const { stack } = run;
|
|
1998
|
+
if (run.push) return;
|
|
1939
1999
|
const ca = stack.local ? await (0, node_fs_promises.readFile)(caFile(run), "utf-8").catch(() => void 0) : void 0;
|
|
1940
2000
|
ctx.logger.info("\n🩺 Checking each app through Caddy…");
|
|
1941
2001
|
const results = await Promise.all(stack.apps.map((app) => checkApp(ctx, app, deps, {
|
|
@@ -2115,7 +2175,7 @@ function applied(ctx, run, change) {
|
|
|
2115
2175
|
});
|
|
2116
2176
|
}
|
|
2117
2177
|
/** Write the stack's files: owner-only, since the env files hold secrets. */
|
|
2118
|
-
async function writeStack(root, dir, stack
|
|
2178
|
+
async function writeStack(root, dir, stack) {
|
|
2119
2179
|
await (0, node_fs_promises.mkdir)(dir, {
|
|
2120
2180
|
recursive: true,
|
|
2121
2181
|
mode: 448
|
|
@@ -2131,9 +2191,9 @@ async function writeStack(root, dir, stack, credentials = {}) {
|
|
|
2131
2191
|
await write((0, node_path.join)(dir, "docker-compose.yml"), composeYaml(stack));
|
|
2132
2192
|
await write((0, node_path.join)(dir, "Caddyfile"), stack.caddyfile);
|
|
2133
2193
|
for (const app of [...stack.apps, ...stack.workers]) if (app.env) await write((0, node_path.join)(dir, `${app.name}.env`), envFile(app.env), 384);
|
|
2134
|
-
if (stack.logs) await write((0, node_path.join)(dir, `${LOGS_SERVICE}.env`), envFile(stack.logs.env), 384);
|
|
2135
|
-
if (stack.redis) await write((0, node_path.join)(dir, `${REDIS_SERVICE}.env`), envFile(stack.redis.env), 384);
|
|
2136
|
-
for (const
|
|
2194
|
+
if (stack.logs && stack.compose.services["openobserve"]?.env_file) await write((0, node_path.join)(dir, `${LOGS_SERVICE}.env`), envFile(stack.logs.env), 384);
|
|
2195
|
+
if (stack.redis && stack.compose.services["redis"]?.env_file) await write((0, node_path.join)(dir, `${REDIS_SERVICE}.env`), envFile(stack.redis.env), 384);
|
|
2196
|
+
for (const entry of await (0, node_fs_promises.readdir)(dir)) if (entry.endsWith(".credentials")) await (0, node_fs_promises.rm)((0, node_path.join)(dir, entry));
|
|
2137
2197
|
for (const [path, content] of Object.entries(stack.dockerfiles)) await write((0, node_path.join)(root, path), content);
|
|
2138
2198
|
await require_state.ensureDockerignore(require_state.findBuildRoot(root));
|
|
2139
2199
|
return files;
|
|
@@ -2183,13 +2243,16 @@ function printPlan(ctx, run) {
|
|
|
2183
2243
|
* digest in the stage's state
|
|
2184
2244
|
* - `verify`: each app asked through Caddy over HTTPS
|
|
2185
2245
|
*
|
|
2246
|
+
* With `push` (`gkm compose --build --push`), run with `buildOnly`, it builds
|
|
2247
|
+
* every image and pushes it to `deploy.registry`, and does nothing else.
|
|
2248
|
+
*
|
|
2186
2249
|
* `gkm compose` is this target with a few more switches (`--build`, `--pull`,
|
|
2187
2250
|
* `--down`), run through the same `deploy()`.
|
|
2188
2251
|
*/
|
|
2189
2252
|
var compose_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ composeTarget: () => composeTarget });
|
|
2190
2253
|
/** The compose target, with its Docker, bundler and probe as given. */
|
|
2191
2254
|
function composeTarget(options = {}) {
|
|
2192
|
-
const { mode, report, ...given } = options;
|
|
2255
|
+
const { mode, push, pin, report, ...given } = options;
|
|
2193
2256
|
const deps = {
|
|
2194
2257
|
...defaultDeps,
|
|
2195
2258
|
...given
|
|
@@ -2205,7 +2268,11 @@ function composeTarget(options = {}) {
|
|
|
2205
2268
|
},
|
|
2206
2269
|
credentials: [],
|
|
2207
2270
|
tag: ({ cwd }) => deps.revision(cwd),
|
|
2208
|
-
validate: (ctx) => validateCompose(ctx, deps,
|
|
2271
|
+
validate: (ctx) => validateCompose(ctx, deps, {
|
|
2272
|
+
...mode ? { mode } : {},
|
|
2273
|
+
...push ? { push } : {},
|
|
2274
|
+
...pin ? { pin } : {}
|
|
2275
|
+
}),
|
|
2209
2276
|
plan: (ctx, run) => planCompose(ctx, run),
|
|
2210
2277
|
provision: (ctx, run) => provisionCompose(ctx, run, deps),
|
|
2211
2278
|
build: (ctx, run) => buildCompose(ctx, run, deps),
|
|
@@ -2218,6 +2285,18 @@ function composeTarget(options = {}) {
|
|
|
2218
2285
|
});
|
|
2219
2286
|
}
|
|
2220
2287
|
//#endregion
|
|
2288
|
+
Object.defineProperty(exports, "ComposePinNeedsPull", {
|
|
2289
|
+
enumerable: true,
|
|
2290
|
+
get: function() {
|
|
2291
|
+
return ComposePinNeedsPull;
|
|
2292
|
+
}
|
|
2293
|
+
});
|
|
2294
|
+
Object.defineProperty(exports, "ComposePushNeedsBuild", {
|
|
2295
|
+
enumerable: true,
|
|
2296
|
+
get: function() {
|
|
2297
|
+
return ComposePushNeedsBuild;
|
|
2298
|
+
}
|
|
2299
|
+
});
|
|
2221
2300
|
Object.defineProperty(exports, "composeProject", {
|
|
2222
2301
|
enumerable: true,
|
|
2223
2302
|
get: function() {
|
|
@@ -2242,6 +2321,18 @@ Object.defineProperty(exports, "dockerCompose", {
|
|
|
2242
2321
|
return dockerCompose;
|
|
2243
2322
|
}
|
|
2244
2323
|
});
|
|
2324
|
+
Object.defineProperty(exports, "parseDigests", {
|
|
2325
|
+
enumerable: true,
|
|
2326
|
+
get: function() {
|
|
2327
|
+
return parseDigests;
|
|
2328
|
+
}
|
|
2329
|
+
});
|
|
2330
|
+
Object.defineProperty(exports, "pinnedRef", {
|
|
2331
|
+
enumerable: true,
|
|
2332
|
+
get: function() {
|
|
2333
|
+
return pinnedRef;
|
|
2334
|
+
}
|
|
2335
|
+
});
|
|
2245
2336
|
Object.defineProperty(exports, "stackDir", {
|
|
2246
2337
|
enumerable: true,
|
|
2247
2338
|
get: function() {
|
|
@@ -2255,4 +2346,4 @@ Object.defineProperty(exports, "stackOverrideFile", {
|
|
|
2255
2346
|
}
|
|
2256
2347
|
});
|
|
2257
2348
|
|
|
2258
|
-
//# sourceMappingURL=compose-
|
|
2349
|
+
//# sourceMappingURL=compose-UKyv_1yU.cjs.map
|