@geekmidas/cli 10.0.0-alpha.61 → 10.0.0-alpha.63
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 +2 -0
- package/dist/{HostingerProvider-DI_Pr2VE.mjs → HostingerProvider-DBBwpDjn.mjs} +2 -2
- package/dist/{HostingerProvider-DI_Pr2VE.mjs.map → HostingerProvider-DBBwpDjn.mjs.map} +1 -1
- package/dist/{HostingerProvider-CgDaD8VR.cjs → HostingerProvider-mJ7YruxH.cjs} +2 -2
- package/dist/{HostingerProvider-CgDaD8VR.cjs.map → HostingerProvider-mJ7YruxH.cjs.map} +1 -1
- package/dist/{LegacyStateStore-JbBVFp_2.cjs → LegacyStateStore-CP7SZwTP.cjs} +2 -2
- package/dist/{LegacyStateStore-JbBVFp_2.cjs.map → LegacyStateStore-CP7SZwTP.cjs.map} +1 -1
- package/dist/{LegacyStateStore-C7vFAxbu.mjs → LegacyStateStore-Q3GmKOdw.mjs} +2 -2
- package/dist/{LegacyStateStore-C7vFAxbu.mjs.map → LegacyStateStore-Q3GmKOdw.mjs.map} +1 -1
- package/dist/{LocalStateStore-DfUwQsL8.mjs → LocalStateStore-BGIXcrvX.mjs} +2 -2
- package/dist/{LocalStateStore-DfUwQsL8.mjs.map → LocalStateStore-BGIXcrvX.mjs.map} +1 -1
- package/dist/{LocalStateStore-DHj_-CQB.cjs → LocalStateStore-sS8mvLeq.cjs} +2 -2
- package/dist/{LocalStateStore-DHj_-CQB.cjs.map → LocalStateStore-sS8mvLeq.cjs.map} +1 -1
- package/dist/{OpenApiTsGenerator-BSrgw7B0.cjs → OpenApiTsGenerator-CjHWFRDd.cjs} +2 -2
- package/dist/{OpenApiTsGenerator-BSrgw7B0.cjs.map → OpenApiTsGenerator-CjHWFRDd.cjs.map} +1 -1
- package/dist/{OpenApiTsGenerator-q5B0z8Xg.mjs → OpenApiTsGenerator-CnAwhGxi.mjs} +2 -2
- package/dist/{OpenApiTsGenerator-q5B0z8Xg.mjs.map → OpenApiTsGenerator-CnAwhGxi.mjs.map} +1 -1
- package/dist/{S3StateStore-xqnpUrzy.cjs → S3StateStore-6jqITH2F.cjs} +2 -2
- package/dist/{S3StateStore-xqnpUrzy.cjs.map → S3StateStore-6jqITH2F.cjs.map} +1 -1
- package/dist/{S3StateStore-Dq6hHtzY.mjs → S3StateStore-D7l_lWJ3.mjs} +2 -2
- package/dist/{S3StateStore-Dq6hHtzY.mjs.map → S3StateStore-D7l_lWJ3.mjs.map} +1 -1
- package/dist/{SSMStateStore-5dBRwVlJ.cjs → SSMStateStore-B__F7IJa.cjs} +2 -2
- package/dist/{SSMStateStore-5dBRwVlJ.cjs.map → SSMStateStore-B__F7IJa.cjs.map} +1 -1
- package/dist/{SSMStateStore-SUmvAbLi.mjs → SSMStateStore-CAQDVpoc.mjs} +2 -2
- package/dist/{SSMStateStore-SUmvAbLi.mjs.map → SSMStateStore-CAQDVpoc.mjs.map} +1 -1
- package/dist/{bundler-DXATpO1T.cjs → bundler-DLfOn0ls.cjs} +3 -3
- package/dist/{bundler-DXATpO1T.cjs.map → bundler-DLfOn0ls.cjs.map} +1 -1
- package/dist/{bundler-B5VsKW-_.mjs → bundler-DyWI41Iy.mjs} +2 -2
- package/dist/{bundler-B5VsKW-_.mjs.map → bundler-DyWI41Iy.mjs.map} +1 -1
- package/dist/{cli-DQdrVkj2.cjs → cli-D-ZM-X2s.cjs} +12 -16
- package/dist/cli-D-ZM-X2s.cjs.map +1 -0
- package/dist/{cli-DEA_J3Sa.mjs → cli-PkVF28LM.mjs} +10 -14
- package/dist/cli-PkVF28LM.mjs.map +1 -0
- package/dist/{config-DXnkCEq0.cjs → config-BEJYKd4s.cjs} +132 -18
- package/dist/config-BEJYKd4s.cjs.map +1 -0
- package/dist/config-C2BUosLm.d.mts +256 -0
- package/dist/config-C2BUosLm.d.mts.map +1 -0
- package/dist/config-CemHVcIr.d.cts +256 -0
- package/dist/config-CemHVcIr.d.cts.map +1 -0
- package/dist/{config-C5-EEdmr.mjs → config-LKKCVCnC.mjs} +109 -19
- package/dist/config-LKKCVCnC.mjs.map +1 -0
- package/dist/config.cjs +6 -2
- package/dist/config.d.cts +4 -211
- package/dist/config.d.mts +4 -211
- package/dist/config.mjs +3 -3
- package/dist/define-CHBIEc5j.mjs +94 -0
- package/dist/define-CHBIEc5j.mjs.map +1 -0
- package/dist/define-Cv_QvDrg.cjs +141 -0
- package/dist/define-Cv_QvDrg.cjs.map +1 -0
- package/dist/deploy/public.cjs +174 -13
- package/dist/deploy/public.cjs.map +1 -0
- package/dist/deploy/public.d.cts +200 -292
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts +200 -292
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +136 -3
- package/dist/deploy/public.mjs.map +1 -0
- package/dist/deploy/sniffer-envparser-worker.cjs +54 -0
- package/dist/deploy/sniffer-envparser-worker.cjs.map +1 -0
- package/dist/deploy/sniffer-envparser-worker.d.cts +1 -0
- package/dist/deploy/sniffer-envparser-worker.d.mts +1 -0
- package/dist/deploy/sniffer-envparser-worker.mjs +55 -0
- package/dist/deploy/sniffer-envparser-worker.mjs.map +1 -0
- package/dist/{deploy-BbJdgQ2b.cjs → deploy-ABBI0lf1.cjs} +169 -561
- package/dist/deploy-ABBI0lf1.cjs.map +1 -0
- package/dist/deploy-BiMrP9i7.cjs +140 -0
- package/dist/deploy-BiMrP9i7.cjs.map +1 -0
- package/dist/{deploy-BJcLmVTc.mjs → deploy-CG8bfFij.mjs} +152 -532
- package/dist/deploy-CG8bfFij.mjs.map +1 -0
- package/dist/deploy-CGW-QY9D.mjs +135 -0
- package/dist/deploy-CGW-QY9D.mjs.map +1 -0
- package/dist/discover-B6yPpvRV.d.mts +99 -0
- package/dist/discover-B6yPpvRV.d.mts.map +1 -0
- package/dist/discover-B_IkPukx.d.cts +99 -0
- package/dist/discover-B_IkPukx.d.cts.map +1 -0
- package/dist/discover-BaT6bpnA.mjs +614 -0
- package/dist/discover-BaT6bpnA.mjs.map +1 -0
- package/dist/discover-C_6COHEv.cjs +729 -0
- package/dist/discover-C_6COHEv.cjs.map +1 -0
- package/dist/dokploy-CwdmlyQL.mjs +32 -0
- package/dist/dokploy-CwdmlyQL.mjs.map +1 -0
- package/dist/dokploy-QJxMhxdf.cjs +32 -0
- package/dist/dokploy-QJxMhxdf.cjs.map +1 -0
- package/dist/{encryption-DaA9gRXr.mjs → encryption-CbQG_ayW.mjs} +4 -4
- package/dist/{encryption-DaA9gRXr.mjs.map → encryption-CbQG_ayW.mjs.map} +1 -1
- package/dist/{encryption-ojzUo7-z.cjs → encryption-DXw3jj0c.cjs} +4 -4
- package/dist/{encryption-ojzUo7-z.cjs.map → encryption-DXw3jj0c.cjs.map} +1 -1
- package/dist/fakes-C9RiT6XG.mjs.map +1 -1
- package/dist/fakes-zW-jNAbQ.cjs.map +1 -1
- package/dist/{github-Cq57poPj.cjs → github-BH_mETav.cjs} +3 -3
- package/dist/{github-Cq57poPj.cjs.map → github-BH_mETav.cjs.map} +1 -1
- package/dist/{github-DmCj2u95.mjs → github-ciwbIwVa.mjs} +3 -3
- package/dist/{github-DmCj2u95.mjs.map → github-ciwbIwVa.mjs.map} +1 -1
- package/dist/{index-UiWCaGzU.d.cts → index-BtXDZQuF.d.cts} +2 -2
- package/dist/{index-Da1-oa9W.d.mts.map → index-BtXDZQuF.d.cts.map} +1 -1
- package/dist/{index-Da1-oa9W.d.mts → index-DrKzpHl-.d.mts} +2 -2
- package/dist/{index-UiWCaGzU.d.cts.map → index-DrKzpHl-.d.mts.map} +1 -1
- package/dist/index.cjs +60 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +57 -49
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-BScRpCEx.cjs → migrate-6oa9y_f2.cjs} +5 -5
- package/dist/{migrate-BScRpCEx.cjs.map → migrate-6oa9y_f2.cjs.map} +1 -1
- package/dist/{migrate-5_J5JySj.mjs → migrate-ImBKTBcW.mjs} +5 -5
- package/dist/{migrate-5_J5JySj.mjs.map → migrate-ImBKTBcW.mjs.map} +1 -1
- package/dist/openapi.cjs +3 -3
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +3 -3
- package/dist/{ready-XlNx-Gbo.cjs → ready-BiG0rt4h.cjs} +3 -3
- package/dist/{ready-XlNx-Gbo.cjs.map → ready-BiG0rt4h.cjs.map} +1 -1
- package/dist/{ready-DQIy21W5.mjs → ready-Bpdnn2ON.mjs} +3 -3
- package/dist/{ready-DQIy21W5.mjs.map → ready-Bpdnn2ON.mjs.map} +1 -1
- package/dist/reconcile/public.cjs +1 -1
- package/dist/reconcile/public.d.cts +4 -77
- package/dist/reconcile/public.d.cts.map +1 -1
- package/dist/reconcile/public.d.mts +4 -77
- package/dist/reconcile/public.d.mts.map +1 -1
- package/dist/reconcile/public.mjs +1 -1
- package/dist/resolve-B1T0hUaR.mjs +170 -0
- package/dist/resolve-B1T0hUaR.mjs.map +1 -0
- package/dist/resolve-xytBTtG4.cjs +217 -0
- package/dist/resolve-xytBTtG4.cjs.map +1 -0
- package/dist/runtime-CMwtq0AL.cjs +163 -0
- package/dist/runtime-CMwtq0AL.cjs.map +1 -0
- package/dist/runtime-CXPlkZzs.d.mts +90 -0
- package/dist/runtime-CXPlkZzs.d.mts.map +1 -0
- package/dist/runtime-DbakJS8u.mjs +134 -0
- package/dist/runtime-DbakJS8u.mjs.map +1 -0
- package/dist/runtime-Dn_n-29S.d.cts +90 -0
- package/dist/runtime-Dn_n-29S.d.cts.map +1 -0
- package/dist/sandbox/config-worker.cjs +43 -0
- package/dist/sandbox/config-worker.cjs.map +1 -0
- package/dist/sandbox/config-worker.d.cts +1 -0
- package/dist/sandbox/config-worker.d.mts +1 -0
- package/dist/sandbox/config-worker.mjs +44 -0
- package/dist/sandbox/config-worker.mjs.map +1 -0
- package/dist/sandbox/discover-worker.cjs +44 -0
- package/dist/sandbox/discover-worker.cjs.map +1 -0
- package/dist/sandbox/discover-worker.d.cts +1 -0
- package/dist/sandbox/discover-worker.d.mts +1 -0
- package/dist/sandbox/discover-worker.mjs +45 -0
- package/dist/sandbox/discover-worker.mjs.map +1 -0
- package/dist/sandbox-M8UnLhXE.d.cts +126 -0
- package/dist/sandbox-M8UnLhXE.d.cts.map +1 -0
- package/dist/sandbox-M8UnLhXE.d.mts +126 -0
- package/dist/sandbox-M8UnLhXE.d.mts.map +1 -0
- package/dist/{workspace-Bp1xVaOz.mjs → schemas-Ckm_aBnF.cjs} +264 -969
- package/dist/schemas-Ckm_aBnF.cjs.map +1 -0
- package/dist/{workspace-B64Xk1Mb.cjs → schemas-D2LCF689.mjs} +195 -1155
- package/dist/schemas-D2LCF689.mjs.map +1 -0
- package/dist/{sniffer-CQmJnNJM.cjs → sniffer-D_SYc_pO.cjs} +379 -214
- package/dist/sniffer-D_SYc_pO.cjs.map +1 -0
- package/dist/{sniffer-bdleks5l.mjs → sniffer-aO_-s5vq.mjs} +346 -211
- package/dist/sniffer-aO_-s5vq.mjs.map +1 -0
- package/dist/target/public.cjs +15 -0
- package/dist/target/public.d.cts +28 -0
- package/dist/target/public.d.cts.map +1 -0
- package/dist/target/public.d.mts +28 -0
- package/dist/target/public.d.mts.map +1 -0
- package/dist/target/public.mjs +4 -0
- package/dist/terminal-D0f1u0LG.cjs +576 -0
- package/dist/terminal-D0f1u0LG.cjs.map +1 -0
- package/dist/terminal-gMxAo9Dj.mjs +517 -0
- package/dist/terminal-gMxAo9Dj.mjs.map +1 -0
- package/dist/{types-efNLu9xu.d.cts → types-CfLKGfC_.d.mts} +624 -34
- package/dist/types-CfLKGfC_.d.mts.map +1 -0
- package/dist/{types-Bp1mVxG0.d.mts → types-DIA7Li-J.d.cts} +626 -34
- package/dist/types-DIA7Li-J.d.cts.map +1 -0
- package/dist/vitest.cjs +2 -2
- package/dist/vitest.mjs +2 -2
- package/dist/workerRuntime-BXfhbe13.cjs +108 -0
- package/dist/workerRuntime-BXfhbe13.cjs.map +1 -0
- package/dist/workerRuntime-CsOyBRx2.mjs +79 -0
- package/dist/workerRuntime-CsOyBRx2.mjs.map +1 -0
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +3 -3
- package/dist/workspace/index.d.mts +3 -3
- package/dist/workspace/index.mjs +1 -1
- package/dist/workspace-Dh7rr7l4.mjs +1024 -0
- package/dist/workspace-Dh7rr7l4.mjs.map +1 -0
- package/dist/workspace-Kl4NG9IH.cjs +1196 -0
- package/dist/workspace-Kl4NG9IH.cjs.map +1 -0
- package/package.json +23 -13
- package/dist/cli-DEA_J3Sa.mjs.map +0 -1
- package/dist/cli-DQdrVkj2.cjs.map +0 -1
- package/dist/config-C5-EEdmr.mjs.map +0 -1
- package/dist/config-DXnkCEq0.cjs.map +0 -1
- package/dist/config.d.cts.map +0 -1
- package/dist/config.d.mts.map +0 -1
- package/dist/deploy-BJcLmVTc.mjs.map +0 -1
- package/dist/deploy-BbJdgQ2b.cjs.map +0 -1
- package/dist/discover-Bc-4eA_p.cjs +0 -299
- package/dist/discover-Bc-4eA_p.cjs.map +0 -1
- package/dist/discover-FrYvzkeC.mjs +0 -262
- package/dist/discover-FrYvzkeC.mjs.map +0 -1
- package/dist/sniffer-CQmJnNJM.cjs.map +0 -1
- package/dist/sniffer-bdleks5l.mjs.map +0 -1
- package/dist/types-Bp1mVxG0.d.mts.map +0 -1
- package/dist/types-efNLu9xu.d.cts.map +0 -1
- package/dist/workspace-B64Xk1Mb.cjs.map +0 -1
- package/dist/workspace-Bp1xVaOz.mjs.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const require_sniffer = require("./sniffer-
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const require_workspace = require("./workspace-B64Xk1Mb.cjs");
|
|
1
|
+
const require_sniffer = require("./sniffer-D_SYc_pO.cjs");
|
|
2
|
+
const require_discover = require("./discover-C_6COHEv.cjs");
|
|
3
|
+
const require_config = require("./config-BEJYKd4s.cjs");
|
|
4
|
+
const require_workspace = require("./workspace-Kl4NG9IH.cjs");
|
|
6
5
|
const require_storage = require("./storage-CSGoC3bK.cjs");
|
|
7
6
|
const require_store = require("./store-KvNQwYaB.cjs");
|
|
7
|
+
const require_terminal = require("./terminal-D0f1u0LG.cjs");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
let node_fs_promises = require("node:fs/promises");
|
|
10
10
|
let node_os = require("node:os");
|
|
@@ -14,96 +14,6 @@ let _geekmidas_db_pg_roles = require("@geekmidas/db/pg/roles");
|
|
|
14
14
|
let pg = require("pg");
|
|
15
15
|
let _geekmidas_cache_postgres = require("@geekmidas/cache/postgres");
|
|
16
16
|
let node_dns_promises = require("node:dns/promises");
|
|
17
|
-
//#region src/deploy/credentials.ts
|
|
18
|
-
/**
|
|
19
|
-
* How a deploy gets the credentials it acts with.
|
|
20
|
-
*
|
|
21
|
-
* `deploy()` never prompts and never reads a terminal: it asks a
|
|
22
|
-
* `CredentialProvider` and, when the provider has nothing, stops with
|
|
23
|
-
* `MissingCredential` naming what it needed and how to supply it. Whether to
|
|
24
|
-
* ask a person, read a vault or fail is the caller's decision — `gkm deploy`
|
|
25
|
-
* prompts at a terminal and stores what was typed; a CI job sets the
|
|
26
|
-
* environment; a host passes its own provider.
|
|
27
|
-
*/
|
|
28
|
-
/** How to supply each kind, for the error that says it is missing. */
|
|
29
|
-
const HOW_TO_PROVIDE = {
|
|
30
|
-
dokploy: "Set DOKPLOY_API_TOKEN (and DOKPLOY_ENDPOINT, or deploy.dokploy.endpoint in gkm.config.ts), run `gkm login --provider dokploy`, or pass them through the deploy's CredentialProvider.",
|
|
31
|
-
registry: "Add the registry in Dokploy (Settings → Docker Registry) and set deploy.dokploy.registryId, set DOCKER_REGISTRY_USERNAME and DOCKER_REGISTRY_PASSWORD, or run `gkm deploy` at a terminal to be asked for them."
|
|
32
|
-
};
|
|
33
|
-
/** A deploy needed a credential, and its provider had none. */
|
|
34
|
-
var MissingCredential = class extends Error {
|
|
35
|
-
kind;
|
|
36
|
-
target;
|
|
37
|
-
howToProvide;
|
|
38
|
-
constructor(kind, target, howToProvide = HOW_TO_PROVIDE[kind]) {
|
|
39
|
-
const what = kind === "dokploy" ? `No Dokploy credentials${target ? ` for ${target}` : ""}.` : `Dokploy has no registry for ${target ?? "the configured registry"}, and there are no credentials to create one with.`;
|
|
40
|
-
super(`${what} ${howToProvide}`);
|
|
41
|
-
this.kind = kind;
|
|
42
|
-
this.target = target;
|
|
43
|
-
this.howToProvide = howToProvide;
|
|
44
|
-
this.name = "MissingCredential";
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
/** Whatever was asked for, from the first provider that has it. */
|
|
48
|
-
function chainCredentials(...providers) {
|
|
49
|
-
return { async get(request, options) {
|
|
50
|
-
for (const provider of providers) {
|
|
51
|
-
const found = await provider.get(request, options);
|
|
52
|
-
if (found) return found;
|
|
53
|
-
}
|
|
54
|
-
} };
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Credentials from the environment, then from what `gkm login` stored. What
|
|
58
|
-
* `deploy()` uses when it is handed no provider.
|
|
59
|
-
*
|
|
60
|
-
* - Dokploy: `DOKPLOY_API_TOKEN` / `DOKPLOY_ENDPOINT`, each falling back to
|
|
61
|
-
* the stored login, and the endpoint finally to `deploy.dokploy.endpoint`.
|
|
62
|
-
* Each half is read on its own: a token is a secret and belongs in the
|
|
63
|
-
* environment, an endpoint is configuration and belongs in the config.
|
|
64
|
-
* - Registry: `DOCKER_REGISTRY_USERNAME` / `DOCKER_REGISTRY_PASSWORD`.
|
|
65
|
-
*/
|
|
66
|
-
function storedCredentials(options = {}) {
|
|
67
|
-
const env = options.env ?? process.env;
|
|
68
|
-
return { async get(asked) {
|
|
69
|
-
const request = asked;
|
|
70
|
-
switch (request.kind) {
|
|
71
|
-
case "dokploy": {
|
|
72
|
-
const stored = (await require_sniffer.readCredentials(options.home ? { home: options.home } : void 0)).dokploy;
|
|
73
|
-
const token = env.DOKPLOY_API_TOKEN ?? stored?.token;
|
|
74
|
-
const endpoint = env.DOKPLOY_ENDPOINT ?? stored?.endpoint ?? request.endpoint;
|
|
75
|
-
if (!token || !endpoint) return void 0;
|
|
76
|
-
return {
|
|
77
|
-
endpoint: endpoint.replace(/\/$/, ""),
|
|
78
|
-
token
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
case "registry": {
|
|
82
|
-
const username = env.DOCKER_REGISTRY_USERNAME;
|
|
83
|
-
const password = env.DOCKER_REGISTRY_PASSWORD;
|
|
84
|
-
if (!username || !password) return void 0;
|
|
85
|
-
return {
|
|
86
|
-
username,
|
|
87
|
-
password
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
} };
|
|
92
|
-
}
|
|
93
|
-
//#endregion
|
|
94
|
-
//#region src/deploy/events.ts
|
|
95
|
-
/** An error as an event carries it: its name and message, nothing else. */
|
|
96
|
-
function eventError(error) {
|
|
97
|
-
if (error instanceof Error) return {
|
|
98
|
-
name: error.name,
|
|
99
|
-
message: error.message
|
|
100
|
-
};
|
|
101
|
-
return {
|
|
102
|
-
name: "Error",
|
|
103
|
-
message: String(error)
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
//#endregion
|
|
107
17
|
//#region src/deploy/fromManifest.ts
|
|
108
18
|
/**
|
|
109
19
|
* The Dokploy target, read off the construct manifest.
|
|
@@ -875,7 +785,7 @@ async function createDnsProvider(options) {
|
|
|
875
785
|
if (isDnsProvider(config.provider)) return config.provider;
|
|
876
786
|
const provider = config.provider;
|
|
877
787
|
if (provider === "hostinger") {
|
|
878
|
-
const { HostingerProvider } = await Promise.resolve().then(() => require("./HostingerProvider-
|
|
788
|
+
const { HostingerProvider } = await Promise.resolve().then(() => require("./HostingerProvider-mJ7YruxH.cjs"));
|
|
879
789
|
return new HostingerProvider();
|
|
880
790
|
}
|
|
881
791
|
if (provider === "route53") {
|
|
@@ -897,7 +807,7 @@ async function createDnsProvider(options) {
|
|
|
897
807
|
*
|
|
898
808
|
* Handles automatic DNS record creation for deployed applications.
|
|
899
809
|
*/
|
|
900
|
-
const logger$
|
|
810
|
+
const logger$2 = require_discover.output;
|
|
901
811
|
/**
|
|
902
812
|
* Check if DNS config is legacy format (single domain with `domain` property)
|
|
903
813
|
*/
|
|
@@ -934,7 +844,7 @@ function groupHostnamesByDomain(appHostnames, dnsConfig) {
|
|
|
934
844
|
for (const [appName, hostname] of appHostnames) {
|
|
935
845
|
const rootDomain = findRootDomain(hostname, dnsConfig);
|
|
936
846
|
if (!rootDomain) {
|
|
937
|
-
logger$
|
|
847
|
+
logger$2.log(` ⚠ No DNS config found for hostname: ${hostname}`);
|
|
938
848
|
continue;
|
|
939
849
|
}
|
|
940
850
|
if (!grouped.has(rootDomain)) grouped.set(rootDomain, /* @__PURE__ */ new Map());
|
|
@@ -984,10 +894,10 @@ function generateRequiredRecords(appHostnames, rootDomain, serverIp) {
|
|
|
984
894
|
* Print DNS records table
|
|
985
895
|
*/
|
|
986
896
|
function printDnsRecordsTable(records, rootDomain) {
|
|
987
|
-
logger$
|
|
988
|
-
logger$
|
|
989
|
-
logger$
|
|
990
|
-
logger$
|
|
897
|
+
logger$2.log(`\n 📋 DNS Records for ${rootDomain}:`);
|
|
898
|
+
logger$2.log(" ┌─────────────────────────────────────┬──────┬─────────────────┬────────┐");
|
|
899
|
+
logger$2.log(" │ Subdomain │ Type │ Value │ Status │");
|
|
900
|
+
logger$2.log(" ├─────────────────────────────────────┼──────┼─────────────────┼────────┤");
|
|
991
901
|
for (const record of records) {
|
|
992
902
|
const subdomain = record.subdomain.padEnd(35);
|
|
993
903
|
const type = record.type.padEnd(4);
|
|
@@ -997,18 +907,18 @@ function printDnsRecordsTable(records, rootDomain) {
|
|
|
997
907
|
else if (record.created) status = "✓ new";
|
|
998
908
|
else if (record.existed) status = "✓";
|
|
999
909
|
else status = "?";
|
|
1000
|
-
logger$
|
|
910
|
+
logger$2.log(` │ ${subdomain} │ ${type} │ ${value} │ ${status.padEnd(6)} │`);
|
|
1001
911
|
}
|
|
1002
|
-
logger$
|
|
912
|
+
logger$2.log(" └─────────────────────────────────────┴──────┴─────────────────┴────────┘");
|
|
1003
913
|
}
|
|
1004
914
|
/**
|
|
1005
915
|
* Print DNS records in a simple format for manual setup
|
|
1006
916
|
*/
|
|
1007
917
|
function printDnsRecordsSimple(records, rootDomain) {
|
|
1008
|
-
logger$
|
|
1009
|
-
logger$
|
|
1010
|
-
for (const record of records) logger$
|
|
1011
|
-
logger$
|
|
918
|
+
logger$2.log("\n 📋 Required DNS Records:");
|
|
919
|
+
logger$2.log(` Add these A records to your DNS provider (${rootDomain}):\n`);
|
|
920
|
+
for (const record of records) logger$2.log(` ${record.subdomain} → ${record.value} (A record)`);
|
|
921
|
+
logger$2.log("");
|
|
1012
922
|
}
|
|
1013
923
|
/**
|
|
1014
924
|
* Create DNS records for a single domain using its configured provider
|
|
@@ -1020,7 +930,7 @@ async function createDnsRecordsForDomain(records, rootDomain, providerConfig) {
|
|
|
1020
930
|
provider = await createDnsProvider({ config: providerConfig });
|
|
1021
931
|
} catch (error) {
|
|
1022
932
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1023
|
-
logger$
|
|
933
|
+
logger$2.log(` ⚠ Failed to create DNS provider for ${rootDomain}: ${message}`);
|
|
1024
934
|
return records.map((r) => ({
|
|
1025
935
|
...r,
|
|
1026
936
|
error: message
|
|
@@ -1074,7 +984,7 @@ async function createDnsRecordsForDomain(records, rootDomain, providerConfig) {
|
|
|
1074
984
|
}
|
|
1075
985
|
} catch (error) {
|
|
1076
986
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1077
|
-
logger$
|
|
987
|
+
logger$2.log(` ⚠ Failed to create DNS records for ${rootDomain}: ${message}`);
|
|
1078
988
|
return records.map((r) => ({
|
|
1079
989
|
hostname: r.hostname,
|
|
1080
990
|
subdomain: r.subdomain,
|
|
@@ -1101,20 +1011,20 @@ async function createDnsRecordsForDomain(records, rootDomain, providerConfig) {
|
|
|
1101
1011
|
async function orchestrateDns(appHostnames, dnsConfig, dokployEndpoint, state) {
|
|
1102
1012
|
if (!dnsConfig) return null;
|
|
1103
1013
|
const normalizedConfig = normalizeDnsConfig(dnsConfig);
|
|
1104
|
-
logger$
|
|
1014
|
+
logger$2.log("\n🌐 Setting up DNS records...");
|
|
1105
1015
|
let serverIp;
|
|
1106
1016
|
try {
|
|
1107
1017
|
const endpointUrl = new URL(dokployEndpoint);
|
|
1108
1018
|
serverIp = await resolveHostnameToIp(endpointUrl.hostname);
|
|
1109
|
-
logger$
|
|
1019
|
+
logger$2.log(` Server IP: ${serverIp} (from ${endpointUrl.hostname})`);
|
|
1110
1020
|
} catch (error) {
|
|
1111
1021
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1112
|
-
logger$
|
|
1022
|
+
logger$2.log(` ⚠ Failed to resolve server IP: ${message}`);
|
|
1113
1023
|
return null;
|
|
1114
1024
|
}
|
|
1115
1025
|
const groupedHostnames = groupHostnamesByDomain(appHostnames, normalizedConfig);
|
|
1116
1026
|
if (groupedHostnames.size === 0) {
|
|
1117
|
-
logger$
|
|
1027
|
+
logger$2.log(" No DNS records needed (no hostnames match configured domains)");
|
|
1118
1028
|
return {
|
|
1119
1029
|
records: [],
|
|
1120
1030
|
success: true,
|
|
@@ -1126,22 +1036,22 @@ async function orchestrateDns(appHostnames, dnsConfig, dokployEndpoint, state) {
|
|
|
1126
1036
|
for (const [rootDomain, domainHostnames] of groupedHostnames) {
|
|
1127
1037
|
const providerConfig = normalizedConfig[rootDomain];
|
|
1128
1038
|
if (!providerConfig) {
|
|
1129
|
-
logger$
|
|
1039
|
+
logger$2.log(` ⚠ No provider config for ${rootDomain}`);
|
|
1130
1040
|
continue;
|
|
1131
1041
|
}
|
|
1132
1042
|
const providerName = typeof providerConfig.provider === "string" ? providerConfig.provider : "custom";
|
|
1133
1043
|
const requiredRecords = generateRequiredRecords(domainHostnames, rootDomain, serverIp);
|
|
1134
1044
|
if (requiredRecords.length === 0) continue;
|
|
1135
|
-
logger$
|
|
1045
|
+
logger$2.log(` Creating DNS records for ${rootDomain} (${providerName})...`);
|
|
1136
1046
|
const domainRecords = await createDnsRecordsForDomain(requiredRecords, rootDomain, providerConfig);
|
|
1137
1047
|
allRecords.push(...domainRecords);
|
|
1138
1048
|
const created = domainRecords.filter((r) => r.created).length;
|
|
1139
1049
|
const existed = domainRecords.filter((r) => r.existed).length;
|
|
1140
1050
|
const failed = domainRecords.filter((r) => r.error).length;
|
|
1141
|
-
if (created > 0) logger$
|
|
1142
|
-
if (existed > 0) logger$
|
|
1051
|
+
if (created > 0) logger$2.log(` ✓ Created ${created} DNS record(s) for ${rootDomain}`);
|
|
1052
|
+
if (existed > 0) logger$2.log(` ✓ ${existed} record(s) already exist for ${rootDomain}`);
|
|
1143
1053
|
if (failed > 0) {
|
|
1144
|
-
logger$
|
|
1054
|
+
logger$2.log(` ⚠ ${failed} record(s) failed for ${rootDomain}`);
|
|
1145
1055
|
hasFailures = true;
|
|
1146
1056
|
}
|
|
1147
1057
|
if (state) {
|
|
@@ -1178,10 +1088,10 @@ async function orchestrateDns(appHostnames, dnsConfig, dokployEndpoint, state) {
|
|
|
1178
1088
|
*/
|
|
1179
1089
|
async function verifyDnsRecords(appHostnames, serverIp, state) {
|
|
1180
1090
|
const results = [];
|
|
1181
|
-
logger$
|
|
1091
|
+
logger$2.log("\n🔍 Verifying DNS records...");
|
|
1182
1092
|
for (const [appName, hostname] of appHostnames) {
|
|
1183
1093
|
if (require_sniffer.isDnsVerified(state, hostname, serverIp)) {
|
|
1184
|
-
logger$
|
|
1094
|
+
logger$2.log(` ✓ ${hostname} (previously verified)`);
|
|
1185
1095
|
results.push({
|
|
1186
1096
|
hostname,
|
|
1187
1097
|
appName,
|
|
@@ -1195,7 +1105,7 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
|
|
|
1195
1105
|
const resolvedIp = await resolveHostnameToIp(hostname);
|
|
1196
1106
|
if (resolvedIp === serverIp) {
|
|
1197
1107
|
require_sniffer.setDnsVerification(state, hostname, serverIp);
|
|
1198
|
-
logger$
|
|
1108
|
+
logger$2.log(` ✓ ${hostname} → ${resolvedIp}`);
|
|
1199
1109
|
results.push({
|
|
1200
1110
|
hostname,
|
|
1201
1111
|
appName,
|
|
@@ -1204,7 +1114,7 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
|
|
|
1204
1114
|
expectedIp: serverIp
|
|
1205
1115
|
});
|
|
1206
1116
|
} else {
|
|
1207
|
-
logger$
|
|
1117
|
+
logger$2.log(` ⚠ ${hostname} resolves to ${resolvedIp}, expected ${serverIp}`);
|
|
1208
1118
|
results.push({
|
|
1209
1119
|
hostname,
|
|
1210
1120
|
appName,
|
|
@@ -1215,7 +1125,7 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
|
|
|
1215
1125
|
}
|
|
1216
1126
|
} catch (error) {
|
|
1217
1127
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1218
|
-
logger$
|
|
1128
|
+
logger$2.log(` ⚠ ${hostname} DNS not propagated (${message})`);
|
|
1219
1129
|
results.push({
|
|
1220
1130
|
hostname,
|
|
1221
1131
|
appName,
|
|
@@ -1229,14 +1139,14 @@ async function verifyDnsRecords(appHostnames, serverIp, state) {
|
|
|
1229
1139
|
const skipped = results.filter((r) => r.skipped).length;
|
|
1230
1140
|
const pending = results.filter((r) => !r.verified).length;
|
|
1231
1141
|
if (pending > 0) {
|
|
1232
|
-
logger$
|
|
1233
|
-
logger$
|
|
1234
|
-
} else if (skipped > 0) logger$
|
|
1142
|
+
logger$2.log(`\n ${verified} verified, ${pending} pending propagation`);
|
|
1143
|
+
logger$2.log(" DNS changes may take 5-30 minutes to propagate");
|
|
1144
|
+
} else if (skipped > 0) logger$2.log(` ${verified} verified (${skipped} from cache)`);
|
|
1235
1145
|
return results;
|
|
1236
1146
|
}
|
|
1237
1147
|
//#endregion
|
|
1238
1148
|
//#region src/deploy/docker.ts
|
|
1239
|
-
const logger$
|
|
1149
|
+
const logger$1 = require_discover.output;
|
|
1240
1150
|
/**
|
|
1241
1151
|
* The id the Dockerfile templates mount the encrypted credentials under:
|
|
1242
1152
|
* `RUN --mount=type=secret,id=gkm_credentials`.
|
|
@@ -1299,8 +1209,8 @@ async function writeCredentialsFile(credentials) {
|
|
|
1299
1209
|
* @param credentials - Encrypted credentials, passed as a build secret
|
|
1300
1210
|
*/
|
|
1301
1211
|
async function buildImage(imageRef, buildArgs, credentials, { cwd, signal, stdio }) {
|
|
1302
|
-
logger$
|
|
1303
|
-
logger$
|
|
1212
|
+
logger$1.log(`\n🔨 Building Docker image: ${imageRef}`);
|
|
1213
|
+
logger$1.log(" Generating Dockerfile for the pre-built bundle...");
|
|
1304
1214
|
await require_sniffer.dockerCommand({
|
|
1305
1215
|
slim: true,
|
|
1306
1216
|
cwd
|
|
@@ -1322,7 +1232,7 @@ async function buildImage(imageRef, buildArgs, credentials, { cwd, signal, stdio
|
|
|
1322
1232
|
...signal ? { signal } : {},
|
|
1323
1233
|
...stdio ? { stdio } : {}
|
|
1324
1234
|
});
|
|
1325
|
-
logger$
|
|
1235
|
+
logger$1.log(`✅ Image built: ${imageRef}`);
|
|
1326
1236
|
} catch (error) {
|
|
1327
1237
|
throw new require_sniffer.DockerBuildFailed(imageRef, error);
|
|
1328
1238
|
} finally {
|
|
@@ -1333,14 +1243,14 @@ async function buildImage(imageRef, buildArgs, credentials, { cwd, signal, stdio
|
|
|
1333
1243
|
* Push Docker image to registry
|
|
1334
1244
|
*/
|
|
1335
1245
|
async function pushImage(imageRef, { cwd, signal, stdio }) {
|
|
1336
|
-
logger$
|
|
1246
|
+
logger$1.log(`\n☁️ Pushing image: ${imageRef}`);
|
|
1337
1247
|
try {
|
|
1338
1248
|
await require_sniffer.run("docker", ["push", imageRef], {
|
|
1339
1249
|
cwd,
|
|
1340
1250
|
...signal ? { signal } : {},
|
|
1341
1251
|
...stdio ? { stdio } : {}
|
|
1342
1252
|
});
|
|
1343
|
-
logger$
|
|
1253
|
+
logger$1.log(`✅ Image pushed: ${imageRef}`);
|
|
1344
1254
|
} catch (error) {
|
|
1345
1255
|
throw new require_sniffer.DockerPushFailed(imageRef, error);
|
|
1346
1256
|
}
|
|
@@ -1390,17 +1300,17 @@ async function deployDocker(options) {
|
|
|
1390
1300
|
await buildImage(imageRef, buildArgs, credentials, docker);
|
|
1391
1301
|
let digest;
|
|
1392
1302
|
if (!skipPush) {
|
|
1393
|
-
if (!config.registry) logger$
|
|
1303
|
+
if (!config.registry) logger$1.warn("\n⚠️ No registry configured. Use --skip-push or configure docker.registry in gkm.config.ts");
|
|
1394
1304
|
else {
|
|
1395
1305
|
await pushImage(imageRef, docker);
|
|
1396
1306
|
digest = await pushedDigest(imageRef, docker);
|
|
1397
1307
|
}
|
|
1398
1308
|
}
|
|
1399
|
-
logger$
|
|
1400
|
-
logger$
|
|
1401
|
-
logger$
|
|
1402
|
-
logger$
|
|
1403
|
-
if (masterKey) logger$
|
|
1309
|
+
logger$1.log("\n✅ Docker deployment ready!");
|
|
1310
|
+
logger$1.log(`\n📋 Deployment details:`);
|
|
1311
|
+
logger$1.log(` Image: ${imageRef}`);
|
|
1312
|
+
logger$1.log(` Stage: ${stage}`);
|
|
1313
|
+
if (masterKey) logger$1.log(`\n🔐 Run the container with GKM_MASTER_KEY set to the key with fingerprint ${require_sniffer.keyFingerprint(masterKey)}.`);
|
|
1404
1314
|
return {
|
|
1405
1315
|
imageRef,
|
|
1406
1316
|
...digest ? { digest } : {},
|
|
@@ -1911,83 +1821,6 @@ function generateSecretsReport(encryptedApps, sniffedApps) {
|
|
|
1911
1821
|
};
|
|
1912
1822
|
}
|
|
1913
1823
|
//#endregion
|
|
1914
|
-
//#region src/deploy/terminal.ts
|
|
1915
|
-
/**
|
|
1916
|
-
* The credentials `gkm deploy` can ask a person for. CLI layer only.
|
|
1917
|
-
*
|
|
1918
|
-
* `deploy()` asks its `CredentialProvider` and stops with `MissingCredential`
|
|
1919
|
-
* when the answer is nothing. At a terminal, `gkm deploy` would rather ask:
|
|
1920
|
-
* this provider reads the environment and the stored login first, and only
|
|
1921
|
-
* when both are empty prompts — and stores a Dokploy login it validated, so
|
|
1922
|
-
* the next deploy does not ask again. With no terminal it answers nothing, and
|
|
1923
|
-
* the deploy says what was missing instead of waiting on a prompt nobody sees.
|
|
1924
|
-
*/
|
|
1925
|
-
const logger$1 = require_discover.output;
|
|
1926
|
-
/** What answers a deploy prompt without a terminal. */
|
|
1927
|
-
const INSTEAD = "Please configure manually.";
|
|
1928
|
-
/** The Dokploy URL typed at the prompt is not a URL. */
|
|
1929
|
-
var DokployEndpointInvalid = class extends Error {
|
|
1930
|
-
endpoint;
|
|
1931
|
-
constructor(endpoint) {
|
|
1932
|
-
super("Invalid URL format");
|
|
1933
|
-
this.endpoint = endpoint;
|
|
1934
|
-
this.name = "DokployEndpointInvalid";
|
|
1935
|
-
}
|
|
1936
|
-
};
|
|
1937
|
-
/** Dokploy refused the token typed at the prompt; nothing was stored. */
|
|
1938
|
-
var DokployTokenRejected = class extends Error {
|
|
1939
|
-
endpoint;
|
|
1940
|
-
constructor(endpoint) {
|
|
1941
|
-
super("Invalid credentials. Please check your token.");
|
|
1942
|
-
this.endpoint = endpoint;
|
|
1943
|
-
this.name = "DokployTokenRejected";
|
|
1944
|
-
}
|
|
1945
|
-
};
|
|
1946
|
-
/** Asks the person at the terminal for what nothing else supplied. */
|
|
1947
|
-
function asking() {
|
|
1948
|
-
return { async get(asked) {
|
|
1949
|
-
if (!require_sniffer.canPrompt()) return void 0;
|
|
1950
|
-
const request = asked;
|
|
1951
|
-
if (request.kind === "dokploy") {
|
|
1952
|
-
logger$1.log("\n📋 Dokploy credentials not found. Let's set them up.");
|
|
1953
|
-
const endpoint = (await require_sniffer.prompt("Dokploy URL (e.g., https://dokploy.example.com): ", { instead: INSTEAD })).replace(/\/$/, "");
|
|
1954
|
-
try {
|
|
1955
|
-
new URL(endpoint);
|
|
1956
|
-
} catch {
|
|
1957
|
-
throw new DokployEndpointInvalid(endpoint);
|
|
1958
|
-
}
|
|
1959
|
-
logger$1.log(`\nGenerate a token at: ${endpoint}/settings/profile\n`);
|
|
1960
|
-
const token = await require_sniffer.prompt("API Token: ", {
|
|
1961
|
-
hidden: true,
|
|
1962
|
-
instead: INSTEAD
|
|
1963
|
-
});
|
|
1964
|
-
logger$1.log("\nValidating credentials...");
|
|
1965
|
-
if (!await require_sniffer.validateDokployToken(endpoint, token)) throw new DokployTokenRejected(endpoint);
|
|
1966
|
-
await require_sniffer.storeDokployCredentials(token, endpoint);
|
|
1967
|
-
logger$1.log("✓ Credentials saved");
|
|
1968
|
-
return {
|
|
1969
|
-
endpoint,
|
|
1970
|
-
token
|
|
1971
|
-
};
|
|
1972
|
-
}
|
|
1973
|
-
logger$1.log(` Dokploy has no registry for ${request.url}. Let's create one.`);
|
|
1974
|
-
return {
|
|
1975
|
-
username: await require_sniffer.prompt("Registry username: ", { instead: INSTEAD }),
|
|
1976
|
-
password: await require_sniffer.prompt("Registry password/token: ", {
|
|
1977
|
-
hidden: true,
|
|
1978
|
-
instead: INSTEAD
|
|
1979
|
-
})
|
|
1980
|
-
};
|
|
1981
|
-
} };
|
|
1982
|
-
}
|
|
1983
|
-
/**
|
|
1984
|
-
* The environment, then the stored login, then — at a terminal — the person
|
|
1985
|
-
* running the command.
|
|
1986
|
-
*/
|
|
1987
|
-
function terminalCredentials(base = storedCredentials()) {
|
|
1988
|
-
return chainCredentials(base, asking());
|
|
1989
|
-
}
|
|
1990
|
-
//#endregion
|
|
1991
1824
|
//#region src/deploy/index.ts
|
|
1992
1825
|
/**
|
|
1993
1826
|
* Deploy Module
|
|
@@ -2188,22 +2021,6 @@ function getServerHostname(endpoint) {
|
|
|
2188
2021
|
return new URL(endpoint).hostname;
|
|
2189
2022
|
}
|
|
2190
2023
|
/**
|
|
2191
|
-
* Generate image tag from stage and timestamp
|
|
2192
|
-
*/
|
|
2193
|
-
function generateTag(stage) {
|
|
2194
|
-
return `${stage}-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19)}`;
|
|
2195
|
-
}
|
|
2196
|
-
/**
|
|
2197
|
-
* The things this deploy creates a container for.
|
|
2198
|
-
*
|
|
2199
|
-
* A deploy unit is a *declaration*, not a config entry — and since that is now
|
|
2200
|
-
* true of every app, not just the ones being deployed, this is the workspace's
|
|
2201
|
-
* own derivation under the name the deploy phases call it by.
|
|
2202
|
-
*/
|
|
2203
|
-
function deployUnits(manifest, workspace) {
|
|
2204
|
-
return require_config.derivedApps(manifest, workspace);
|
|
2205
|
-
}
|
|
2206
|
-
/**
|
|
2207
2024
|
* The variables an app cannot start without.
|
|
2208
2025
|
*
|
|
2209
2026
|
* The sniffer reports every key it saw in `requiredEnvVars` and says which of
|
|
@@ -2221,26 +2038,6 @@ function requiredOf(requirements) {
|
|
|
2221
2038
|
const optional = new Set(requirements.optionalEnvVars);
|
|
2222
2039
|
return requirements.requiredEnvVars.map((name) => name.endsWith("?") ? name.slice(0, -1) : name).filter((name) => !optional.has(name));
|
|
2223
2040
|
}
|
|
2224
|
-
/** Apps were asked for by name that the workspace does not have. */
|
|
2225
|
-
var UnknownDeployApps = class extends Error {
|
|
2226
|
-
apps;
|
|
2227
|
-
available;
|
|
2228
|
-
constructor(apps, available) {
|
|
2229
|
-
super(`Unknown apps: ${apps.join(", ")}\nAvailable apps: ${available.join(", ")}`);
|
|
2230
|
-
this.apps = apps;
|
|
2231
|
-
this.available = available;
|
|
2232
|
-
this.name = "UnknownDeployApps";
|
|
2233
|
-
}
|
|
2234
|
-
};
|
|
2235
|
-
/** Every app asked for deploys somewhere other than Dokploy. */
|
|
2236
|
-
var NoDeployableApps = class extends Error {
|
|
2237
|
-
stage;
|
|
2238
|
-
constructor(stage) {
|
|
2239
|
-
super("No apps to deploy. All selected apps have unsupported deploy targets.");
|
|
2240
|
-
this.stage = stage;
|
|
2241
|
-
this.name = "NoDeployableApps";
|
|
2242
|
-
}
|
|
2243
|
-
};
|
|
2244
2041
|
/** A backend failed, so the run stopped before deploying anything after it. */
|
|
2245
2042
|
var BackendDeployFailed = class extends Error {
|
|
2246
2043
|
app;
|
|
@@ -2263,23 +2060,24 @@ var MissingEnvVars = class extends Error {
|
|
|
2263
2060
|
this.name = "MissingEnvVars";
|
|
2264
2061
|
}
|
|
2265
2062
|
};
|
|
2266
|
-
/** Workspace deploys go to Dokploy; another provider was asked for. */
|
|
2267
|
-
var DeployProviderUnsupported = class extends Error {
|
|
2268
|
-
provider;
|
|
2269
|
-
constructor(provider) {
|
|
2270
|
-
super(`Workspace deployment only supports Dokploy. Got: ${provider}`);
|
|
2271
|
-
this.provider = provider;
|
|
2272
|
-
this.name = "DeployProviderUnsupported";
|
|
2273
|
-
}
|
|
2274
|
-
};
|
|
2275
2063
|
/** How `resolveProject` found a project, in the journal's words. */
|
|
2276
2064
|
const PROJECT_VIA = {
|
|
2277
2065
|
state: "recorded",
|
|
2278
2066
|
marker: "found",
|
|
2279
2067
|
created: "created"
|
|
2280
2068
|
};
|
|
2069
|
+
/** `childOutput` as `spawn` reads it, where it is not the default. */
|
|
2070
|
+
const CHILD_STDIO = {
|
|
2071
|
+
stderr: [
|
|
2072
|
+
"ignore",
|
|
2073
|
+
2,
|
|
2074
|
+
2
|
|
2075
|
+
],
|
|
2076
|
+
ignore: "ignore"
|
|
2077
|
+
};
|
|
2281
2078
|
/**
|
|
2282
|
-
* Deploy every app in a workspace to Dokploy
|
|
2079
|
+
* Deploy every app in a workspace to Dokploy: the engine under the built-in
|
|
2080
|
+
* `dokploy` target.
|
|
2283
2081
|
*
|
|
2284
2082
|
* Two-phase orchestration:
|
|
2285
2083
|
* - PHASE 1: Deploy backend apps (with encrypted secrets)
|
|
@@ -2290,119 +2088,60 @@ const PROJECT_VIA = {
|
|
|
2290
2088
|
* - Only GKM_MASTER_KEY is injected as Dokploy env var
|
|
2291
2089
|
* - Frontend apps get public URLs baked in at build time (no secrets)
|
|
2292
2090
|
*
|
|
2293
|
-
* The
|
|
2294
|
-
*
|
|
2295
|
-
* `ctx.emit` and to `output`, and every failure is thrown.
|
|
2091
|
+
* The run around it — the target, the apps, the lock, the phase events — is
|
|
2092
|
+
* `runDeploy`'s. This says what it is doing and checks what Dokploy needs.
|
|
2296
2093
|
*
|
|
2297
2094
|
* @internal
|
|
2298
2095
|
*/
|
|
2299
|
-
async function
|
|
2300
|
-
const { stage,
|
|
2301
|
-
ctx
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
cwd: configured.root
|
|
2309
|
-
});
|
|
2310
|
-
const units = deployUnits(manifest, configured);
|
|
2311
|
-
const workspace = Object.keys(units).length > 0 ? {
|
|
2312
|
-
...configured,
|
|
2313
|
-
apps: units
|
|
2314
|
-
} : configured;
|
|
2315
|
-
const identity = require_store.deployIdentity(workspace, stage);
|
|
2096
|
+
async function validateDokploy(phase) {
|
|
2097
|
+
const { workspace, stage, identity, tag: imageTag } = phase;
|
|
2098
|
+
const ctx = {
|
|
2099
|
+
emit: phase.emit,
|
|
2100
|
+
credentials: phase.credentials,
|
|
2101
|
+
signal: phase.signal,
|
|
2102
|
+
dryRun: phase.dryRun,
|
|
2103
|
+
...phase.childOutput !== "inherit" ? { stdio: CHILD_STDIO[phase.childOutput] } : {}
|
|
2104
|
+
};
|
|
2316
2105
|
logger.log(`\n🚀 Deploying workspace "${workspace.name}" to Dokploy...`);
|
|
2317
2106
|
logger.log(` Stage: ${stage}`);
|
|
2318
|
-
const imageTag = tag ?? generateTag(stage);
|
|
2319
2107
|
logger.log(` Tag: ${imageTag}`);
|
|
2320
|
-
const
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
logger.log(` Deploying apps: ${appsToDeployNames.join(", ")}`);
|
|
2327
|
-
} else logger.log(` Deploying all apps: ${appsToDeployNames.join(", ")}`);
|
|
2328
|
-
const skipped = [];
|
|
2329
|
-
const skip = (app, reason) => {
|
|
2330
|
-
skipped.push({
|
|
2331
|
-
app,
|
|
2332
|
-
reason
|
|
2333
|
-
});
|
|
2334
|
-
ctx.emit({
|
|
2335
|
-
type: "app.skipped",
|
|
2336
|
-
app,
|
|
2337
|
-
reason
|
|
2338
|
-
});
|
|
2339
|
-
};
|
|
2340
|
-
const dokployApps = appsToDeployNames.filter((name) => {
|
|
2341
|
-
const target = workspace.apps[name].resolvedDeployTarget;
|
|
2342
|
-
if (target === "sst") {
|
|
2343
|
-
const reason = `it deploys with SST — run \`gkm build && sst deploy --stage ${stage}\``;
|
|
2344
|
-
logger.log(` ⚠️ Skipping ${name}: ${reason}`);
|
|
2345
|
-
skip(name, reason);
|
|
2346
|
-
return false;
|
|
2347
|
-
}
|
|
2348
|
-
if (!require_workspace.isDeployTargetSupported(target)) {
|
|
2349
|
-
const reason = require_workspace.getDeployTargetError(target, name);
|
|
2350
|
-
logger.log(` ⚠️ Skipping ${name}: ${reason}`);
|
|
2351
|
-
skip(name, reason);
|
|
2352
|
-
return false;
|
|
2353
|
-
}
|
|
2354
|
-
return true;
|
|
2355
|
-
});
|
|
2356
|
-
if (dokployApps.length === 0) throw new NoDeployableApps(stage);
|
|
2357
|
-
appsToDeployNames = dokployApps;
|
|
2358
|
-
for (const name of appsToDeployNames) if (workspace.apps[name].type === "mobile") skip(name, MOBILE_SKIP_REASON);
|
|
2359
|
-
ctx.emit({
|
|
2360
|
-
type: "deploy.started",
|
|
2361
|
-
stage,
|
|
2362
|
-
identity: identity.key,
|
|
2363
|
-
tag: imageTag,
|
|
2364
|
-
apps: appsToDeployNames.filter((name) => workspace.apps[name].type !== "mobile"),
|
|
2365
|
-
dryRun: ctx.dryRun
|
|
2366
|
-
});
|
|
2367
|
-
const store = await require_sniffer.createStateStore({
|
|
2368
|
-
config: workspace.state,
|
|
2369
|
-
workspaceRoot: workspace.root,
|
|
2370
|
-
workspaceName: workspace.name
|
|
2371
|
-
});
|
|
2108
|
+
const askedFor = /* @__PURE__ */ new Set([...phase.apps, ...phase.skipped.map((skipped) => skipped.app)]);
|
|
2109
|
+
const asked = require_workspace.getAppBuildOrder(workspace).filter((name) => askedFor.has(name));
|
|
2110
|
+
logger.log(asked.length === Object.keys(workspace.apps).length ? ` Deploying all apps: ${asked.join(", ")}` : ` Deploying apps: ${asked.join(", ")}`);
|
|
2111
|
+
for (const { app, reason } of phase.skipped) logger.log(` ⚠️ Skipping ${app}: ${reason}`);
|
|
2112
|
+
const appsToDeployNames = [...phase.apps];
|
|
2113
|
+
for (const name of appsToDeployNames) if (workspace.apps[name].type === "mobile") phase.skip(name, MOBILE_SKIP_REASON);
|
|
2372
2114
|
const run = {
|
|
2373
2115
|
workspace,
|
|
2374
|
-
manifest,
|
|
2116
|
+
manifest: phase.manifest,
|
|
2375
2117
|
stage,
|
|
2376
2118
|
imageTag,
|
|
2377
2119
|
appsToDeployNames,
|
|
2378
2120
|
identity,
|
|
2379
|
-
store,
|
|
2380
|
-
skipped,
|
|
2121
|
+
store: phase.state,
|
|
2122
|
+
skipped: phase.skipped,
|
|
2123
|
+
secrets: phase.secrets,
|
|
2381
2124
|
ctx
|
|
2382
2125
|
};
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
} finally {
|
|
2388
|
-
await lock.release();
|
|
2389
|
-
}
|
|
2126
|
+
return {
|
|
2127
|
+
...run,
|
|
2128
|
+
preflight: await preflight(run)
|
|
2129
|
+
};
|
|
2390
2130
|
}
|
|
2391
2131
|
/**
|
|
2392
2132
|
* The stage's secrets and every app's environment requirements. A dry run
|
|
2393
2133
|
* reads the secrets and generates nothing into the store.
|
|
2394
2134
|
*/
|
|
2395
|
-
async function preflight({ workspace, manifest, stage, ctx }) {
|
|
2135
|
+
async function preflight({ workspace, manifest, stage, secrets: secretsStore, ctx }) {
|
|
2396
2136
|
logger.log("\n🔐 Loading secrets and analyzing environment requirements...");
|
|
2397
|
-
const
|
|
2398
|
-
const stored = await secretsStore.read(stage);
|
|
2137
|
+
const stored = await secretsStore.read();
|
|
2399
2138
|
if (!stored) logger.log(` ⚠️ No secrets found for stage "${stage}"; starting them`);
|
|
2400
2139
|
const { secrets: stageSecrets, generated } = require_sniffer.withGeneratedSecrets(stored ?? require_storage.initStageSecrets(stage), manifest);
|
|
2401
2140
|
if (generated.length > 0) {
|
|
2402
|
-
if (ctx.dryRun) logger.log(` 🔑 Would generate for "${stage}" (${secretsStore.
|
|
2141
|
+
if (ctx.dryRun) logger.log(` 🔑 Would generate for "${stage}" (${secretsStore.store}): ${generated.join(", ")}`);
|
|
2403
2142
|
else {
|
|
2404
|
-
await secretsStore.write(
|
|
2405
|
-
logger.log(` 🔑 Generated for "${stage}" (${secretsStore.
|
|
2143
|
+
await secretsStore.write(stageSecrets);
|
|
2144
|
+
logger.log(` 🔑 Generated for "${stage}" (${secretsStore.store}): ${generated.join(", ")}`);
|
|
2406
2145
|
}
|
|
2407
2146
|
}
|
|
2408
2147
|
const sniffedApps = await require_sniffer.sniffAllApps(workspace.apps, workspace.root);
|
|
@@ -2418,14 +2157,14 @@ async function preflight({ workspace, manifest, stage, ctx }) {
|
|
|
2418
2157
|
encryptedSecrets
|
|
2419
2158
|
};
|
|
2420
2159
|
}
|
|
2421
|
-
/**
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
}
|
|
2160
|
+
/**
|
|
2161
|
+
* The project, environment and registry, then what the manifest declares.
|
|
2162
|
+
* Each is looked up — by the id the stage's state recorded, else by name —
|
|
2163
|
+
* before it is created, so a run stopped part way is finished by the next.
|
|
2164
|
+
*/
|
|
2165
|
+
async function provisionDokploy(run) {
|
|
2166
|
+
const { workspace, manifest, stage, appsToDeployNames, identity, store, ctx } = run;
|
|
2167
|
+
const { stageSecrets } = run.preflight;
|
|
2429
2168
|
const changes = [];
|
|
2430
2169
|
const applied = (change, via) => {
|
|
2431
2170
|
changes.push(change);
|
|
@@ -2435,11 +2174,6 @@ async function deployLocked(run) {
|
|
|
2435
2174
|
via
|
|
2436
2175
|
});
|
|
2437
2176
|
};
|
|
2438
|
-
ctx.signal?.throwIfAborted();
|
|
2439
|
-
ctx.emit({
|
|
2440
|
-
type: "phase.started",
|
|
2441
|
-
phase: "provision"
|
|
2442
|
-
});
|
|
2443
2177
|
const { api, endpoint } = await dokployApi(workspace, ctx);
|
|
2444
2178
|
logger.log("\n📋 Loading deploy state...");
|
|
2445
2179
|
const journal = await DeployJournal.open(store, stage, () => require_sniffer.createEmptyState(stage, "", ""));
|
|
@@ -2511,7 +2245,7 @@ async function deployLocked(run) {
|
|
|
2511
2245
|
kind: "registry",
|
|
2512
2246
|
url
|
|
2513
2247
|
}, { signal: ctx.signal });
|
|
2514
|
-
if (!login) throw new MissingCredential("registry", url);
|
|
2248
|
+
if (!login) throw new require_terminal.MissingCredential("registry", url);
|
|
2515
2249
|
const created = await api.createRegistry("Default Registry", url, login.username, login.password);
|
|
2516
2250
|
registryCreated = true;
|
|
2517
2251
|
logger.log(` ✓ Registry created: ${created.registryId}`);
|
|
@@ -2595,10 +2329,34 @@ async function deployLocked(run) {
|
|
|
2595
2329
|
logger.log(` ✓ Postgres backup schedule created (${backupSchedule})`);
|
|
2596
2330
|
} else logger.log(" ✓ Using existing postgres backup schedule");
|
|
2597
2331
|
}
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2332
|
+
run.provisioned = {
|
|
2333
|
+
api,
|
|
2334
|
+
endpoint,
|
|
2335
|
+
journal,
|
|
2336
|
+
state,
|
|
2337
|
+
projectId: project.projectId,
|
|
2338
|
+
environmentId,
|
|
2339
|
+
registry,
|
|
2340
|
+
registryId,
|
|
2341
|
+
declaredEnv,
|
|
2342
|
+
changes,
|
|
2343
|
+
applied
|
|
2344
|
+
};
|
|
2345
|
+
}
|
|
2346
|
+
/**
|
|
2347
|
+
* Each app's image built and pushed, its application configured and
|
|
2348
|
+
* deployed, and its domain attached: backends first, each failure stopping
|
|
2349
|
+
* the run; then sites, whose build args are the backends' public URLs.
|
|
2350
|
+
*
|
|
2351
|
+
* Building is here rather than in a `build` phase of its own because an
|
|
2352
|
+
* image is built beside its application — a site's build args are resolved
|
|
2353
|
+
* per app, against the backends released before it.
|
|
2354
|
+
*/
|
|
2355
|
+
async function releaseDokploy(run) {
|
|
2356
|
+
const { workspace, stage, imageTag, appsToDeployNames, identity, ctx } = run;
|
|
2357
|
+
const { stageSecrets, sniffedApps, encryptedSecrets } = run.preflight;
|
|
2358
|
+
const { api, journal, state, environmentId, registry, registryId, declaredEnv, changes, applied } = run.provisioned;
|
|
2359
|
+
const project = { projectId: run.provisioned.projectId };
|
|
2602
2360
|
const backendApps = appsToDeployNames.filter((name) => workspace.apps[name].type === "backend");
|
|
2603
2361
|
const frontendApps = appsToDeployNames.filter((name) => workspace.apps[name].type === "web");
|
|
2604
2362
|
const publicUrls = {};
|
|
@@ -2634,7 +2392,7 @@ async function deployLocked(run) {
|
|
|
2634
2392
|
ctx.emit({
|
|
2635
2393
|
type: "app.failed",
|
|
2636
2394
|
app: appName,
|
|
2637
|
-
error: eventError(error)
|
|
2395
|
+
error: require_terminal.eventError(error)
|
|
2638
2396
|
});
|
|
2639
2397
|
};
|
|
2640
2398
|
/** An image is pushed: worth keeping even if what follows fails. */
|
|
@@ -2659,11 +2417,6 @@ async function deployLocked(run) {
|
|
|
2659
2417
|
};
|
|
2660
2418
|
const frontendUrls = [];
|
|
2661
2419
|
for (const appName of frontendApps) frontendUrls.push(`https://${hostOf(workspace, appName, stage)}`);
|
|
2662
|
-
ctx.signal?.throwIfAborted();
|
|
2663
|
-
ctx.emit({
|
|
2664
|
-
type: "phase.started",
|
|
2665
|
-
phase: "release"
|
|
2666
|
-
});
|
|
2667
2420
|
if (backendApps.length > 0) {
|
|
2668
2421
|
logger.log("\n📦 PHASE 1: Deploying backend applications...");
|
|
2669
2422
|
for (const appName of backendApps) {
|
|
@@ -2829,15 +2582,17 @@ async function deployLocked(run) {
|
|
|
2829
2582
|
logger.log("\n📋 Saving deploy state...");
|
|
2830
2583
|
await journal.save();
|
|
2831
2584
|
logger.log(" ✓ State saved");
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
}
|
|
2585
|
+
run.released = {
|
|
2586
|
+
results,
|
|
2587
|
+
publicUrls,
|
|
2588
|
+
appHostnames
|
|
2589
|
+
};
|
|
2590
|
+
}
|
|
2591
|
+
/** DNS records for each released app, and Dokploy's validation of each domain. */
|
|
2592
|
+
async function verifyDokploy(run) {
|
|
2593
|
+
const { workspace } = run;
|
|
2594
|
+
const { api, endpoint, journal, state } = run.provisioned;
|
|
2595
|
+
const { appHostnames } = run.released;
|
|
2841
2596
|
const dnsConfig = workspace.deploy.dns;
|
|
2842
2597
|
if (dnsConfig && appHostnames.size > 0) {
|
|
2843
2598
|
const dnsResult = await orchestrateDns(appHostnames, dnsConfig, endpoint);
|
|
@@ -2857,10 +2612,14 @@ async function deployLocked(run) {
|
|
|
2857
2612
|
}
|
|
2858
2613
|
}
|
|
2859
2614
|
}
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2615
|
+
}
|
|
2616
|
+
/** What the run did, printed as the summary it always ended with. */
|
|
2617
|
+
function dokployResult(run) {
|
|
2618
|
+
if (run.result) return run.result;
|
|
2619
|
+
const { stage, identity, imageTag } = run;
|
|
2620
|
+
const { projectId, environmentId, changes } = run.provisioned;
|
|
2621
|
+
const { results, publicUrls } = run.released;
|
|
2622
|
+
const project = { projectId };
|
|
2864
2623
|
const successCount = results.filter((r) => r.success).length;
|
|
2865
2624
|
const failedCount = results.filter((r) => !r.success).length;
|
|
2866
2625
|
logger.log(`\n${"─".repeat(50)}`);
|
|
@@ -2882,7 +2641,7 @@ async function deployLocked(run) {
|
|
|
2882
2641
|
identity: identity.key,
|
|
2883
2642
|
tag: imageTag,
|
|
2884
2643
|
dryRun: false,
|
|
2885
|
-
skipped: run.skipped,
|
|
2644
|
+
skipped: [...run.skipped],
|
|
2886
2645
|
urls: publicUrls,
|
|
2887
2646
|
changes
|
|
2888
2647
|
};
|
|
@@ -2983,7 +2742,7 @@ async function dokployApi(workspace, ctx) {
|
|
|
2983
2742
|
kind: "dokploy",
|
|
2984
2743
|
...configured ? { endpoint: configured } : {}
|
|
2985
2744
|
}, { signal: ctx.signal });
|
|
2986
|
-
if (!creds) throw new MissingCredential("dokploy", configured);
|
|
2745
|
+
if (!creds) throw new require_terminal.MissingCredential("dokploy", configured);
|
|
2987
2746
|
return {
|
|
2988
2747
|
api: new require_sniffer.DokployApi({
|
|
2989
2748
|
baseUrl: creds.endpoint,
|
|
@@ -3003,19 +2762,9 @@ function hostOf(workspace, appName, stage) {
|
|
|
3003
2762
|
* else: no lock, no state written, no secret generated, no Dokploy resource
|
|
3004
2763
|
* created or changed, no image built or pushed.
|
|
3005
2764
|
*/
|
|
3006
|
-
async function
|
|
2765
|
+
async function planDokploy(run) {
|
|
3007
2766
|
const { workspace, manifest, stage, imageTag, appsToDeployNames, identity } = run;
|
|
3008
2767
|
const { ctx } = run;
|
|
3009
|
-
await preflight(run);
|
|
3010
|
-
ctx.emit({
|
|
3011
|
-
type: "phase.finished",
|
|
3012
|
-
phase: "validate"
|
|
3013
|
-
});
|
|
3014
|
-
ctx.signal?.throwIfAborted();
|
|
3015
|
-
ctx.emit({
|
|
3016
|
-
type: "phase.started",
|
|
3017
|
-
phase: "plan"
|
|
3018
|
-
});
|
|
3019
2768
|
logger.log("\n🔎 Dry run: nothing will be created, changed, built or pushed.");
|
|
3020
2769
|
const changes = [];
|
|
3021
2770
|
const plan = (change, detail) => {
|
|
@@ -3130,11 +2879,7 @@ async function planDeploy(run) {
|
|
|
3130
2879
|
}
|
|
3131
2880
|
const creates = changes.filter((c) => c.action !== "reuse").length;
|
|
3132
2881
|
logger.log(`\n✅ Dry run complete: ${creates} to create or build, ${changes.length - creates} to reuse.`);
|
|
3133
|
-
|
|
3134
|
-
type: "phase.finished",
|
|
3135
|
-
phase: "plan"
|
|
3136
|
-
});
|
|
3137
|
-
return {
|
|
2882
|
+
run.result = {
|
|
3138
2883
|
apps,
|
|
3139
2884
|
projectId: project?.projectId ?? "",
|
|
3140
2885
|
environmentId: environment?.environmentId ?? "",
|
|
@@ -3144,7 +2889,7 @@ async function planDeploy(run) {
|
|
|
3144
2889
|
identity: identity.key,
|
|
3145
2890
|
tag: imageTag,
|
|
3146
2891
|
dryRun: true,
|
|
3147
|
-
skipped: run.skipped,
|
|
2892
|
+
skipped: [...run.skipped],
|
|
3148
2893
|
urls,
|
|
3149
2894
|
changes
|
|
3150
2895
|
};
|
|
@@ -3152,161 +2897,18 @@ async function planDeploy(run) {
|
|
|
3152
2897
|
/** Why a mobile app is left out of a Dokploy deploy. */
|
|
3153
2898
|
const MOBILE_SKIP_REASON = "deploys via its framework toolchain";
|
|
3154
2899
|
//#endregion
|
|
3155
|
-
//#region src/deploy/deploy.ts
|
|
3156
|
-
/**
|
|
3157
|
-
* `deploy()`: a deploy as a library call.
|
|
3158
|
-
*
|
|
3159
|
-
* `gkm deploy` could only be driven from an interactive terminal: it prompted
|
|
3160
|
-
* for what it lacked and exited the process on failure, worked out of
|
|
3161
|
-
* `process.cwd()`, and reported progress by printing. Here the caller says
|
|
3162
|
-
* where the project is, hands over the credentials and a signal, and gets back
|
|
3163
|
-
* a run — events to iterate while it goes, and a structured result at the end.
|
|
3164
|
-
* Nothing below this asks a person anything or ends the process; `gkm deploy`
|
|
3165
|
-
* is a thin wrapper that does both.
|
|
3166
|
-
*/
|
|
3167
|
-
/**
|
|
3168
|
-
* Every event a run emits, kept so that each iteration — however late it
|
|
3169
|
-
* starts — sees the run from its first event to its last.
|
|
3170
|
-
*/
|
|
3171
|
-
var EventLog = class {
|
|
3172
|
-
events = [];
|
|
3173
|
-
closed = false;
|
|
3174
|
-
waiting = [];
|
|
3175
|
-
push(event) {
|
|
3176
|
-
this.events.push(event);
|
|
3177
|
-
this.wake();
|
|
3178
|
-
}
|
|
3179
|
-
close() {
|
|
3180
|
-
this.closed = true;
|
|
3181
|
-
this.wake();
|
|
3182
|
-
}
|
|
3183
|
-
wake() {
|
|
3184
|
-
const waiting = this.waiting;
|
|
3185
|
-
this.waiting = [];
|
|
3186
|
-
for (const resume of waiting) resume();
|
|
3187
|
-
}
|
|
3188
|
-
async *iterate() {
|
|
3189
|
-
let next = 0;
|
|
3190
|
-
while (true) if (next < this.events.length) yield this.events[next++];
|
|
3191
|
-
else if (this.closed) return;
|
|
3192
|
-
else await new Promise((resume) => this.waiting.push(resume));
|
|
3193
|
-
}
|
|
3194
|
-
};
|
|
3195
|
-
/** `childOutput` as `spawn` reads it, where it is not the default. */
|
|
3196
|
-
const CHILD_STDIO = {
|
|
3197
|
-
stderr: [
|
|
3198
|
-
"ignore",
|
|
3199
|
-
2,
|
|
3200
|
-
2
|
|
3201
|
-
],
|
|
3202
|
-
ignore: "ignore"
|
|
3203
|
-
};
|
|
3204
|
-
function forward(logger, level, message) {
|
|
3205
|
-
if (!logger) return;
|
|
3206
|
-
if (level === "info") logger.info(message);
|
|
3207
|
-
else if (level === "error" && logger.error) logger.error(message);
|
|
3208
|
-
else logger.warn(message);
|
|
3209
|
-
}
|
|
3210
|
-
/**
|
|
3211
|
-
* Deploy a project's stage.
|
|
3212
|
-
*
|
|
3213
|
-
* ```ts
|
|
3214
|
-
* import { deploy } from '@geekmidas/cli/deploy';
|
|
3215
|
-
*
|
|
3216
|
-
* const run = deploy({ cwd: '/srv/checkouts/shop', stage: 'production' });
|
|
3217
|
-
* for await (const event of run) {
|
|
3218
|
-
* if (event.type === 'app.deployed') console.log(event.app, event.url);
|
|
3219
|
-
* }
|
|
3220
|
-
* const result = await run.result;
|
|
3221
|
-
* ```
|
|
3222
|
-
*
|
|
3223
|
-
* The run starts at once; iterating it is optional, and an iteration started
|
|
3224
|
-
* late still sees every event from the first.
|
|
3225
|
-
*/
|
|
3226
|
-
function deploy(input) {
|
|
3227
|
-
const log = new EventLog();
|
|
3228
|
-
const emit = (event) => {
|
|
3229
|
-
log.push(event);
|
|
3230
|
-
if (event.type === "log") forward(input.logger, event.level, event.message);
|
|
3231
|
-
};
|
|
3232
|
-
const ctx = {
|
|
3233
|
-
emit,
|
|
3234
|
-
credentials: input.credentials ?? storedCredentials({ home: input.home ?? require_home.gkmHome() }),
|
|
3235
|
-
dryRun: input.dryRun ?? false,
|
|
3236
|
-
home: input.home ?? require_home.gkmHome(),
|
|
3237
|
-
...input.signal ? { signal: input.signal } : {},
|
|
3238
|
-
...input.childOutput && input.childOutput !== "inherit" ? { stdio: CHILD_STDIO[input.childOutput] } : {}
|
|
3239
|
-
};
|
|
3240
|
-
const result = require_discover.withOutput((level, message) => emit({
|
|
3241
|
-
type: "log",
|
|
3242
|
-
level,
|
|
3243
|
-
message
|
|
3244
|
-
}), async () => {
|
|
3245
|
-
try {
|
|
3246
|
-
input.signal?.throwIfAborted();
|
|
3247
|
-
const deployed = await runDeploy(() => load(input), {
|
|
3248
|
-
stage: input.stage,
|
|
3249
|
-
...input.tag ? { tag: input.tag } : {},
|
|
3250
|
-
...input.apps ? { apps: input.apps } : {}
|
|
3251
|
-
}, ctx);
|
|
3252
|
-
emit({
|
|
3253
|
-
type: "deploy.finished",
|
|
3254
|
-
result: deployed
|
|
3255
|
-
});
|
|
3256
|
-
return deployed;
|
|
3257
|
-
} catch (error) {
|
|
3258
|
-
emit({
|
|
3259
|
-
type: "deploy.failed",
|
|
3260
|
-
error: eventError(error)
|
|
3261
|
-
});
|
|
3262
|
-
throw error;
|
|
3263
|
-
} finally {
|
|
3264
|
-
log.close();
|
|
3265
|
-
}
|
|
3266
|
-
});
|
|
3267
|
-
result.catch(() => {});
|
|
3268
|
-
return {
|
|
3269
|
-
result,
|
|
3270
|
-
[Symbol.asyncIterator]: () => log.iterate()
|
|
3271
|
-
};
|
|
3272
|
-
}
|
|
3273
|
-
/** The workspace at `input.cwd`, refusing a stage it does not deploy. */
|
|
3274
|
-
async function load(input) {
|
|
3275
|
-
const { workspace } = await require_config.loadWorkspaceConfig((0, node_path.resolve)(input.cwd));
|
|
3276
|
-
require_workspace.assertDeployedStage(workspace.stages, input.stage);
|
|
3277
|
-
return workspace;
|
|
3278
|
-
}
|
|
3279
|
-
//#endregion
|
|
3280
2900
|
Object.defineProperty(exports, "BackendDeployFailed", {
|
|
3281
2901
|
enumerable: true,
|
|
3282
2902
|
get: function() {
|
|
3283
2903
|
return BackendDeployFailed;
|
|
3284
2904
|
}
|
|
3285
2905
|
});
|
|
3286
|
-
Object.defineProperty(exports, "DeployProviderUnsupported", {
|
|
3287
|
-
enumerable: true,
|
|
3288
|
-
get: function() {
|
|
3289
|
-
return DeployProviderUnsupported;
|
|
3290
|
-
}
|
|
3291
|
-
});
|
|
3292
|
-
Object.defineProperty(exports, "MissingCredential", {
|
|
3293
|
-
enumerable: true,
|
|
3294
|
-
get: function() {
|
|
3295
|
-
return MissingCredential;
|
|
3296
|
-
}
|
|
3297
|
-
});
|
|
3298
2906
|
Object.defineProperty(exports, "MissingEnvVars", {
|
|
3299
2907
|
enumerable: true,
|
|
3300
2908
|
get: function() {
|
|
3301
2909
|
return MissingEnvVars;
|
|
3302
2910
|
}
|
|
3303
2911
|
});
|
|
3304
|
-
Object.defineProperty(exports, "NoDeployableApps", {
|
|
3305
|
-
enumerable: true,
|
|
3306
|
-
get: function() {
|
|
3307
|
-
return NoDeployableApps;
|
|
3308
|
-
}
|
|
3309
|
-
});
|
|
3310
2912
|
Object.defineProperty(exports, "ProjectNotOwned", {
|
|
3311
2913
|
enumerable: true,
|
|
3312
2914
|
get: function() {
|
|
@@ -3331,35 +2933,41 @@ Object.defineProperty(exports, "RegistryNotFound", {
|
|
|
3331
2933
|
return RegistryNotFound;
|
|
3332
2934
|
}
|
|
3333
2935
|
});
|
|
3334
|
-
Object.defineProperty(exports, "
|
|
2936
|
+
Object.defineProperty(exports, "dokployResult", {
|
|
2937
|
+
enumerable: true,
|
|
2938
|
+
get: function() {
|
|
2939
|
+
return dokployResult;
|
|
2940
|
+
}
|
|
2941
|
+
});
|
|
2942
|
+
Object.defineProperty(exports, "planDokploy", {
|
|
3335
2943
|
enumerable: true,
|
|
3336
2944
|
get: function() {
|
|
3337
|
-
return
|
|
2945
|
+
return planDokploy;
|
|
3338
2946
|
}
|
|
3339
2947
|
});
|
|
3340
|
-
Object.defineProperty(exports, "
|
|
2948
|
+
Object.defineProperty(exports, "provisionDokploy", {
|
|
3341
2949
|
enumerable: true,
|
|
3342
2950
|
get: function() {
|
|
3343
|
-
return
|
|
2951
|
+
return provisionDokploy;
|
|
3344
2952
|
}
|
|
3345
2953
|
});
|
|
3346
|
-
Object.defineProperty(exports, "
|
|
2954
|
+
Object.defineProperty(exports, "releaseDokploy", {
|
|
3347
2955
|
enumerable: true,
|
|
3348
2956
|
get: function() {
|
|
3349
|
-
return
|
|
2957
|
+
return releaseDokploy;
|
|
3350
2958
|
}
|
|
3351
2959
|
});
|
|
3352
|
-
Object.defineProperty(exports, "
|
|
2960
|
+
Object.defineProperty(exports, "validateDokploy", {
|
|
3353
2961
|
enumerable: true,
|
|
3354
2962
|
get: function() {
|
|
3355
|
-
return
|
|
2963
|
+
return validateDokploy;
|
|
3356
2964
|
}
|
|
3357
2965
|
});
|
|
3358
|
-
Object.defineProperty(exports, "
|
|
2966
|
+
Object.defineProperty(exports, "verifyDokploy", {
|
|
3359
2967
|
enumerable: true,
|
|
3360
2968
|
get: function() {
|
|
3361
|
-
return
|
|
2969
|
+
return verifyDokploy;
|
|
3362
2970
|
}
|
|
3363
2971
|
});
|
|
3364
2972
|
|
|
3365
|
-
//# sourceMappingURL=deploy-
|
|
2973
|
+
//# sourceMappingURL=deploy-ABBI0lf1.cjs.map
|