@geekmidas/cli 10.0.0-alpha.82 → 10.0.0-alpha.84
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/{EndpointGenerator-DtnIGafh.mjs → EndpointGenerator-CVc6Oi1Y.mjs} +185 -82
- package/dist/EndpointGenerator-CVc6Oi1Y.mjs.map +1 -0
- package/dist/{EndpointGenerator-cKlnllIu.cjs → EndpointGenerator-CwLjBCFE.cjs} +203 -82
- package/dist/EndpointGenerator-CwLjBCFE.cjs.map +1 -0
- package/dist/{LegacyStateStore-Ceq7A_75.mjs → LegacyStateStore-CTsUFLNQ.mjs} +2 -2
- package/dist/{LegacyStateStore-Ceq7A_75.mjs.map → LegacyStateStore-CTsUFLNQ.mjs.map} +1 -1
- package/dist/{LegacyStateStore-Z-EKUGSX.cjs → LegacyStateStore-EDT2TUSe.cjs} +2 -2
- package/dist/{LegacyStateStore-Z-EKUGSX.cjs.map → LegacyStateStore-EDT2TUSe.cjs.map} +1 -1
- package/dist/{LocalStateStore-Bocb8dmZ.cjs → LocalStateStore-CdpzTvPn.cjs} +2 -2
- package/dist/{LocalStateStore-Bocb8dmZ.cjs.map → LocalStateStore-CdpzTvPn.cjs.map} +1 -1
- package/dist/{LocalStateStore-C72bwpG2.mjs → LocalStateStore-D1VfxRuK.mjs} +2 -2
- package/dist/{LocalStateStore-C72bwpG2.mjs.map → LocalStateStore-D1VfxRuK.mjs.map} +1 -1
- package/dist/{OpenApiTsGenerator-CdUM6Hvv.cjs → OpenApiTsGenerator-B--HV-sW.cjs} +2 -2
- package/dist/{OpenApiTsGenerator-CdUM6Hvv.cjs.map → OpenApiTsGenerator-B--HV-sW.cjs.map} +1 -1
- package/dist/{OpenApiTsGenerator-ByRPMbBN.mjs → OpenApiTsGenerator-CkvsPdgg.mjs} +2 -2
- package/dist/{OpenApiTsGenerator-ByRPMbBN.mjs.map → OpenApiTsGenerator-CkvsPdgg.mjs.map} +1 -1
- package/dist/{S3StateStore-35YfcdL_.cjs → S3StateStore-BPM74zwv.cjs} +2 -2
- package/dist/{S3StateStore-35YfcdL_.cjs.map → S3StateStore-BPM74zwv.cjs.map} +1 -1
- package/dist/{S3StateStore-C9upSW5o.mjs → S3StateStore-DVZ1YuGJ.mjs} +2 -2
- package/dist/{S3StateStore-C9upSW5o.mjs.map → S3StateStore-DVZ1YuGJ.mjs.map} +1 -1
- package/dist/{SSMStateStore-dOmFO6g1.mjs → SSMStateStore-DLvnGyyl.mjs} +2 -2
- package/dist/{SSMStateStore-dOmFO6g1.mjs.map → SSMStateStore-DLvnGyyl.mjs.map} +1 -1
- package/dist/{SSMStateStore-W-Ps22AQ.cjs → SSMStateStore-qerm5c36.cjs} +2 -2
- package/dist/{SSMStateStore-W-Ps22AQ.cjs.map → SSMStateStore-qerm5c36.cjs.map} +1 -1
- package/dist/{SubscriberGenerator-DQZeGkDW.mjs → SubscriberGenerator-BPqQf8fB.mjs} +2 -2
- package/dist/{SubscriberGenerator-DQZeGkDW.mjs.map → SubscriberGenerator-BPqQf8fB.mjs.map} +1 -1
- package/dist/{SubscriberGenerator-CYriX5BV.cjs → SubscriberGenerator-BVn7cQ-2.cjs} +2 -2
- package/dist/{SubscriberGenerator-CYriX5BV.cjs.map → SubscriberGenerator-BVn7cQ-2.cjs.map} +1 -1
- package/dist/{add-1T3y6E4M.cjs → add-BQ8v1ZII.cjs} +3 -3
- package/dist/{add-1T3y6E4M.cjs.map → add-BQ8v1ZII.cjs.map} +1 -1
- package/dist/{add-DnYHJOap.mjs → add-DbnzC7Kl.mjs} +3 -3
- package/dist/{add-DnYHJOap.mjs.map → add-DbnzC7Kl.mjs.map} +1 -1
- package/dist/{bundler-DlKdxCGh.mjs → bundler-D4030Afw.mjs} +5 -5
- package/dist/{bundler-DlKdxCGh.mjs.map → bundler-D4030Afw.mjs.map} +1 -1
- package/dist/{bundler-YNvLdvlh.cjs → bundler-DjrRffko.cjs} +5 -5
- package/dist/{bundler-YNvLdvlh.cjs.map → bundler-DjrRffko.cjs.map} +1 -1
- package/dist/{cli-CWee1-wU.cjs → cli-D8YQAYUX.cjs} +3 -3
- package/dist/{cli-CWee1-wU.cjs.map → cli-D8YQAYUX.cjs.map} +1 -1
- package/dist/{cli-qMszGvDu.mjs → cli-DwTa9d_8.mjs} +3 -3
- package/dist/{cli-qMszGvDu.mjs.map → cli-DwTa9d_8.mjs.map} +1 -1
- package/dist/{compose-D4sD4Lgr.mjs → compose-C5wz8mf9.mjs} +64 -24
- package/dist/compose-C5wz8mf9.mjs.map +1 -0
- package/dist/{compose-qnDyPJNp.cjs → compose-DqWh1TaO.cjs} +64 -24
- package/dist/compose-DqWh1TaO.cjs.map +1 -0
- package/dist/{config-Mr4rcXFC.d.cts → config-BzIfP8a-.d.cts} +16 -3
- package/dist/config-BzIfP8a-.d.cts.map +1 -0
- package/dist/{config-L_6NivCp.d.mts → config-DhdzmndX.d.mts} +16 -3
- package/dist/config-DhdzmndX.d.mts.map +1 -0
- package/dist/config.cjs +1 -1
- package/dist/config.d.cts +3 -3
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +1 -1
- package/dist/deploy/public.cjs +6 -6
- package/dist/deploy/public.d.cts +3 -3
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts +3 -3
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +6 -6
- package/dist/{deploy-C00DAKOt.mjs → deploy-BwIKGxWH.mjs} +14 -5
- package/dist/deploy-BwIKGxWH.mjs.map +1 -0
- package/dist/{deploy-CXP2fXvK.cjs → deploy-C8sWg81_.cjs} +14 -5
- package/dist/deploy-C8sWg81_.cjs.map +1 -0
- package/dist/{dokploy-BHcSmghb.cjs → dokploy-BkRxJbfi.cjs} +2 -2
- package/dist/{dokploy-BHcSmghb.cjs.map → dokploy-BkRxJbfi.cjs.map} +1 -1
- package/dist/{dokploy-B3zoCmJb.mjs → dokploy-ijjms1-h.mjs} +2 -2
- package/dist/{dokploy-B3zoCmJb.mjs.map → dokploy-ijjms1-h.mjs.map} +1 -1
- package/dist/{drivers-B4RP2B2O.mjs → drivers-DTZzxeIl.mjs} +2 -2
- package/dist/{drivers-B4RP2B2O.mjs.map → drivers-DTZzxeIl.mjs.map} +1 -1
- package/dist/{drivers-CJx76mcb.cjs → drivers-LYSdQDmd.cjs} +2 -2
- package/dist/{drivers-CJx76mcb.cjs.map → drivers-LYSdQDmd.cjs.map} +1 -1
- package/dist/{encryption-DPFljXtM.mjs → encryption-BRcBAmjL.mjs} +3 -3
- package/dist/{encryption-DPFljXtM.mjs.map → encryption-BRcBAmjL.mjs.map} +1 -1
- package/dist/{encryption-DLin89I_.cjs → encryption-g6PzwwfL.cjs} +3 -3
- package/dist/{encryption-DLin89I_.cjs.map → encryption-g6PzwwfL.cjs.map} +1 -1
- package/dist/{engine-CgzgIg-_.mjs → engine-BP0CZ5fh.mjs} +33 -13
- package/dist/engine-BP0CZ5fh.mjs.map +1 -0
- package/dist/{engine-BS3iX9Mu.cjs → engine-DLEJsZ3i.cjs} +33 -13
- package/dist/engine-DLEJsZ3i.cjs.map +1 -0
- package/dist/{github-D8KVmNRg.cjs → github-B8YjwdLK.cjs} +3 -3
- package/dist/{github-D8KVmNRg.cjs.map → github-B8YjwdLK.cjs.map} +1 -1
- package/dist/{github-DL4zwJsR.mjs → github-Zs-dVJbR.mjs} +3 -3
- package/dist/{github-DL4zwJsR.mjs.map → github-Zs-dVJbR.mjs.map} +1 -1
- package/dist/{index-C0UmP_lg.d.mts → index-D1ODeM9s.d.cts} +7 -3
- package/dist/index-D1ODeM9s.d.cts.map +1 -0
- package/dist/{index-DTEPwLml.d.cts → index-f77HdqN5.d.mts} +7 -3
- package/dist/index-f77HdqN5.d.mts.map +1 -0
- package/dist/index.cjs +553 -134
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +553 -134
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-DIjG8-QR.cjs → migrate-BfZN1S32.cjs} +3 -3
- package/dist/{migrate-DIjG8-QR.cjs.map → migrate-BfZN1S32.cjs.map} +1 -1
- package/dist/{migrate-CCejlgU0.mjs → migrate-CdXcX0XR.mjs} +3 -3
- package/dist/{migrate-CCejlgU0.mjs.map → migrate-CdXcX0XR.mjs.map} +1 -1
- package/dist/{migrate-Cd3kcI7o.mjs → migrate-DOMU4uKe.mjs} +3 -3
- package/dist/{migrate-Cd3kcI7o.mjs.map → migrate-DOMU4uKe.mjs.map} +1 -1
- package/dist/{migrate-BdKhIJgT.cjs → migrate-FoL_mZIz.cjs} +3 -3
- package/dist/{migrate-BdKhIJgT.cjs.map → migrate-FoL_mZIz.cjs.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-4kx2pAhm.cjs → ready-BpNbORRB.cjs} +5 -5
- package/dist/{ready-4kx2pAhm.cjs.map → ready-BpNbORRB.cjs.map} +1 -1
- package/dist/{ready-DhZbZtFw.mjs → ready-b6vm0-W-.mjs} +5 -5
- package/dist/{ready-DhZbZtFw.mjs.map → ready-b6vm0-W-.mjs.map} +1 -1
- package/dist/reconcile/public.d.cts +1 -1
- package/dist/reconcile/public.d.mts +1 -1
- package/dist/{resolve-ApSUK_HB.cjs → resolve-T2I-5FcT.cjs} +3 -3
- package/dist/{resolve-ApSUK_HB.cjs.map → resolve-T2I-5FcT.cjs.map} +1 -1
- package/dist/{resolve-DY9TaVeV.mjs → resolve-r7PAs6ng.mjs} +3 -3
- package/dist/{resolve-DY9TaVeV.mjs.map → resolve-r7PAs6ng.mjs.map} +1 -1
- package/dist/{rollback-DXU6cr7q.mjs → rollback-BSdxnW3X.mjs} +5 -5
- package/dist/{rollback-DXU6cr7q.mjs.map → rollback-BSdxnW3X.mjs.map} +1 -1
- package/dist/{rollback-CdGhCk1d.cjs → rollback-CPSDjGse.cjs} +5 -5
- package/dist/{rollback-CdGhCk1d.cjs.map → rollback-CPSDjGse.cjs.map} +1 -1
- package/dist/{runtime-ekxfPNM-.d.mts → runtime-CNu2C2hB.d.mts} +2 -2
- package/dist/{runtime-D6A-C6zh.d.cts.map → runtime-CNu2C2hB.d.mts.map} +1 -1
- package/dist/{runtime-D6A-C6zh.d.cts → runtime-DMLgL26v.d.cts} +2 -2
- package/dist/{runtime-ekxfPNM-.d.mts.map → runtime-DMLgL26v.d.cts.map} +1 -1
- package/dist/{seeds-DbyqaXW4.mjs → seeds-BK8caVMm.mjs} +1707 -1612
- package/dist/seeds-BK8caVMm.mjs.map +1 -0
- package/dist/{seeds-BLzrSwEr.cjs → seeds-DQ0FG57Z.cjs} +2558 -2421
- package/dist/seeds-DQ0FG57Z.cjs.map +1 -0
- package/dist/{sniffer-ByWtH28i.mjs → sniffer-CqE_KTTp.mjs} +6 -6
- package/dist/{sniffer-ByWtH28i.mjs.map → sniffer-CqE_KTTp.mjs.map} +1 -1
- package/dist/{sniffer-BjG-1mlD.cjs → sniffer-hSf5mRgV.cjs} +6 -6
- package/dist/{sniffer-BjG-1mlD.cjs.map → sniffer-hSf5mRgV.cjs.map} +1 -1
- package/dist/stages-CS1sjcRb.cjs +174 -0
- package/dist/stages-CS1sjcRb.cjs.map +1 -0
- package/dist/stages-CSXt7N2b.mjs +174 -0
- package/dist/stages-CSXt7N2b.mjs.map +1 -0
- package/dist/target/public.cjs +1 -1
- package/dist/target/public.d.cts +2 -2
- package/dist/target/public.d.mts +2 -2
- package/dist/target/public.mjs +1 -1
- package/dist/{types-DZtj9jeI.d.cts → types-BZn-8ssD.d.mts} +75 -22
- package/dist/types-BZn-8ssD.d.mts.map +1 -0
- package/dist/{types-BzCavjGt.d.mts → types-DiZj6hqp.d.cts} +76 -21
- package/dist/types-DiZj6hqp.d.cts.map +1 -0
- package/dist/vitest.cjs +1 -1
- package/dist/vitest.mjs +1 -1
- package/dist/workspace/index.cjs +2 -1
- package/dist/workspace/index.d.cts +3 -3
- package/dist/workspace/index.d.mts +3 -3
- package/dist/workspace/index.mjs +2 -2
- package/dist/{workspace-Bp8FEkF-.cjs → workspace-Bic_R3tz.cjs} +345 -99
- package/dist/workspace-Bic_R3tz.cjs.map +1 -0
- package/dist/{workspace-BBdqmkch.mjs → workspace-Drz4jsvy.mjs} +314 -98
- package/dist/workspace-Drz4jsvy.mjs.map +1 -0
- package/package.json +15 -15
- package/dist/EndpointGenerator-DtnIGafh.mjs.map +0 -1
- package/dist/EndpointGenerator-cKlnllIu.cjs.map +0 -1
- package/dist/compose-D4sD4Lgr.mjs.map +0 -1
- package/dist/compose-qnDyPJNp.cjs.map +0 -1
- package/dist/config-L_6NivCp.d.mts.map +0 -1
- package/dist/config-Mr4rcXFC.d.cts.map +0 -1
- package/dist/deploy-C00DAKOt.mjs.map +0 -1
- package/dist/deploy-CXP2fXvK.cjs.map +0 -1
- package/dist/engine-BS3iX9Mu.cjs.map +0 -1
- package/dist/engine-CgzgIg-_.mjs.map +0 -1
- package/dist/index-C0UmP_lg.d.mts.map +0 -1
- package/dist/index-DTEPwLml.d.cts.map +0 -1
- package/dist/seeds-BLzrSwEr.cjs.map +0 -1
- package/dist/seeds-DbyqaXW4.mjs.map +0 -1
- package/dist/types-BzCavjGt.d.mts.map +0 -1
- package/dist/types-DZtj9jeI.d.cts.map +0 -1
- package/dist/workspace-BBdqmkch.mjs.map +0 -1
- package/dist/workspace-Bp8FEkF-.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -5,22 +5,22 @@ const require_run = require("./run-fVZ-rLnc.cjs");
|
|
|
5
5
|
const require_credentials = require("./credentials-BVs7mrtw.cjs");
|
|
6
6
|
const require_discover = require("./discover-D1It5r_h.cjs");
|
|
7
7
|
const require_derive = require("./derive-DAbo49sm.cjs");
|
|
8
|
-
const require_workspace = require("./workspace-
|
|
8
|
+
const require_workspace = require("./workspace-Bic_R3tz.cjs");
|
|
9
9
|
const require_config = require("./config.cjs");
|
|
10
|
-
const require_seeds = require("./seeds-
|
|
11
|
-
const require_EndpointGenerator = require("./EndpointGenerator-
|
|
10
|
+
const require_seeds = require("./seeds-DQ0FG57Z.cjs");
|
|
11
|
+
const require_EndpointGenerator = require("./EndpointGenerator-CwLjBCFE.cjs");
|
|
12
12
|
const require_openapi = require("./openapi.cjs");
|
|
13
|
-
const require_SubscriberGenerator = require("./SubscriberGenerator-
|
|
13
|
+
const require_SubscriberGenerator = require("./SubscriberGenerator-BVn7cQ-2.cjs");
|
|
14
14
|
const require_appPorts = require("./appPorts-Cu79hJF6.cjs");
|
|
15
|
-
const require_drivers = require("./drivers-
|
|
15
|
+
const require_drivers = require("./drivers-LYSdQDmd.cjs");
|
|
16
16
|
const require_emit = require("./emit-Dmc1nvdS.cjs");
|
|
17
|
-
const require_sniffer = require("./sniffer-
|
|
18
|
-
const require_deploy = require("./deploy-
|
|
19
|
-
const require_compose = require("./compose-
|
|
17
|
+
const require_sniffer = require("./sniffer-hSf5mRgV.cjs");
|
|
18
|
+
const require_deploy = require("./deploy-C8sWg81_.cjs");
|
|
19
|
+
const require_compose = require("./compose-DqWh1TaO.cjs");
|
|
20
20
|
const require_credentialSchemas = require("./credentialSchemas-DCR4Wd1W.cjs");
|
|
21
|
-
const require_LocalStateStore = require("./LocalStateStore-
|
|
21
|
+
const require_LocalStateStore = require("./LocalStateStore-CdpzTvPn.cjs");
|
|
22
22
|
const require_utils = require("./utils-D2Nk1Nv2.cjs");
|
|
23
|
-
const require_ready = require("./ready-
|
|
23
|
+
const require_ready = require("./ready-BpNbORRB.cjs");
|
|
24
24
|
let node_path = require("node:path");
|
|
25
25
|
let commander = require("commander");
|
|
26
26
|
let node_process = require("node:process");
|
|
@@ -53,7 +53,7 @@ crypto = require_rolldown_runtime.__toESM(crypto, 1);
|
|
|
53
53
|
let _geekmidas_constructs_functions = require("@geekmidas/constructs/functions");
|
|
54
54
|
let _geekmidas_constructs_topic = require("@geekmidas/constructs/topic");
|
|
55
55
|
//#region package.json
|
|
56
|
-
var version = "10.0.0-alpha.
|
|
56
|
+
var version = "10.0.0-alpha.84";
|
|
57
57
|
//#endregion
|
|
58
58
|
//#region src/prompt.ts
|
|
59
59
|
/**
|
|
@@ -136,7 +136,7 @@ const logger$8 = console;
|
|
|
136
136
|
* Validate Dokploy token by making a test API call
|
|
137
137
|
*/
|
|
138
138
|
async function validateDokployToken(endpoint, token) {
|
|
139
|
-
const { DokployApi } = await Promise.resolve().then(() => require("./sniffer-
|
|
139
|
+
const { DokployApi } = await Promise.resolve().then(() => require("./sniffer-hSf5mRgV.cjs")).then((n) => n.dokploy_api_exports);
|
|
140
140
|
return new DokployApi({
|
|
141
141
|
baseUrl: endpoint,
|
|
142
142
|
token
|
|
@@ -536,10 +536,9 @@ var NoLocalCredentials = class extends Error {
|
|
|
536
536
|
/** The logins of every service the workspace last published. */
|
|
537
537
|
function devCredentials(workspace, credentials, ports) {
|
|
538
538
|
const containers = SIGNED_IN.filter((container) => require_seeds.portsOf(container).some((port) => ports[port.key] !== void 0));
|
|
539
|
-
const
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
via: `gkm compose --stage ${workspace.stages.local}`
|
|
539
|
+
const local = ports.openobserve !== void 0 ? {
|
|
540
|
+
url: `http://localhost:${ports.openobserve}`,
|
|
541
|
+
via: "gkm dev"
|
|
543
542
|
} : void 0;
|
|
544
543
|
return {
|
|
545
544
|
workspace: workspace.name,
|
|
@@ -759,6 +758,7 @@ async function collect(records) {
|
|
|
759
758
|
root,
|
|
760
759
|
stage: lead.workspace.stage,
|
|
761
760
|
manifest: group.find((r) => r.manifest)?.manifest ?? null,
|
|
761
|
+
telemetry: group.find((r) => r.telemetry)?.telemetry ?? null,
|
|
762
762
|
apps: discovered,
|
|
763
763
|
allowedOrigins: [...new Set(group.flatMap((r) => r.allowedOrigins))]
|
|
764
764
|
});
|
|
@@ -1103,6 +1103,7 @@ var DiscoverySession = class DiscoverySession {
|
|
|
1103
1103
|
workspace: options.workspace,
|
|
1104
1104
|
allowedOrigins: [...options.allowedOrigins ?? []],
|
|
1105
1105
|
...options.manifest ? { manifest: options.manifest } : {},
|
|
1106
|
+
...options.telemetry ? { telemetry: options.telemetry } : {},
|
|
1106
1107
|
apps: options.apps
|
|
1107
1108
|
};
|
|
1108
1109
|
writeRecord(registry, record);
|
|
@@ -1856,7 +1857,8 @@ async function devCommand(options) {
|
|
|
1856
1857
|
hooks,
|
|
1857
1858
|
skipBundle: true,
|
|
1858
1859
|
bustCache,
|
|
1859
|
-
serveEmpty: true
|
|
1860
|
+
serveEmpty: true,
|
|
1861
|
+
workspaceName: workspace.name
|
|
1860
1862
|
}));
|
|
1861
1863
|
logger$5.log(`🔨 Building ${workspaceAppName ?? "the app"}`);
|
|
1862
1864
|
const initial = await build();
|
|
@@ -1864,6 +1866,7 @@ async function devCommand(options) {
|
|
|
1864
1866
|
let secretsJsonPath;
|
|
1865
1867
|
let publicUrl;
|
|
1866
1868
|
let manifest;
|
|
1869
|
+
let telemetryUi;
|
|
1867
1870
|
const appSecrets = await require_seeds.loadSecretsForApp(workspace ? await require_seeds.secretsStoreFor(workspace, config.stages.local) : new require_seeds.FileSecretsStore(secretsRoot), config.stages.local);
|
|
1868
1871
|
if (workspace) {
|
|
1869
1872
|
const reconciled = await require_seeds.reconcileWorkspace(workspace, {
|
|
@@ -1875,10 +1878,25 @@ async function devCommand(options) {
|
|
|
1875
1878
|
logger$5.log("🐳 Services");
|
|
1876
1879
|
for (const line of require_seeds.describeServices(reconciled.services)) logger$5.log(line);
|
|
1877
1880
|
}
|
|
1881
|
+
if (!process.env["GKM_DISCOVERY_QUIET"] && reconciled.credentials && reconciled.ports) {
|
|
1882
|
+
const { services: logins } = devCredentials(workspace, reconciled.credentials, reconciled.ports);
|
|
1883
|
+
if (logins.length > 0) {
|
|
1884
|
+
logger$5.log("🔑 Logins (again any time: gkm dev:credentials)");
|
|
1885
|
+
for (const line of describeLogins(logins)) logger$5.log(line);
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1878
1888
|
Object.assign(appSecrets, reconciled.env);
|
|
1889
|
+
const scoped = require_seeds.scopeTelemetryEnv(appSecrets, {
|
|
1890
|
+
uses: reconciled.manifest !== void 0 && require_seeds.appTelemetry(reconciled.manifest, workspaceAppName) !== void 0,
|
|
1891
|
+
serviceName: workspaceAppName,
|
|
1892
|
+
telemetry: reconciled.env
|
|
1893
|
+
});
|
|
1894
|
+
for (const key of Object.keys(appSecrets)) if (!(key in scoped)) delete appSecrets[key];
|
|
1895
|
+
Object.assign(appSecrets, scoped);
|
|
1879
1896
|
const own = reconciled.plan.resources.find((r) => (r.kind === "rest-api" || r.kind === "site") && require_derive.appKey(r.id) === workspaceAppName);
|
|
1880
1897
|
publicUrl = own ? reconciled.env[own.envKey] : void 0;
|
|
1881
1898
|
manifest = reconciled.manifest;
|
|
1899
|
+
telemetryUi = telemetryUiOf(reconciled.services);
|
|
1882
1900
|
}
|
|
1883
1901
|
if (Object.keys(appSecrets).length > 0) {
|
|
1884
1902
|
const secretsDir = (0, node_path.join)(secretsRoot, ".gkm");
|
|
@@ -1901,6 +1919,7 @@ async function devCommand(options) {
|
|
|
1901
1919
|
},
|
|
1902
1920
|
allowedOrigins: workspace.dev?.allowedOrigins ?? [],
|
|
1903
1921
|
...manifest ? { manifest } : {},
|
|
1922
|
+
...telemetryUi ? { telemetry: telemetryUi } : {},
|
|
1904
1923
|
apps: [{
|
|
1905
1924
|
name: workspaceAppName,
|
|
1906
1925
|
type: "backend",
|
|
@@ -2209,17 +2228,20 @@ async function workspaceDevCommand(configured, options) {
|
|
|
2209
2228
|
logger$5.log("🔑 Logins (again any time: gkm dev:credentials)");
|
|
2210
2229
|
for (const line of describeLogins(logins)) logger$5.log(line);
|
|
2211
2230
|
}
|
|
2212
|
-
const secretsEnv = {
|
|
2231
|
+
const secretsEnv = require_seeds.scopeTelemetryEnv({
|
|
2213
2232
|
...rawSecrets,
|
|
2214
2233
|
...reconciled.env
|
|
2215
|
-
}
|
|
2234
|
+
}, {
|
|
2235
|
+
uses: false,
|
|
2236
|
+
serviceName: workspace.name
|
|
2237
|
+
});
|
|
2216
2238
|
const fakes = options.fake ? await serveFakes(reconciled.fakes, reconciled.ports) : [];
|
|
2217
2239
|
for (const { id, port } of fakes) logger$5.log(`🎭 ${id} fake: http://localhost:${port}`);
|
|
2218
2240
|
logger$5.log(options.migrate || options.seed ? "🗄️ Migrating the databases" : "🗄️ Checking for pending migrations");
|
|
2219
2241
|
if (options.migrate || options.seed) {
|
|
2220
|
-
const { prepareDevDatabases } = await Promise.resolve().then(() => require("./migrate-
|
|
2242
|
+
const { prepareDevDatabases } = await Promise.resolve().then(() => require("./migrate-BfZN1S32.cjs"));
|
|
2221
2243
|
await prepareDevDatabases(workspace, reconciled.env, { seed: !!options.seed });
|
|
2222
|
-
} else await Promise.resolve().then(() => require("./migrate-
|
|
2244
|
+
} else await Promise.resolve().then(() => require("./migrate-BfZN1S32.cjs")).then(({ reportPendingMigrations }) => reportPendingMigrations(workspace, reconciled.env)).catch((error) => {
|
|
2223
2245
|
logger$5.log(`⚠️ Could not check for pending migrations: ${error instanceof Error ? error.message : String(error)}`);
|
|
2224
2246
|
});
|
|
2225
2247
|
const appUrls = {};
|
|
@@ -2274,6 +2296,7 @@ async function workspaceDevCommand(configured, options) {
|
|
|
2274
2296
|
break;
|
|
2275
2297
|
}
|
|
2276
2298
|
}
|
|
2299
|
+
const workspaceTelemetry = telemetryUiOf(reconciled.services);
|
|
2277
2300
|
const discovery = await joinDiscovery({
|
|
2278
2301
|
role: "workspace",
|
|
2279
2302
|
port: discoveryPort(workspace.dev),
|
|
@@ -2284,6 +2307,7 @@ async function workspaceDevCommand(configured, options) {
|
|
|
2284
2307
|
},
|
|
2285
2308
|
allowedOrigins: workspace.dev?.allowedOrigins ?? [],
|
|
2286
2309
|
...reconciled.manifest ? { manifest: reconciled.manifest } : {},
|
|
2310
|
+
...workspaceTelemetry ? { telemetry: workspaceTelemetry } : {},
|
|
2287
2311
|
apps: buildOrder.flatMap((name) => {
|
|
2288
2312
|
const app = workspace.apps[name];
|
|
2289
2313
|
if (!app) return [];
|
|
@@ -2481,6 +2505,18 @@ var EntryRunner = class {
|
|
|
2481
2505
|
}
|
|
2482
2506
|
};
|
|
2483
2507
|
/**
|
|
2508
|
+
* Where the local OpenObserve is, and who signs in to it, when reconcile runs
|
|
2509
|
+
* one — for the discovery endpoint, which is told no password.
|
|
2510
|
+
*/
|
|
2511
|
+
function telemetryUiOf(services) {
|
|
2512
|
+
const ui = services.find((s) => s.container === require_seeds.TELEMETRY_CONTAINER);
|
|
2513
|
+
if (!ui) return void 0;
|
|
2514
|
+
return {
|
|
2515
|
+
url: ui.address,
|
|
2516
|
+
email: require_seeds.LOCAL_LOGS_EMAIL
|
|
2517
|
+
};
|
|
2518
|
+
}
|
|
2519
|
+
/**
|
|
2484
2520
|
* Generate the content of the dev server entry file (server.ts).
|
|
2485
2521
|
* Uses dynamic import for createApp so Credentials are populated
|
|
2486
2522
|
* before any app modules evaluate.
|
|
@@ -2526,6 +2562,7 @@ if (existsSync(secretsPath)) {
|
|
|
2526
2562
|
injectWs(server);
|
|
2527
2563
|
console.log('🔌 Telescope real-time updates enabled');
|
|
2528
2564
|
}`;
|
|
2565
|
+
const telemetry = require_EndpointGenerator.startTelemetryCode(["/health", "/ready"]);
|
|
2529
2566
|
if (selfServing) return `#!/usr/bin/env node
|
|
2530
2567
|
/**
|
|
2531
2568
|
* Development server entry point for a surface that serves itself
|
|
@@ -2535,8 +2572,17 @@ ${credentialsInjection}${parentWatch}const port = process.argv.includes('--port'
|
|
|
2535
2572
|
? Number.parseInt(process.argv[process.argv.indexOf('--port') + 1])
|
|
2536
2573
|
: 3000;
|
|
2537
2574
|
|
|
2575
|
+
${telemetry}
|
|
2538
2576
|
// Dynamic import so Credentials are populated before the surface evaluates
|
|
2539
|
-
const { app } = await import('${appImportPath}');
|
|
2577
|
+
const { app: surface } = await import('${appImportPath}');
|
|
2578
|
+
|
|
2579
|
+
// Behind the request spans when there are any, as the production server is.
|
|
2580
|
+
const { Hono } = await import('hono');
|
|
2581
|
+
const app = requestSpans ? new Hono() : surface;
|
|
2582
|
+
if (requestSpans) {
|
|
2583
|
+
${require_EndpointGenerator.mountRequestSpansCode("app").trim().replace(/\n/g, "\n ")}
|
|
2584
|
+
app.route('/', surface);
|
|
2585
|
+
}
|
|
2540
2586
|
|
|
2541
2587
|
${serveCode.replace(/^ {4}/gm, "")}
|
|
2542
2588
|
`;
|
|
@@ -2549,11 +2595,16 @@ ${credentialsInjection}${parentWatch}const port = process.argv.includes('--port'
|
|
|
2549
2595
|
? Number.parseInt(process.argv[process.argv.indexOf('--port') + 1])
|
|
2550
2596
|
: 3000;
|
|
2551
2597
|
|
|
2598
|
+
${telemetry}
|
|
2552
2599
|
// Dynamic import so Credentials are populated before env.ts evaluates
|
|
2553
2600
|
const { createApp } = await import('${appImportPath}');
|
|
2554
2601
|
|
|
2602
|
+
// The span middleware first, as the production server mounts it.
|
|
2603
|
+
const { Hono } = await import('hono');
|
|
2604
|
+
const root = new Hono();
|
|
2605
|
+
${require_EndpointGenerator.mountRequestSpansCode("root")}
|
|
2555
2606
|
// createApp is async to support optional WebSocket setup
|
|
2556
|
-
const { app, start } = await createApp(
|
|
2607
|
+
const { app, start } = await createApp(root, ${enableOpenApi});
|
|
2557
2608
|
|
|
2558
2609
|
// Start the server
|
|
2559
2610
|
start({
|
|
@@ -2995,6 +3046,7 @@ export default app;
|
|
|
2995
3046
|
*/
|
|
2996
3047
|
async function writeSurfaceServer(outputDir, options) {
|
|
2997
3048
|
await (0, node_fs_promises.mkdir)(outputDir, { recursive: true });
|
|
3049
|
+
await require_EndpointGenerator.writeTelemetryModule(outputDir, options.telemetry);
|
|
2998
3050
|
const shutdown = options.gracefulShutdown ? `
|
|
2999
3051
|
// Stop taking requests, let in-flight ones finish, then close what the
|
|
3000
3052
|
// construct opened — bounded by GKM_SHUTDOWN_TIMEOUT_MS, under Docker's 10s
|
|
@@ -3021,12 +3073,14 @@ process.on('SIGINT', shutdown);
|
|
|
3021
3073
|
*/
|
|
3022
3074
|
import { serve } from '@hono/node-server';
|
|
3023
3075
|
import { Hono } from 'hono';
|
|
3024
|
-
${options.gracefulShutdown ? "import { runShutdownHooks } from '@geekmidas/constructs';\n" : ""}
|
|
3076
|
+
${options.gracefulShutdown ? "import { runShutdownHooks } from '@geekmidas/constructs';\n" : ""}
|
|
3077
|
+
${require_EndpointGenerator.startTelemetryCode([options.healthCheck])}
|
|
3078
|
+
const { app: surface } = await import('./app.js');
|
|
3025
3079
|
|
|
3026
3080
|
const port = Number(process.env.PORT) || 3000;
|
|
3027
3081
|
|
|
3028
3082
|
const app = new Hono();
|
|
3029
|
-
// First, so a probe is answered without reaching the surface's own routes.
|
|
3083
|
+
${require_EndpointGenerator.mountRequestSpansCode("app")}// First, so a probe is answered without reaching the surface's own routes.
|
|
3030
3084
|
app.get(${JSON.stringify(options.healthCheck)}, (c) =>
|
|
3031
3085
|
c.json({ status: 'ok', timestamp: Date.now() }),
|
|
3032
3086
|
);
|
|
@@ -3223,11 +3277,23 @@ async function buildApp(input) {
|
|
|
3223
3277
|
});
|
|
3224
3278
|
if (selfServing) {
|
|
3225
3279
|
await writeSurfaceEntry((0, node_path.join)(appRoot, ".gkm", "server"), selfServing.source);
|
|
3280
|
+
const telemetry = require_EndpointGenerator.telemetryFor({
|
|
3281
|
+
node: require_seeds.telemetryOf(declared, selfServing.id),
|
|
3282
|
+
appRoot,
|
|
3283
|
+
app: appNameOf(input),
|
|
3284
|
+
cwd: workspaceRoot,
|
|
3285
|
+
serviceName: selfServing.id,
|
|
3286
|
+
...input.workspaceName && { workspaceName: input.workspaceName }
|
|
3287
|
+
});
|
|
3288
|
+
await require_EndpointGenerator.writeTelemetryModule((0, node_path.join)(appRoot, ".gkm", "server"), telemetry);
|
|
3226
3289
|
logger$4.log(`Generated a server for ${selfServing.id} from its own declaration`);
|
|
3227
3290
|
if (production?.bundle && !input.skipBundle) {
|
|
3228
3291
|
const outputDir = (0, node_path.join)(appRoot, ".gkm", "server");
|
|
3229
|
-
const entryPoint = await writeSurfaceServer(outputDir,
|
|
3230
|
-
|
|
3292
|
+
const entryPoint = await writeSurfaceServer(outputDir, {
|
|
3293
|
+
...production,
|
|
3294
|
+
...telemetry ? { telemetry } : {}
|
|
3295
|
+
});
|
|
3296
|
+
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-DjrRffko.cjs"));
|
|
3231
3297
|
await bundleServer({
|
|
3232
3298
|
entryPoint,
|
|
3233
3299
|
outputDir: (0, node_path.join)(outputDir, "dist"),
|
|
@@ -3262,12 +3328,7 @@ async function buildApp(input) {
|
|
|
3262
3328
|
events: eventsBackends
|
|
3263
3329
|
}),
|
|
3264
3330
|
eventsBackends,
|
|
3265
|
-
markOptional: input.markOptional ?? false
|
|
3266
|
-
...production && { telemetry: require_EndpointGenerator.telemetryFor({
|
|
3267
|
-
appRoot,
|
|
3268
|
-
surfaceId: derived.surface?.id,
|
|
3269
|
-
workspaceName: input.workspaceName
|
|
3270
|
-
}) }
|
|
3331
|
+
markOptional: input.markOptional ?? false
|
|
3271
3332
|
};
|
|
3272
3333
|
const endpointGenerator = new require_EndpointGenerator.EndpointGenerator();
|
|
3273
3334
|
const functionGenerator = new FunctionGenerator();
|
|
@@ -3285,6 +3346,15 @@ async function buildApp(input) {
|
|
|
3285
3346
|
topicGenerator.load(code, appRoot, bustCache)
|
|
3286
3347
|
]);
|
|
3287
3348
|
const allEndpoints = servedBy(loadedEndpoints, derived.surface);
|
|
3349
|
+
if (target === "server") buildContext.telemetry = require_EndpointGenerator.telemetryFor({
|
|
3350
|
+
node: derived.surface ? require_seeds.telemetryOf(declared, derived.surface.id) : void 0,
|
|
3351
|
+
appRoot,
|
|
3352
|
+
app: appNameOf(input),
|
|
3353
|
+
cwd: workspaceRoot,
|
|
3354
|
+
serviceName: derived.surface?.id ?? (0, node_path.basename)(appRoot),
|
|
3355
|
+
...input.workspaceName && { workspaceName: input.workspaceName },
|
|
3356
|
+
routes: require_EndpointGenerator.routeTelemetry(allEndpoints.map(({ construct }) => construct))
|
|
3357
|
+
});
|
|
3288
3358
|
logger$4.log(`Found ${allEndpoints.length} endpoints`);
|
|
3289
3359
|
logger$4.log(`Found ${allFunctions.length} functions`);
|
|
3290
3360
|
logger$4.log(`Found ${allCrons.length} crons`);
|
|
@@ -3312,6 +3382,14 @@ async function buildApp(input) {
|
|
|
3312
3382
|
const appName = Object.entries(input.workspace.apps).find(([, app]) => (0, node_path.resolve)(input.workspace.root, app.path) === (0, node_path.resolve)(appRoot))?.[0];
|
|
3313
3383
|
await buildWorkers({
|
|
3314
3384
|
context: buildContext,
|
|
3385
|
+
telemetry: (workerId) => require_EndpointGenerator.telemetryFor({
|
|
3386
|
+
node: require_seeds.telemetryOf(declared, workerId),
|
|
3387
|
+
appRoot,
|
|
3388
|
+
app: appNameOf(input),
|
|
3389
|
+
cwd: workspaceRoot,
|
|
3390
|
+
serviceName: workerId,
|
|
3391
|
+
...input.workspaceName && { workspaceName: input.workspaceName }
|
|
3392
|
+
}),
|
|
3315
3393
|
workers: require_seeds.workerUnits(input.workspace, declared, background).filter((unit) => unit.app === appName),
|
|
3316
3394
|
serverDir: (0, node_path.join)(appRoot, ".gkm", "server"),
|
|
3317
3395
|
crons: allCrons,
|
|
@@ -3323,7 +3401,14 @@ async function buildApp(input) {
|
|
|
3323
3401
|
}
|
|
3324
3402
|
await require_openapi.generateOpenApi(allEndpoints.map(({ construct }) => construct), {
|
|
3325
3403
|
openapi: config.openapi,
|
|
3326
|
-
root: workspaceRoot
|
|
3404
|
+
root: workspaceRoot,
|
|
3405
|
+
...derived.surface ? clientTelemetry({
|
|
3406
|
+
manifest: declared,
|
|
3407
|
+
surfaceId: derived.surface.id,
|
|
3408
|
+
telemetry: input.workspace?.deploy?.telemetry,
|
|
3409
|
+
stage: input.stage,
|
|
3410
|
+
localStage: input.workspace?.stages.local ?? config.stages?.local
|
|
3411
|
+
}) : {}
|
|
3327
3412
|
});
|
|
3328
3413
|
return {
|
|
3329
3414
|
...result,
|
|
@@ -3341,9 +3426,11 @@ async function buildWorkers(input) {
|
|
|
3341
3426
|
const crons = owned(input.crons);
|
|
3342
3427
|
const queues = owned(input.queues);
|
|
3343
3428
|
const subscribers = owned(input.subscribers);
|
|
3429
|
+
const telemetry = input.telemetry(worker.id);
|
|
3344
3430
|
const entryPoint = await generator.build({
|
|
3345
3431
|
context: input.context,
|
|
3346
3432
|
workerId: worker.id,
|
|
3433
|
+
...telemetry ? { telemetry } : {},
|
|
3347
3434
|
outputDir: require_seeds.workerEntryDir(input.serverDir, worker.id),
|
|
3348
3435
|
crons,
|
|
3349
3436
|
queues,
|
|
@@ -3351,7 +3438,7 @@ async function buildWorkers(input) {
|
|
|
3351
3438
|
});
|
|
3352
3439
|
logger$4.log(`Generated worker ${worker.id}: ${crons.length} crons, ${queues.length} queues, ${subscribers.length} subscribers`);
|
|
3353
3440
|
if (!input.bundle) continue;
|
|
3354
|
-
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-
|
|
3441
|
+
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-DjrRffko.cjs"));
|
|
3355
3442
|
const outfile = require_seeds.workerBundleName(worker.id);
|
|
3356
3443
|
await bundleServer({
|
|
3357
3444
|
entryPoint,
|
|
@@ -3370,6 +3457,22 @@ async function buildWorkers(input) {
|
|
|
3370
3457
|
logger$4.log(`✅ Bundle complete: .gkm/server/dist/${outfile}`);
|
|
3371
3458
|
}
|
|
3372
3459
|
}
|
|
3460
|
+
/**
|
|
3461
|
+
* Whether the surface's generated client propagates trace context, and at
|
|
3462
|
+
* what rate: on when a site that calls it has an edge to a `Telemetry`
|
|
3463
|
+
* construct, at the stage's sample rate — every trace locally, and on a build
|
|
3464
|
+
* for no stage. Off for a stage that sends no telemetry.
|
|
3465
|
+
*/
|
|
3466
|
+
function clientTelemetry(options) {
|
|
3467
|
+
if (!require_seeds.surfaceClientTraced(options.manifest, options.surfaceId)) return {};
|
|
3468
|
+
const local = !options.stage || options.stage === options.localStage;
|
|
3469
|
+
const sampleRate = require_workspace.stageSampleRate(options.telemetry, options.stage ?? "", local);
|
|
3470
|
+
return sampleRate === void 0 ? {} : { telemetry: { sampleRate } };
|
|
3471
|
+
}
|
|
3472
|
+
/** The app being built, by its workspace name or its directory's. */
|
|
3473
|
+
function appNameOf(input) {
|
|
3474
|
+
return (input.workspace ? Object.entries(input.workspace.apps).find(([, app]) => (0, node_path.resolve)(input.workspace.root, app.path) === (0, node_path.resolve)(input.appRoot))?.[0] : void 0) ?? (0, node_path.basename)(input.appRoot);
|
|
3475
|
+
}
|
|
3373
3476
|
async function buildForTarget(target, context, appRoot, workspaceRoot, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, queueGenerator, topicGenerator, endpoints, functions, crons, subscribers, queues, topics, enableOpenApi, skipBundle, stage) {
|
|
3374
3477
|
const outputDir = (0, node_path.join)(appRoot, ".gkm", target);
|
|
3375
3478
|
await Promise.all([...SUPERSEDED_OUTPUT.map((dir) => (0, node_path.join)(appRoot, ".gkm", dir)), ...appRoot === workspaceRoot ? [] : [(0, node_path.join)(appRoot, ".gkm", "manifest")]].map((dir) => (0, node_fs_promises.rm)(dir, {
|
|
@@ -3421,7 +3524,7 @@ async function buildForTarget(target, context, appRoot, workspaceRoot, endpointG
|
|
|
3421
3524
|
let masterKey;
|
|
3422
3525
|
if (context.production?.bundle && !skipBundle) {
|
|
3423
3526
|
logger$4.log(`\n📦 Bundling production server...`);
|
|
3424
|
-
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-
|
|
3527
|
+
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-DjrRffko.cjs"));
|
|
3425
3528
|
const allConstructs = [
|
|
3426
3529
|
...endpoints.map((e) => e.construct),
|
|
3427
3530
|
...functions.map((f) => f.construct),
|
|
@@ -5108,12 +5211,12 @@ const PNPM_VERSION = "pnpm@10.13.1";
|
|
|
5108
5211
|
const BIOME_SCHEMA = `https://biomejs.dev/schemas/${DEPENDENCY_VERSIONS["@biomejs/biome"].replace(/^[~^]/, "")}/schema.json`;
|
|
5109
5212
|
//#endregion
|
|
5110
5213
|
//#region src/init/versions.ts
|
|
5111
|
-
const require$
|
|
5214
|
+
const require$2 = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
5112
5215
|
function loadPackageJson() {
|
|
5113
5216
|
try {
|
|
5114
|
-
return require$
|
|
5217
|
+
return require$2("../package.json");
|
|
5115
5218
|
} catch {
|
|
5116
|
-
return require$
|
|
5219
|
+
return require$2("../../package.json");
|
|
5117
5220
|
}
|
|
5118
5221
|
}
|
|
5119
5222
|
/**
|
|
@@ -5123,25 +5226,25 @@ function loadPackageJson() {
|
|
|
5123
5226
|
* Run: pnpm --filter @geekmidas/cli sync-versions
|
|
5124
5227
|
*/
|
|
5125
5228
|
const GEEKMIDAS_VERSIONS = {
|
|
5126
|
-
"@geekmidas/audit": "~10.0.0-alpha.
|
|
5127
|
-
"@geekmidas/auth": "~10.0.0-alpha.
|
|
5128
|
-
"@geekmidas/cache": "~10.0.0-alpha.
|
|
5129
|
-
"@geekmidas/client": "~10.0.0-alpha.
|
|
5130
|
-
"@geekmidas/cloud": "~10.0.0-alpha.
|
|
5131
|
-
"@geekmidas/constructs": "~10.0.0-alpha.
|
|
5132
|
-
"@geekmidas/db": "~10.0.0-alpha.
|
|
5133
|
-
"@geekmidas/emailkit": "~10.0.0-alpha.
|
|
5134
|
-
"@geekmidas/envkit": "~10.0.0-alpha.
|
|
5135
|
-
"@geekmidas/errors": "~10.0.0-alpha.
|
|
5136
|
-
"@geekmidas/events": "~10.0.0-alpha.
|
|
5137
|
-
"@geekmidas/logger": "~10.0.0-alpha.
|
|
5138
|
-
"@geekmidas/manifest": "~10.0.0-alpha.
|
|
5139
|
-
"@geekmidas/rate-limit": "~10.0.0-alpha.
|
|
5140
|
-
"@geekmidas/schema": "~10.0.0-alpha.
|
|
5141
|
-
"@geekmidas/services": "~10.0.0-alpha.
|
|
5142
|
-
"@geekmidas/storage": "~10.0.0-alpha.
|
|
5143
|
-
"@geekmidas/telescope": "~10.0.0-alpha.
|
|
5144
|
-
"@geekmidas/testkit": "~10.0.0-alpha.
|
|
5229
|
+
"@geekmidas/audit": "~10.0.0-alpha.84",
|
|
5230
|
+
"@geekmidas/auth": "~10.0.0-alpha.84",
|
|
5231
|
+
"@geekmidas/cache": "~10.0.0-alpha.84",
|
|
5232
|
+
"@geekmidas/client": "~10.0.0-alpha.84",
|
|
5233
|
+
"@geekmidas/cloud": "~10.0.0-alpha.84",
|
|
5234
|
+
"@geekmidas/constructs": "~10.0.0-alpha.84",
|
|
5235
|
+
"@geekmidas/db": "~10.0.0-alpha.84",
|
|
5236
|
+
"@geekmidas/emailkit": "~10.0.0-alpha.84",
|
|
5237
|
+
"@geekmidas/envkit": "~10.0.0-alpha.84",
|
|
5238
|
+
"@geekmidas/errors": "~10.0.0-alpha.84",
|
|
5239
|
+
"@geekmidas/events": "~10.0.0-alpha.84",
|
|
5240
|
+
"@geekmidas/logger": "~10.0.0-alpha.84",
|
|
5241
|
+
"@geekmidas/manifest": "~10.0.0-alpha.84",
|
|
5242
|
+
"@geekmidas/rate-limit": "~10.0.0-alpha.84",
|
|
5243
|
+
"@geekmidas/schema": "~10.0.0-alpha.84",
|
|
5244
|
+
"@geekmidas/services": "~10.0.0-alpha.84",
|
|
5245
|
+
"@geekmidas/storage": "~10.0.0-alpha.84",
|
|
5246
|
+
"@geekmidas/telescope": "~10.0.0-alpha.84",
|
|
5247
|
+
"@geekmidas/testkit": "~10.0.0-alpha.84",
|
|
5145
5248
|
"@geekmidas/cli": `~${loadPackageJson().version}`
|
|
5146
5249
|
};
|
|
5147
5250
|
//#endregion
|
|
@@ -5514,6 +5617,38 @@ coverage/
|
|
|
5514
5617
|
return files;
|
|
5515
5618
|
}
|
|
5516
5619
|
//#endregion
|
|
5620
|
+
//#region src/init/stagesAction.ts
|
|
5621
|
+
/**
|
|
5622
|
+
* How a scaffolded workflow names the `stages` action.
|
|
5623
|
+
*
|
|
5624
|
+
* A published CLI pins it to the commit it was released from: the release
|
|
5625
|
+
* build is given that commit as `GKM_RELEASE_COMMIT`, which the build writes
|
|
5626
|
+
* into the bundle (`define` in tsdown.config.ts). The action at that commit is
|
|
5627
|
+
* the one released beside this CLI, and a commit SHA cannot be moved under a
|
|
5628
|
+
* project the way a branch or a tag can.
|
|
5629
|
+
*
|
|
5630
|
+
* A CLI built anywhere else — a checkout, a local build — knows no released
|
|
5631
|
+
* commit, and names `main`.
|
|
5632
|
+
*/
|
|
5633
|
+
const require$1 = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
5634
|
+
function cliVersion() {
|
|
5635
|
+
try {
|
|
5636
|
+
return require$1("../package.json").version;
|
|
5637
|
+
} catch {
|
|
5638
|
+
return require$1("../../package.json").version;
|
|
5639
|
+
}
|
|
5640
|
+
}
|
|
5641
|
+
/** The action, as a workflow's `uses:` names it before the `@`. */
|
|
5642
|
+
const STAGES_ACTION = "geekmidas/toolbox/actions/stages";
|
|
5643
|
+
const COMMIT = /^[0-9a-f]{40}$/;
|
|
5644
|
+
/**
|
|
5645
|
+
* The `uses:` value for the stages action, with a comment saying which CLI
|
|
5646
|
+
* release the pinned commit is.
|
|
5647
|
+
*/
|
|
5648
|
+
function stagesActionUses(commit = "1a6631b7e6dc71b7dd7b7afb8ca5b82225454826", version = cliVersion()) {
|
|
5649
|
+
return commit && COMMIT.test(commit) ? `${STAGES_ACTION}@${commit} # @geekmidas/cli ${version}` : `${STAGES_ACTION}@main # pin to a commit SHA: see the action's README`;
|
|
5650
|
+
}
|
|
5651
|
+
//#endregion
|
|
5517
5652
|
//#region src/init/generators/github.ts
|
|
5518
5653
|
/**
|
|
5519
5654
|
* The GitHub workflows a scaffold ships with.
|
|
@@ -5523,11 +5658,14 @@ coverage/
|
|
|
5523
5658
|
* release, labelled from their titles.
|
|
5524
5659
|
* - `deploy.yml` — when a deploy target was picked: a push to main deploys the
|
|
5525
5660
|
* stages that are not protected, publishing the drafted release deploys the
|
|
5526
|
-
* protected ones.
|
|
5661
|
+
* protected ones, and a manual run deploys the one stage it names.
|
|
5527
5662
|
*
|
|
5528
|
-
* The deploy workflow names no stage.
|
|
5529
|
-
*
|
|
5530
|
-
*
|
|
5663
|
+
* The deploy workflow names no stage. Its first job runs the
|
|
5664
|
+
* `geekmidas/toolbox/actions/stages` action, which asks the project's own
|
|
5665
|
+
* `gkm stages --github-output` which stages the run builds and deploys — so
|
|
5666
|
+
* the config stays the one place stages are declared, the rules for each event
|
|
5667
|
+
* are tested code in the CLI, and a workflow cannot fall out of step with
|
|
5668
|
+
* either.
|
|
5531
5669
|
*/
|
|
5532
5670
|
/** How each package manager is set up, installs, and runs a script. */
|
|
5533
5671
|
const TOOLING = {
|
|
@@ -5713,46 +5851,21 @@ template: |
|
|
|
5713
5851
|
**Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION
|
|
5714
5852
|
`;
|
|
5715
5853
|
}
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
- uses: aws-actions/configure-aws-credentials@v4
|
|
5723
|
-
with:
|
|
5724
|
-
role-to-assume: \${{ vars.AWS_ROLE_ARN }}
|
|
5725
|
-
aws-region: ${options.region}
|
|
5726
|
-
` : "";
|
|
5727
|
-
const keyDir = `~/.gkm/keys/${require_seeds.projectKey({ name: options.name })}`;
|
|
5728
|
-
const stageSecrets = sst ? credentials : `
|
|
5729
|
-
# The stage's secrets are kept in the encrypted .gkm/secrets/<stage>.json,
|
|
5730
|
-
# and each environment holds its key as GKM_SECRETS_KEY. .gkm/ is
|
|
5731
|
-
# gitignored, so a checkout has the key but not the file: set
|
|
5732
|
-
# secrets.store in gkm.config.ts to a store CI can reach before deploying
|
|
5733
|
-
# from here.
|
|
5734
|
-
# Owner-only, as the CLI writes its own keys. The stage reaches the shell
|
|
5735
|
-
# as a variable, never pasted into the script: on a manual run it is
|
|
5736
|
-
# whatever was typed.
|
|
5737
|
-
- name: Stage secrets key
|
|
5738
|
-
run: |
|
|
5739
|
-
mkdir -p -m 700 ${keyDir}
|
|
5740
|
-
(umask 077 && printf '%s' "$KEY" > ${keyDir}/"$STAGE".key)
|
|
5741
|
-
env:
|
|
5742
|
-
KEY: \${{ secrets.GKM_SECRETS_KEY }}
|
|
5743
|
-
STAGE: \${{ matrix.stage }}
|
|
5744
|
-
`;
|
|
5745
|
-
const deployEnv = sst ? "" : `
|
|
5746
|
-
DOKPLOY_API_TOKEN: \${{ secrets.DOKPLOY_API_TOKEN }}
|
|
5747
|
-
DOKPLOY_ENDPOINT: \${{ vars.DOKPLOY_ENDPOINT }}`;
|
|
5854
|
+
/**
|
|
5855
|
+
* What every deploy workflow starts with: its triggers, and the `stages` job,
|
|
5856
|
+
* which asks the project's own gkm (through the stages action) which stages
|
|
5857
|
+
* this run builds and deploys. Nothing in a workflow names a stage.
|
|
5858
|
+
*/
|
|
5859
|
+
function deployHeader(build) {
|
|
5748
5860
|
return `name: Deploy
|
|
5749
5861
|
|
|
5750
5862
|
# Which stages exist, and which are protected, is read from \`stages\` in
|
|
5751
|
-
# gkm.config.ts
|
|
5863
|
+
# gkm.config.ts by the project's own gkm, through the stages action — nothing
|
|
5864
|
+
# here names one:
|
|
5752
5865
|
#
|
|
5753
|
-
# push to main every deployed stage that is not protected
|
|
5866
|
+
# push to main ${build ? "builds every deployed stage, deploys those not protected" : "every deployed stage that is not protected"}
|
|
5754
5867
|
# release published the protected stages (publish the drafted release)
|
|
5755
|
-
# run workflow the one stage you name
|
|
5868
|
+
# run workflow the one stage you name, at the ref you name
|
|
5756
5869
|
on:
|
|
5757
5870
|
push:
|
|
5758
5871
|
branches: [main]
|
|
@@ -5763,17 +5876,27 @@ on:
|
|
|
5763
5876
|
stage:
|
|
5764
5877
|
description: A deployed stage from gkm.config.ts
|
|
5765
5878
|
required: true
|
|
5879
|
+
type: string
|
|
5880
|
+
ref:
|
|
5881
|
+
description: The commit, tag or branch to deploy (default the latest on main)
|
|
5882
|
+
required: false
|
|
5883
|
+
type: string
|
|
5766
5884
|
|
|
5767
5885
|
permissions:
|
|
5768
5886
|
contents: read
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5887
|
+
`;
|
|
5888
|
+
}
|
|
5889
|
+
function stagesJob(options) {
|
|
5890
|
+
const pm = tooling(options);
|
|
5891
|
+
return ` stages:
|
|
5773
5892
|
name: Pick stages
|
|
5774
5893
|
runs-on: ubuntu-latest
|
|
5775
5894
|
outputs:
|
|
5776
|
-
|
|
5895
|
+
build: \${{ steps.stages.outputs.build }}
|
|
5896
|
+
deploy: \${{ steps.stages.outputs.deploy }}
|
|
5897
|
+
has-build: \${{ steps.stages.outputs.has-build }}
|
|
5898
|
+
has-deploy: \${{ steps.stages.outputs.has-deploy }}
|
|
5899
|
+
aws-region: \${{ steps.stages.outputs.aws-region }}
|
|
5777
5900
|
steps:
|
|
5778
5901
|
- uses: actions/checkout@v4
|
|
5779
5902
|
|
|
@@ -5781,44 +5904,286 @@ ${pm.setup}
|
|
|
5781
5904
|
- name: Install
|
|
5782
5905
|
run: ${pm.install}
|
|
5783
5906
|
|
|
5907
|
+
# Runs \`gkm stages --github-output\`: the rules for each event are the
|
|
5908
|
+
# installed CLI's, and a manual run naming a stage gkm.config.ts does not
|
|
5909
|
+
# deploy fails here.
|
|
5784
5910
|
- name: Read stages from gkm.config.ts
|
|
5785
|
-
id:
|
|
5911
|
+
id: stages
|
|
5912
|
+
uses: ${stagesActionUses()}
|
|
5913
|
+
with:
|
|
5914
|
+
stage: \${{ inputs.stage }}
|
|
5915
|
+
`;
|
|
5916
|
+
}
|
|
5917
|
+
/**
|
|
5918
|
+
* The registry login a compose build pushes with: GitHub's own token on
|
|
5919
|
+
* ghcr.io, otherwise a username variable and a password secret.
|
|
5920
|
+
*/
|
|
5921
|
+
function registryLogin(registry) {
|
|
5922
|
+
const host = registry.split("/")[0];
|
|
5923
|
+
const ghcr = host === "ghcr.io";
|
|
5924
|
+
return ` - uses: docker/login-action@v3
|
|
5925
|
+
with:
|
|
5926
|
+
registry: ${host}
|
|
5927
|
+
username: ${ghcr ? "${{ github.actor }}" : "${{ vars.REGISTRY_USERNAME }}"}
|
|
5928
|
+
password: ${ghcr ? "${{ secrets.GITHUB_TOKEN }}" : "${{ secrets.REGISTRY_PASSWORD }}"}
|
|
5929
|
+
`;
|
|
5930
|
+
}
|
|
5931
|
+
/**
|
|
5932
|
+
* The compose deploy: images are built and pushed by the runner, where the
|
|
5933
|
+
* code is, and pulled by the server, where the stage runs.
|
|
5934
|
+
*
|
|
5935
|
+
* - `build` (on a push): every deployed stage's images, tagged with the
|
|
5936
|
+
* commit, and their digests kept as the artifact `digests-<stage>`.
|
|
5937
|
+
* - `deploy`: the commit the event names — a release's tag, a manual run's
|
|
5938
|
+
* `ref` — then that commit's push build, whose digests pin each image. Over
|
|
5939
|
+
* SSH, with a pinned host key, the server checks the commit out and runs
|
|
5940
|
+
* `gkm compose` on exactly those images.
|
|
5941
|
+
*/
|
|
5942
|
+
function composeDeploy(options) {
|
|
5943
|
+
const pm = tooling(options);
|
|
5944
|
+
const registry = options.registry ?? "";
|
|
5945
|
+
return `${deployHeader(true)}
|
|
5946
|
+
jobs:
|
|
5947
|
+
${stagesJob(options)}
|
|
5948
|
+
build:
|
|
5949
|
+
name: Build \${{ matrix.stage }}
|
|
5950
|
+
needs: stages
|
|
5951
|
+
if: needs.stages.outputs.has-build == 'true'
|
|
5952
|
+
runs-on: ubuntu-latest
|
|
5953
|
+
strategy:
|
|
5954
|
+
fail-fast: false
|
|
5955
|
+
matrix:
|
|
5956
|
+
stage: \${{ fromJSON(needs.stages.outputs.build) }}
|
|
5957
|
+
# One GitHub environment per stage: its secrets, variables and approvals.
|
|
5958
|
+
environment: \${{ matrix.stage }}
|
|
5959
|
+
permissions:
|
|
5960
|
+
contents: read
|
|
5961
|
+
packages: write
|
|
5962
|
+
id-token: write
|
|
5963
|
+
steps:
|
|
5964
|
+
- uses: actions/checkout@v4
|
|
5965
|
+
|
|
5966
|
+
${pm.setup}
|
|
5967
|
+
- name: Install
|
|
5968
|
+
run: ${pm.install}
|
|
5969
|
+
|
|
5970
|
+
${registryLogin(registry)}
|
|
5971
|
+
# A site's public URLs are built into it, so the build reads the stage's
|
|
5972
|
+
# secrets store. With secrets.store on SSM or Secrets Manager the job
|
|
5973
|
+
# assumes the stage's role (AWS_ROLE_ARN, set by gkm deploy:github);
|
|
5974
|
+
# with the default 'file' store there is no role to assume.
|
|
5975
|
+
- name: Assume the stage's AWS role
|
|
5976
|
+
if: needs.stages.outputs.aws-region != ''
|
|
5977
|
+
uses: aws-actions/configure-aws-credentials@v4
|
|
5978
|
+
with:
|
|
5979
|
+
role-to-assume: \${{ vars.AWS_ROLE_ARN }}
|
|
5980
|
+
aws-region: \${{ needs.stages.outputs.aws-region }}
|
|
5981
|
+
|
|
5982
|
+
# Builds and pushes every image the stage runs, tagged with the commit,
|
|
5983
|
+
# and starts nothing.
|
|
5984
|
+
- name: Build and push
|
|
5985
|
+
run: ${pm.exec} gkm compose --stage "$STAGE" --build --push --tag "$SHA" --digests-file digests.json
|
|
5986
|
+
env:
|
|
5987
|
+
STAGE: \${{ matrix.stage }}
|
|
5988
|
+
SHA: \${{ github.sha }}
|
|
5989
|
+
|
|
5990
|
+
# What each tag pointed at when it was pushed. A deploy runs these
|
|
5991
|
+
# digests, so a tag moved since cannot change what is released.
|
|
5992
|
+
- uses: actions/upload-artifact@v4
|
|
5993
|
+
with:
|
|
5994
|
+
name: digests-\${{ matrix.stage }}
|
|
5995
|
+
path: digests.json
|
|
5996
|
+
retention-days: 90
|
|
5997
|
+
|
|
5998
|
+
deploy:
|
|
5999
|
+
name: Deploy \${{ matrix.stage }}
|
|
6000
|
+
needs: [stages, build]
|
|
6001
|
+
# The build is skipped on a release or a manual run: deploy then anyway,
|
|
6002
|
+
# but never after a failed build.
|
|
6003
|
+
if: \${{ !cancelled() && !failure() && needs.stages.outputs.has-deploy == 'true' }}
|
|
6004
|
+
runs-on: ubuntu-latest
|
|
6005
|
+
strategy:
|
|
6006
|
+
fail-fast: false
|
|
6007
|
+
matrix:
|
|
6008
|
+
stage: \${{ fromJSON(needs.stages.outputs.deploy) }}
|
|
6009
|
+
environment: \${{ matrix.stage }}
|
|
6010
|
+
concurrency:
|
|
6011
|
+
group: deploy-\${{ matrix.stage }}
|
|
6012
|
+
cancel-in-progress: false
|
|
6013
|
+
permissions:
|
|
6014
|
+
contents: read
|
|
6015
|
+
actions: read
|
|
6016
|
+
steps:
|
|
6017
|
+
# A release deploys its tag's commit, never its target_commitish — the
|
|
6018
|
+
# branch it was drafted against, which has moved on since.
|
|
6019
|
+
- name: Resolve the commit
|
|
6020
|
+
id: commit
|
|
6021
|
+
run: |
|
|
6022
|
+
case "$EVENT" in
|
|
6023
|
+
release) ref="tags/$TAG" ;;
|
|
6024
|
+
workflow_dispatch) ref="\${REF:-$SHA}" ;;
|
|
6025
|
+
*) ref="$SHA" ;;
|
|
6026
|
+
esac
|
|
6027
|
+
sha=$(gh api "repos/$REPO/commits/$ref" --jq .sha)
|
|
6028
|
+
echo "Deploying $sha"
|
|
6029
|
+
echo "sha=$sha" >> "$GITHUB_OUTPUT"
|
|
6030
|
+
env:
|
|
6031
|
+
GH_TOKEN: \${{ github.token }}
|
|
6032
|
+
REPO: \${{ github.repository }}
|
|
6033
|
+
EVENT: \${{ github.event_name }}
|
|
6034
|
+
TAG: \${{ github.event.release.tag_name }}
|
|
6035
|
+
REF: \${{ inputs.ref }}
|
|
6036
|
+
SHA: \${{ github.sha }}
|
|
6037
|
+
|
|
6038
|
+
# The push run of this workflow that built the commit for this stage:
|
|
6039
|
+
# this run on a push, the newest one with the stage's digests otherwise.
|
|
6040
|
+
- name: Find the commit's push build
|
|
6041
|
+
id: build
|
|
5786
6042
|
run: |
|
|
5787
|
-
$
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
" >> "$GITHUB_OUTPUT"
|
|
6043
|
+
if [ "$EVENT" = push ]; then
|
|
6044
|
+
echo "run-id=$RUN_ID" >> "$GITHUB_OUTPUT"
|
|
6045
|
+
exit 0
|
|
6046
|
+
fi
|
|
6047
|
+
workflow=\${WORKFLOW_REF%%@*}
|
|
6048
|
+
workflow=\${workflow##*/}
|
|
6049
|
+
for id in $(gh run list --repo "$REPO" --workflow "$workflow" --event push --commit "$SHA" --limit 20 --json databaseId --jq '.[].databaseId'); do
|
|
6050
|
+
found=$(gh api "repos/$REPO/actions/runs/$id/artifacts?name=$ARTIFACT" --jq '[.artifacts[] | select(.expired | not)] | length')
|
|
6051
|
+
if [ "$found" -gt 0 ]; then
|
|
6052
|
+
echo "run-id=$id" >> "$GITHUB_OUTPUT"
|
|
6053
|
+
exit 0
|
|
6054
|
+
fi
|
|
6055
|
+
done
|
|
6056
|
+
echo "run-id=" >> "$GITHUB_OUTPUT"
|
|
5801
6057
|
env:
|
|
6058
|
+
GH_TOKEN: \${{ github.token }}
|
|
6059
|
+
REPO: \${{ github.repository }}
|
|
5802
6060
|
EVENT: \${{ github.event_name }}
|
|
5803
|
-
|
|
6061
|
+
RUN_ID: \${{ github.run_id }}
|
|
6062
|
+
WORKFLOW_REF: \${{ github.workflow_ref }}
|
|
6063
|
+
SHA: \${{ steps.commit.outputs.sha }}
|
|
6064
|
+
ARTIFACT: digests-\${{ matrix.stage }}
|
|
6065
|
+
|
|
6066
|
+
- name: Download digests-\${{ matrix.stage }}
|
|
6067
|
+
if: steps.build.outputs.run-id != ''
|
|
6068
|
+
uses: actions/download-artifact@v4
|
|
6069
|
+
with:
|
|
6070
|
+
name: digests-\${{ matrix.stage }}
|
|
6071
|
+
run-id: \${{ steps.build.outputs.run-id }}
|
|
6072
|
+
github-token: \${{ github.token }}
|
|
5804
6073
|
|
|
6074
|
+
- name: No digests — deploying by tag
|
|
6075
|
+
if: steps.build.outputs.run-id == ''
|
|
6076
|
+
run: |
|
|
6077
|
+
echo "::warning title=$STAGE deploys by tag, not digest::No push build of $SHA kept digests-$STAGE (never built, or older than 90 days). The server runs whatever the tag $SHA points at in the registry now, which anyone who can push there could have replaced."
|
|
6078
|
+
env:
|
|
6079
|
+
STAGE: \${{ matrix.stage }}
|
|
6080
|
+
SHA: \${{ steps.commit.outputs.sha }}
|
|
6081
|
+
|
|
6082
|
+
# Each environment holds DEPLOY_SSH_KEY (secret) and DEPLOY_KNOWN_HOSTS,
|
|
6083
|
+
# DEPLOY_HOST, DEPLOY_USER and DEPLOY_PATH (variables): the server's
|
|
6084
|
+
# host key is pinned, never accepted on first sight. DEPLOY_PATH is a
|
|
6085
|
+
# clone of this repository, with a docker login to ${registry.split("/")[0]}
|
|
6086
|
+
# and the stage's secrets.
|
|
6087
|
+
#
|
|
6088
|
+
# Every value reaches the server as an argument to a quoted heredoc —
|
|
6089
|
+
# nothing is pasted into the script.
|
|
6090
|
+
- name: Deploy on the server
|
|
6091
|
+
run: |
|
|
6092
|
+
mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
|
6093
|
+
(umask 077 && printf '%s\\n' "$SSH_KEY" > ~/.ssh/deploy_key)
|
|
6094
|
+
printf '%s\\n' "$KNOWN_HOSTS" > ~/.ssh/known_hosts
|
|
6095
|
+
digests=""
|
|
6096
|
+
if [ -f digests.json ]; then digests=$(base64 -w0 < digests.json); fi
|
|
6097
|
+
ssh -i ~/.ssh/deploy_key -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes \\
|
|
6098
|
+
"$DEPLOY_USER@$DEPLOY_HOST" \\
|
|
6099
|
+
"bash -s -- $(printf '%q ' "$STAGE" "$SHA" "$DEPLOY_PATH" "$digests")" <<'REMOTE'
|
|
6100
|
+
set -euo pipefail
|
|
6101
|
+
stage=$1 sha=$2 dir=$3 digests=$4
|
|
6102
|
+
cd "$dir"
|
|
6103
|
+
git fetch --quiet origin
|
|
6104
|
+
git checkout --quiet --detach "$sha"
|
|
6105
|
+
${pm.install}
|
|
6106
|
+
args=(--stage "$stage" --tag "$sha")
|
|
6107
|
+
if [ -n "$digests" ]; then
|
|
6108
|
+
mkdir -p .gkm
|
|
6109
|
+
printf '%s' "$digests" | base64 -d > ".gkm/digests-$stage.json"
|
|
6110
|
+
args+=(--digests-file ".gkm/digests-$stage.json")
|
|
6111
|
+
fi
|
|
6112
|
+
${pm.exec} gkm compose "\${args[@]}"
|
|
6113
|
+
REMOTE
|
|
6114
|
+
env:
|
|
6115
|
+
SSH_KEY: \${{ secrets.DEPLOY_SSH_KEY }}
|
|
6116
|
+
KNOWN_HOSTS: \${{ vars.DEPLOY_KNOWN_HOSTS }}
|
|
6117
|
+
DEPLOY_HOST: \${{ vars.DEPLOY_HOST }}
|
|
6118
|
+
DEPLOY_USER: \${{ vars.DEPLOY_USER }}
|
|
6119
|
+
DEPLOY_PATH: \${{ vars.DEPLOY_PATH }}
|
|
6120
|
+
STAGE: \${{ matrix.stage }}
|
|
6121
|
+
SHA: \${{ steps.commit.outputs.sha }}
|
|
6122
|
+
`;
|
|
6123
|
+
}
|
|
6124
|
+
/**
|
|
6125
|
+
* Dokploy and SST: `gkm deploy` builds, releases and health-checks a stage in
|
|
6126
|
+
* one step, from a checkout, so there is no separate build job — the stages
|
|
6127
|
+
* job's `deploy` list is the matrix, and `build` goes unused.
|
|
6128
|
+
*/
|
|
6129
|
+
function targetDeploy(options) {
|
|
6130
|
+
const pm = tooling(options);
|
|
6131
|
+
const sst = options.deployTarget === "sst";
|
|
6132
|
+
const credentials = sst ? `
|
|
6133
|
+
# An IAM role GitHub assumes through OIDC — no long-lived AWS keys. Set
|
|
6134
|
+
# AWS_ROLE_ARN as a variable on each environment.
|
|
6135
|
+
- uses: aws-actions/configure-aws-credentials@v4
|
|
6136
|
+
with:
|
|
6137
|
+
role-to-assume: \${{ vars.AWS_ROLE_ARN }}
|
|
6138
|
+
aws-region: ${options.region}
|
|
6139
|
+
` : "";
|
|
6140
|
+
const keyDir = `~/.gkm/keys/${require_seeds.projectKey({ name: options.name })}`;
|
|
6141
|
+
const stageSecrets = sst ? credentials : `
|
|
6142
|
+
# The stage's secrets are kept in the encrypted .gkm/secrets/<stage>.json,
|
|
6143
|
+
# and each environment holds its key as GKM_SECRETS_KEY. .gkm/ is
|
|
6144
|
+
# gitignored, so a checkout has the key but not the file: set
|
|
6145
|
+
# secrets.store in gkm.config.ts to a store CI can reach before deploying
|
|
6146
|
+
# from here.
|
|
6147
|
+
# Owner-only, as the CLI writes its own keys. The stage reaches the shell
|
|
6148
|
+
# as a variable, never pasted into the script: on a manual run it is
|
|
6149
|
+
# whatever was typed.
|
|
6150
|
+
- name: Stage secrets key
|
|
6151
|
+
run: |
|
|
6152
|
+
mkdir -p ${keyDir} && chmod 700 ${keyDir}
|
|
6153
|
+
(umask 077 && printf '%s' "$KEY" > ${keyDir}/"$STAGE".key)
|
|
6154
|
+
env:
|
|
6155
|
+
KEY: \${{ secrets.GKM_SECRETS_KEY }}
|
|
6156
|
+
STAGE: \${{ matrix.stage }}
|
|
6157
|
+
`;
|
|
6158
|
+
const deployEnv = sst ? "" : `
|
|
6159
|
+
DOKPLOY_API_TOKEN: \${{ secrets.DOKPLOY_API_TOKEN }}
|
|
6160
|
+
DOKPLOY_ENDPOINT: \${{ vars.DOKPLOY_ENDPOINT }}`;
|
|
6161
|
+
return `${deployHeader(false)}
|
|
6162
|
+
jobs:
|
|
6163
|
+
${stagesJob(options)}
|
|
5805
6164
|
deploy:
|
|
5806
6165
|
name: Deploy \${{ matrix.stage }}
|
|
5807
6166
|
needs: stages
|
|
5808
|
-
if: needs.stages.outputs.
|
|
6167
|
+
if: needs.stages.outputs.has-deploy == 'true'
|
|
5809
6168
|
runs-on: ubuntu-latest
|
|
5810
6169
|
strategy:
|
|
5811
6170
|
fail-fast: false
|
|
5812
6171
|
matrix:
|
|
5813
|
-
stage: \${{ fromJSON(needs.stages.outputs.
|
|
6172
|
+
stage: \${{ fromJSON(needs.stages.outputs.deploy) }}
|
|
5814
6173
|
# One GitHub environment per stage: its secrets and variables, and any
|
|
5815
6174
|
# approval rule you put on a protected one.
|
|
5816
6175
|
environment: \${{ matrix.stage }}
|
|
5817
6176
|
concurrency:
|
|
5818
6177
|
group: deploy-\${{ matrix.stage }}
|
|
5819
6178
|
cancel-in-progress: false
|
|
6179
|
+
permissions:
|
|
6180
|
+
contents: read${sst ? "\n id-token: write" : ""}
|
|
5820
6181
|
steps:
|
|
6182
|
+
# The event's own commit — a release's tag, the push — or the ref a
|
|
6183
|
+
# manual run names.
|
|
5821
6184
|
- uses: actions/checkout@v4
|
|
6185
|
+
with:
|
|
6186
|
+
ref: \${{ inputs.ref }}
|
|
5822
6187
|
|
|
5823
6188
|
${pm.setup}
|
|
5824
6189
|
- name: Install
|
|
@@ -5832,6 +6197,9 @@ ${stageSecrets}
|
|
|
5832
6197
|
STAGE: \${{ matrix.stage }}${deployEnv}
|
|
5833
6198
|
`;
|
|
5834
6199
|
}
|
|
6200
|
+
function deploy(options) {
|
|
6201
|
+
return options.deployTarget === "compose" ? composeDeploy(options) : targetDeploy(options);
|
|
6202
|
+
}
|
|
5835
6203
|
function generateGithubFiles(options) {
|
|
5836
6204
|
const files = [
|
|
5837
6205
|
{
|
|
@@ -6672,6 +7040,11 @@ export type ListUsersResponse = z.infer<typeof ListUsersResponseSchema>;
|
|
|
6672
7040
|
const perStage = (options, command) => Object.fromEntries(options.stages.deployed.map((stage) => [`deploy:${stage}`, command(stage)]));
|
|
6673
7041
|
function deployPackage(options) {
|
|
6674
7042
|
switch (options.deployTarget) {
|
|
7043
|
+
case "compose": return {
|
|
7044
|
+
scripts: perStage(options, (stage) => `gkm compose --stage ${stage}`),
|
|
7045
|
+
dependencies: {},
|
|
7046
|
+
devDependencies: {}
|
|
7047
|
+
};
|
|
6675
7048
|
case "dokploy": return {
|
|
6676
7049
|
scripts: perStage(options, (stage) => `gkm deploy --stage ${stage}`),
|
|
6677
7050
|
dependencies: {},
|
|
@@ -7181,6 +7554,13 @@ ${workspaceConstructsGlobs(options.routesStructure, (0, node_path.dirname)(optio
|
|
|
7181
7554
|
* `gkm build` builds for, and which backends a cache or a broker resolves to.
|
|
7182
7555
|
*/
|
|
7183
7556
|
function deployBlock(options) {
|
|
7557
|
+
if (options.deployTarget === "compose") return `
|
|
7558
|
+
// \`gkm compose --stage <stage>\` runs a stage as one Docker Compose stack on
|
|
7559
|
+
// the machine it runs on. CI builds every image and pushes it here; the
|
|
7560
|
+
// server pulls exactly those. On ghcr.io the owner is the repository's —
|
|
7561
|
+
// the user or organisation whose packages the workflow's token can write.
|
|
7562
|
+
deploy: { default: 'compose', registry: '${options.registry}' },
|
|
7563
|
+
`;
|
|
7184
7564
|
if (options.deployTarget !== "sst") return "";
|
|
7185
7565
|
return `
|
|
7186
7566
|
// \`gkm deploy\` runs \`sst deploy\` on the manifest \`gkm build\` writes to
|
|
@@ -9757,6 +10137,11 @@ const deployTargetChoices = [
|
|
|
9757
10137
|
value: "dokploy",
|
|
9758
10138
|
description: "Deploy to Dokploy (Docker-based hosting)"
|
|
9759
10139
|
},
|
|
10140
|
+
{
|
|
10141
|
+
title: "Server (Docker Compose)",
|
|
10142
|
+
value: "compose",
|
|
10143
|
+
description: "One Docker Compose stack per stage on your own server; CI builds the images"
|
|
10144
|
+
},
|
|
9760
10145
|
{
|
|
9761
10146
|
title: "AWS (SST)",
|
|
9762
10147
|
value: "sst",
|
|
@@ -9894,6 +10279,13 @@ async function initCommand(projectName, options = {}) {
|
|
|
9894
10279
|
message: "AWS region (e.g. eu-west-1):",
|
|
9895
10280
|
validate: (value) => AWS_REGION.test(value.trim()) || "An AWS region, like eu-west-1"
|
|
9896
10281
|
},
|
|
10282
|
+
{
|
|
10283
|
+
type: (_prev, values) => !options.yes && !options.registry && (options.deploy ?? values.deployTarget) === "compose" ? "text" : null,
|
|
10284
|
+
name: "registry",
|
|
10285
|
+
message: "Container registry CI pushes to (e.g. ghcr.io/<your GitHub owner>):",
|
|
10286
|
+
initial: (_prev, values) => defaultRegistry(projectName || options.name || values.name),
|
|
10287
|
+
validate: (value) => value.trim().length > 0 || "A registry, like ghcr.io/acme"
|
|
10288
|
+
},
|
|
9897
10289
|
{
|
|
9898
10290
|
type: options.yes || options.stages ? null : "text",
|
|
9899
10291
|
name: "deployedStages",
|
|
@@ -9995,6 +10387,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
9995
10387
|
packageManager: pkgManager,
|
|
9996
10388
|
deployTarget,
|
|
9997
10389
|
stages: resolveStages(options, answers),
|
|
10390
|
+
...deployTarget === "compose" ? { registry: options.registry ?? answers.registry?.trim() ?? defaultRegistry(name) } : {},
|
|
9998
10391
|
...deployTarget === "sst" ? { region: options.region ?? (options.yes ? "eu-west-1" : answers.region?.trim()) } : {},
|
|
9999
10392
|
constructs,
|
|
10000
10393
|
frontendFramework
|
|
@@ -10166,6 +10559,13 @@ function printNextSteps(projectName, options, pkgManager) {
|
|
|
10166
10559
|
for (const stage of deployed) console.log(` ${require_utils.getRunCommand(pkgManager, `deploy:${stage}`)}`);
|
|
10167
10560
|
console.log("");
|
|
10168
10561
|
}
|
|
10562
|
+
if (options.deployTarget === "compose") {
|
|
10563
|
+
console.log("🚀 Deployment (Docker Compose, on your server):");
|
|
10564
|
+
console.log(` Images are pushed to ${options.registry}; .github/workflows/deploy.yml builds them`);
|
|
10565
|
+
console.log(" and runs gkm compose on the server over SSH. See the comments in it for the");
|
|
10566
|
+
console.log(" environment variables and secrets each stage needs.");
|
|
10567
|
+
console.log("");
|
|
10568
|
+
}
|
|
10169
10569
|
if (options.deployTarget === "sst") {
|
|
10170
10570
|
console.log("🚀 Deployment (AWS, through SST):");
|
|
10171
10571
|
for (const stage of deployed) console.log(` ${require_utils.getRunCommand(pkgManager, `deploy:${stage}`)} # gkm deploy: build, sst deploy, health checks`);
|
|
@@ -10205,6 +10605,14 @@ var UnknownDeployTarget = class extends Error {
|
|
|
10205
10605
|
this.name = "UnknownDeployTarget";
|
|
10206
10606
|
}
|
|
10207
10607
|
};
|
|
10608
|
+
/**
|
|
10609
|
+
* Where a compose deploy's images go when nobody said: GitHub's registry,
|
|
10610
|
+
* under an owner named after the project. The generated config says to change
|
|
10611
|
+
* it to the repository's owner, whose packages the workflow's token can write.
|
|
10612
|
+
*/
|
|
10613
|
+
function defaultRegistry(name) {
|
|
10614
|
+
return `ghcr.io/${(name ?? "my-org").toLowerCase()}`;
|
|
10615
|
+
}
|
|
10208
10616
|
/** `--region` that is not shaped like one, e.g. `europe` for `eu-west-1`. */
|
|
10209
10617
|
var NotAnAwsRegion = class extends Error {
|
|
10210
10618
|
region;
|
|
@@ -10909,7 +11317,7 @@ function testDatabases(reconciled) {
|
|
|
10909
11317
|
* starts without the reference data the app needs.
|
|
10910
11318
|
*/
|
|
10911
11319
|
async function migrateTestStage(workspace, env) {
|
|
10912
|
-
const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-
|
|
11320
|
+
const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-BfZN1S32.cjs"));
|
|
10913
11321
|
const { discover } = await Promise.resolve().then(() => require("./discover-D1It5r_h.cjs")).then((n) => n.discover_exports);
|
|
10914
11322
|
const sources = {};
|
|
10915
11323
|
const manifest = await discover({
|
|
@@ -11245,7 +11653,7 @@ const program = new commander.Command();
|
|
|
11245
11653
|
program.name("gkm").description("GeekMidas backend framework CLI").version(version).option("--cwd <path>", "Change working directory").option("--debug", "Enable debug mode (verbose errors with stack traces)").hook("preAction", () => {
|
|
11246
11654
|
if (program.opts().debug);
|
|
11247
11655
|
});
|
|
11248
|
-
program.command("init").description("Scaffold a new project").argument("[name]", "Project name").option("--template <template>", "Project template (minimal, api, serverless, worker)").option("--skip-install", "Skip dependency installation", false).option("-y, --yes", "Skip prompts, use defaults", false).option("--monorepo", "Setup as monorepo with packages/models", false).option("--api-path <path>", "API app path in monorepo (default: apps/api)").option("--pm <manager>", "Package manager (pnpm, npm, yarn, bun)").option("--deploy <target>", "Where it deploys (dokploy, sst, none)").option("--region <region>", "AWS region for an SST deploy (e.g. eu-west-1)").option("--stages <names>", "Deployed stages, comma-separated (e.g. staging,prod)").option("--protected-stage <name>", "Which deployed stage is production").option("--local-stage <name>", "What gkm dev runs as (e.g. dev)").action(async (name, options) => {
|
|
11656
|
+
program.command("init").description("Scaffold a new project").argument("[name]", "Project name").option("--template <template>", "Project template (minimal, api, serverless, worker)").option("--skip-install", "Skip dependency installation", false).option("-y, --yes", "Skip prompts, use defaults", false).option("--monorepo", "Setup as monorepo with packages/models", false).option("--api-path <path>", "API app path in monorepo (default: apps/api)").option("--pm <manager>", "Package manager (pnpm, npm, yarn, bun)").option("--deploy <target>", "Where it deploys (dokploy, compose, sst, none)").option("--region <region>", "AWS region for an SST deploy (e.g. eu-west-1)").option("--registry <registry>", "Container registry for a compose deploy (e.g. ghcr.io/acme)").option("--stages <names>", "Deployed stages, comma-separated (e.g. staging,prod)").option("--protected-stage <name>", "Which deployed stage is production").option("--local-stage <name>", "What gkm dev runs as (e.g. dev)").action(async (name, options) => {
|
|
11249
11657
|
try {
|
|
11250
11658
|
const globalOptions = program.opts();
|
|
11251
11659
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
@@ -11353,7 +11761,7 @@ program.command("migrate").description("Apply each database construct's migratio
|
|
|
11353
11761
|
try {
|
|
11354
11762
|
const globalOptions = program.opts();
|
|
11355
11763
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11356
|
-
const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11764
|
+
const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-BfZN1S32.cjs"));
|
|
11357
11765
|
await migrateCommand({
|
|
11358
11766
|
...options,
|
|
11359
11767
|
...construct ? { construct } : {}
|
|
@@ -11367,7 +11775,7 @@ program.command("seed").description("Migrate, then run each database construct's
|
|
|
11367
11775
|
try {
|
|
11368
11776
|
const globalOptions = program.opts();
|
|
11369
11777
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11370
|
-
const { seedCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11778
|
+
const { seedCommand } = await Promise.resolve().then(() => require("./migrate-BfZN1S32.cjs"));
|
|
11371
11779
|
await seedCommand({
|
|
11372
11780
|
...options,
|
|
11373
11781
|
...construct ? { construct } : {}
|
|
@@ -11381,7 +11789,7 @@ program.command("migration").description("Write a construct's next migration: an
|
|
|
11381
11789
|
try {
|
|
11382
11790
|
const globalOptions = program.opts();
|
|
11383
11791
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11384
|
-
const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11792
|
+
const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-BfZN1S32.cjs"));
|
|
11385
11793
|
await migrationCommand({
|
|
11386
11794
|
construct,
|
|
11387
11795
|
...name ? { name } : {}
|
|
@@ -11489,7 +11897,7 @@ program.command("secrets:add").description("Build the keys a stage must be given
|
|
|
11489
11897
|
try {
|
|
11490
11898
|
const globalOptions = program.opts();
|
|
11491
11899
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11492
|
-
const { secretsAddCommand } = await Promise.resolve().then(() => require("./add-
|
|
11900
|
+
const { secretsAddCommand } = await Promise.resolve().then(() => require("./add-BQ8v1ZII.cjs"));
|
|
11493
11901
|
await secretsAddCommand(options);
|
|
11494
11902
|
} catch (error) {
|
|
11495
11903
|
console.error(formatError(error));
|
|
@@ -11500,7 +11908,7 @@ program.command("encryption:rotate").description("Add a new current key to an En
|
|
|
11500
11908
|
try {
|
|
11501
11909
|
const globalOptions = program.opts();
|
|
11502
11910
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11503
|
-
const { encryptionRotateCommand } = await Promise.resolve().then(() => require("./encryption-
|
|
11911
|
+
const { encryptionRotateCommand } = await Promise.resolve().then(() => require("./encryption-g6PzwwfL.cjs"));
|
|
11504
11912
|
await encryptionRotateCommand(construct, options);
|
|
11505
11913
|
} catch (error) {
|
|
11506
11914
|
console.error(formatError(error));
|
|
@@ -11511,7 +11919,7 @@ program.command("encryption:retire").description("Remove an old key from an Encr
|
|
|
11511
11919
|
try {
|
|
11512
11920
|
const globalOptions = program.opts();
|
|
11513
11921
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11514
|
-
const { encryptionRetireCommand } = await Promise.resolve().then(() => require("./encryption-
|
|
11922
|
+
const { encryptionRetireCommand } = await Promise.resolve().then(() => require("./encryption-g6PzwwfL.cjs"));
|
|
11515
11923
|
await encryptionRetireCommand(construct, key, options);
|
|
11516
11924
|
} catch (error) {
|
|
11517
11925
|
console.error(formatError(error));
|
|
@@ -11554,7 +11962,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
11554
11962
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11555
11963
|
const { loadWorkspaceConfig } = await Promise.resolve().then(() => require("./config.cjs"));
|
|
11556
11964
|
const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-CuCQBa5-.cjs"));
|
|
11557
|
-
const { secretsStoreFor } = await Promise.resolve().then(() => require("./seeds-
|
|
11965
|
+
const { secretsStoreFor } = await Promise.resolve().then(() => require("./seeds-DQ0FG57Z.cjs")).then((n) => n.store_exports);
|
|
11558
11966
|
const { workspace } = await loadWorkspaceConfig();
|
|
11559
11967
|
const stage = options.stage ?? workspace.stages.local;
|
|
11560
11968
|
const store = await secretsStoreFor(workspace, stage);
|
|
@@ -11563,7 +11971,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
11563
11971
|
console.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
|
|
11564
11972
|
process.exit(1);
|
|
11565
11973
|
}
|
|
11566
|
-
const { derivedContainers } = await Promise.resolve().then(() => require("./seeds-
|
|
11974
|
+
const { derivedContainers } = await Promise.resolve().then(() => require("./seeds-DQ0FG57Z.cjs")).then((n) => n.workspace_exports);
|
|
11567
11975
|
const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
|
|
11568
11976
|
if (!result) {
|
|
11569
11977
|
console.log(`\n✓ Secrets for stage "${stage}" are up-to-date`);
|
|
@@ -11581,7 +11989,7 @@ program.command("secrets:migrate").description("Copy a deployed stage's secrets
|
|
|
11581
11989
|
try {
|
|
11582
11990
|
const globalOptions = program.opts();
|
|
11583
11991
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11584
|
-
const { secretsMigrateCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11992
|
+
const { secretsMigrateCommand } = await Promise.resolve().then(() => require("./migrate-FoL_mZIz.cjs"));
|
|
11585
11993
|
await secretsMigrateCommand(options);
|
|
11586
11994
|
} catch (error) {
|
|
11587
11995
|
console.error(formatError(error));
|
|
@@ -11589,7 +11997,7 @@ program.command("secrets:migrate").description("Copy a deployed stage's secrets
|
|
|
11589
11997
|
}
|
|
11590
11998
|
});
|
|
11591
11999
|
program.command("deploy").description("Deploy a stage through its target").option("--target <name>", "Deploy target: dokploy, compose, sst, or one named in deploy.targets (default: deploy.default)").option("--provider <provider>", "[DEPRECATED] Use --target instead").requiredOption("--stage <stage>", "Deployment stage (e.g., production, staging)").option("--tag <tag>", "Image tag (default: stage-timestamp; compose: the commit). Compose pulls a given tag").option("--skip-push", "Skip pushing image to registry").option("--skip-build", "Skip build step (use existing build)").option("--json", "Write events as JSON lines instead of progress; never prompts").option("--dry-run", "Show what would be created or reused; change, build and push nothing").option("--atomic", "If the release fails, roll back every app it released, not only the failed ones").option("--allow-dev-services <list>", "Server targets: run MinIO and/or Mailpit (minio,mailpit) for mail and buckets the stage's secrets don't configure. Not production-grade").action(async (options) => {
|
|
11592
|
-
const { deployCli } = await Promise.resolve().then(() => require("./cli-
|
|
12000
|
+
const { deployCli } = await Promise.resolve().then(() => require("./cli-D8YQAYUX.cjs"));
|
|
11593
12001
|
const globalOptions = program.opts();
|
|
11594
12002
|
const code = await deployCli({
|
|
11595
12003
|
cwd: (0, node_path.resolve)(globalOptions.cwd ?? process.cwd()),
|
|
@@ -11606,7 +12014,7 @@ program.command("deploy").description("Deploy a stage through its target").optio
|
|
|
11606
12014
|
});
|
|
11607
12015
|
program.command("deploy:rollback").description("Put a stage's app back on its previous release (Dokploy): one app with --app, every app with --atomic").requiredOption("--stage <stage>", "A deployed stage").option("--app <app>", "The app to roll back").option("--atomic", "Roll back every app that has an earlier release").action(async (options) => {
|
|
11608
12016
|
try {
|
|
11609
|
-
const { rollbackStage } = await Promise.resolve().then(() => require("./rollback-
|
|
12017
|
+
const { rollbackStage } = await Promise.resolve().then(() => require("./rollback-CPSDjGse.cjs")).then((n) => n.rollback_exports);
|
|
11610
12018
|
const { terminalCredentials } = await Promise.resolve().then(() => require("./terminal-BL5E0xbR.cjs"));
|
|
11611
12019
|
const globalOptions = program.opts();
|
|
11612
12020
|
await rollbackStage({
|
|
@@ -11642,13 +12050,24 @@ program.command("deploy:github").description("Let GitHub Actions deploy a stage:
|
|
|
11642
12050
|
try {
|
|
11643
12051
|
const globalOptions = program.opts();
|
|
11644
12052
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11645
|
-
const { deployGithubCommand } = await Promise.resolve().then(() => require("./github-
|
|
12053
|
+
const { deployGithubCommand } = await Promise.resolve().then(() => require("./github-B8YjwdLK.cjs"));
|
|
11646
12054
|
await deployGithubCommand(options);
|
|
11647
12055
|
} catch (error) {
|
|
11648
12056
|
console.error(formatError(error));
|
|
11649
12057
|
process.exit(1);
|
|
11650
12058
|
}
|
|
11651
12059
|
});
|
|
12060
|
+
program.command("stages").description("The workspace's stages from gkm.config.ts: local, deployed and protected").option("--json", "Print them as JSON").option("--github-output", "Write the stages, and which this workflow run builds and deploys, to $GITHUB_OUTPUT").option("--event <name>", "The event to plan for (default: $GITHUB_EVENT_NAME)").option("--stage <stage>", "The stage a workflow_dispatch deploys").action(async (options) => {
|
|
12061
|
+
try {
|
|
12062
|
+
const globalOptions = program.opts();
|
|
12063
|
+
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
12064
|
+
const { stagesCommand } = await Promise.resolve().then(() => require("./stages-CS1sjcRb.cjs"));
|
|
12065
|
+
await stagesCommand(options);
|
|
12066
|
+
} catch (error) {
|
|
12067
|
+
console.error(formatError(error));
|
|
12068
|
+
process.exit(1);
|
|
12069
|
+
}
|
|
12070
|
+
});
|
|
11652
12071
|
program.command("deploy:list").description("List Dokploy resources (projects, registries)").option("--endpoint <url>", "Dokploy server URL (uses stored credentials if logged in)").option("--projects", "List projects").option("--registries", "List registries").action(async (options) => {
|
|
11653
12072
|
try {
|
|
11654
12073
|
const globalOptions = program.opts();
|