@geekmidas/cli 10.0.0-alpha.75 → 10.0.0-alpha.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{LegacyStateStore-BFnXUFlx.cjs → LegacyStateStore-DwngfJxr.cjs} +2 -2
- package/dist/{LegacyStateStore-BFnXUFlx.cjs.map → LegacyStateStore-DwngfJxr.cjs.map} +1 -1
- package/dist/{LegacyStateStore-cpt3K1vx.mjs → LegacyStateStore-dyq07_Ir.mjs} +2 -2
- package/dist/{LegacyStateStore-cpt3K1vx.mjs.map → LegacyStateStore-dyq07_Ir.mjs.map} +1 -1
- package/dist/{LocalStateStore-zQGZ9b4J.cjs → LocalStateStore-B0NCde8Z.cjs} +2 -2
- package/dist/{LocalStateStore-zQGZ9b4J.cjs.map → LocalStateStore-B0NCde8Z.cjs.map} +1 -1
- package/dist/{LocalStateStore-RH9F2ZEy.mjs → LocalStateStore-DLxCCatI.mjs} +2 -2
- package/dist/{LocalStateStore-RH9F2ZEy.mjs.map → LocalStateStore-DLxCCatI.mjs.map} +1 -1
- package/dist/{S3StateStore-CT-ZMlQY.cjs → S3StateStore-BOenb-3o.cjs} +2 -2
- package/dist/{S3StateStore-CT-ZMlQY.cjs.map → S3StateStore-BOenb-3o.cjs.map} +1 -1
- package/dist/{S3StateStore-DBeBc0c0.mjs → S3StateStore-CGK_4hlo.mjs} +2 -2
- package/dist/{S3StateStore-DBeBc0c0.mjs.map → S3StateStore-CGK_4hlo.mjs.map} +1 -1
- package/dist/{SSMStateStore-rnzNfOaV.mjs → SSMStateStore-B_5_RqY-.mjs} +2 -2
- package/dist/{SSMStateStore-rnzNfOaV.mjs.map → SSMStateStore-B_5_RqY-.mjs.map} +1 -1
- package/dist/{SSMStateStore-HmsH3c4v.cjs → SSMStateStore-DYeD__7p.cjs} +2 -2
- package/dist/{SSMStateStore-HmsH3c4v.cjs.map → SSMStateStore-DYeD__7p.cjs.map} +1 -1
- package/dist/{add-Cvzdw8cf.mjs → add-B7IMXzou.mjs} +3 -3
- package/dist/{add-Cvzdw8cf.mjs.map → add-B7IMXzou.mjs.map} +1 -1
- package/dist/{add-CHBin8TF.cjs → add-j2yI3cbS.cjs} +3 -3
- package/dist/{add-CHBin8TF.cjs.map → add-j2yI3cbS.cjs.map} +1 -1
- package/dist/{aws-DojzQnLd.mjs → aws-Bja4zGSs.mjs} +13 -9
- package/dist/aws-Bja4zGSs.mjs.map +1 -0
- package/dist/{aws-DkHdTV-p.cjs → aws-CQAuluiu.cjs} +13 -9
- package/dist/aws-CQAuluiu.cjs.map +1 -0
- package/dist/awsStore-7VmS_cZR.cjs +54 -0
- package/dist/awsStore-7VmS_cZR.cjs.map +1 -0
- package/dist/awsStore-B529csle.mjs +43 -0
- package/dist/awsStore-B529csle.mjs.map +1 -0
- package/dist/{bundler-_8AEZhrs.cjs → bundler-Cf6OgaOe.cjs} +5 -5
- package/dist/bundler-Cf6OgaOe.cjs.map +1 -0
- package/dist/{bundler-xjp5RwRS.mjs → bundler-DO6bHhnb.mjs} +5 -5
- package/dist/bundler-DO6bHhnb.mjs.map +1 -0
- package/dist/{cli-BTGfA0B7.mjs → cli-BCPOHmg9.mjs} +3 -3
- package/dist/{cli-BTGfA0B7.mjs.map → cli-BCPOHmg9.mjs.map} +1 -1
- package/dist/{cli-B4ktxAsM.cjs → cli-CNanUB7a.cjs} +3 -3
- package/dist/{cli-B4ktxAsM.cjs.map → cli-CNanUB7a.cjs.map} +1 -1
- package/dist/{compose-DdH2JQJD.mjs → compose-Dq4VCtu5.mjs} +4 -3
- package/dist/compose-Dq4VCtu5.mjs.map +1 -0
- package/dist/{compose-UKyv_1yU.cjs → compose-h_6oNnHC.cjs} +4 -3
- package/dist/compose-h_6oNnHC.cjs.map +1 -0
- package/dist/{config-B38YWicj.d.cts → config-CWyhLSY1.d.cts} +3 -3
- package/dist/{config-B38YWicj.d.cts.map → config-CWyhLSY1.d.cts.map} +1 -1
- package/dist/{config-DA0kRTQe.d.mts → config-CqAvPP-f.d.mts} +3 -3
- package/dist/{config-DA0kRTQe.d.mts.map → config-CqAvPP-f.d.mts.map} +1 -1
- 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-XUZoA1us.cjs → deploy-CT3R9de9.cjs} +5 -5
- package/dist/{deploy-XUZoA1us.cjs.map → deploy-CT3R9de9.cjs.map} +1 -1
- package/dist/{deploy-CuSsiFIc.mjs → deploy-CVXEx7Nm.mjs} +5 -5
- package/dist/{deploy-CuSsiFIc.mjs.map → deploy-CVXEx7Nm.mjs.map} +1 -1
- package/dist/{dokploy-DZXTQX10.mjs → dokploy-CYm2ozFs.mjs} +2 -2
- package/dist/{dokploy-DZXTQX10.mjs.map → dokploy-CYm2ozFs.mjs.map} +1 -1
- package/dist/{dokploy-Cvgg_pID.cjs → dokploy-eSGmlhhj.cjs} +2 -2
- package/dist/{dokploy-Cvgg_pID.cjs.map → dokploy-eSGmlhhj.cjs.map} +1 -1
- package/dist/{encryption-JkeMPugf.mjs → encryption-DC0rsR1W.mjs} +3 -3
- package/dist/{encryption-JkeMPugf.mjs.map → encryption-DC0rsR1W.mjs.map} +1 -1
- package/dist/{encryption-w-Ehh9DW.cjs → encryption-vS3Qzw73.cjs} +3 -3
- package/dist/{encryption-w-Ehh9DW.cjs.map → encryption-vS3Qzw73.cjs.map} +1 -1
- package/dist/{engine-CmozkHxq.mjs → engine-BOO5TWZd.mjs} +4 -4
- package/dist/{engine-CmozkHxq.mjs.map → engine-BOO5TWZd.mjs.map} +1 -1
- package/dist/{engine-zpWBMsQq.cjs → engine-C0N2d1i5.cjs} +4 -4
- package/dist/{engine-zpWBMsQq.cjs.map → engine-C0N2d1i5.cjs.map} +1 -1
- package/dist/{github-BNngHoId.mjs → github-CEaFDL6t.mjs} +6 -6
- package/dist/github-CEaFDL6t.mjs.map +1 -0
- package/dist/{github-BGdJ-Lnm.cjs → github-ClkdCOL9.cjs} +6 -6
- package/dist/github-ClkdCOL9.cjs.map +1 -0
- package/dist/{index-vMidfqhU.d.cts → index-Ccu0f_2m.d.cts} +2 -2
- package/dist/{index-B-1lLGzy.d.mts.map → index-Ccu0f_2m.d.cts.map} +1 -1
- package/dist/{index-B-1lLGzy.d.mts → index-DOxmDKqv.d.mts} +2 -2
- package/dist/{index-vMidfqhU.d.cts.map → index-DOxmDKqv.d.mts.map} +1 -1
- package/dist/index.cjs +79 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +79 -50
- package/dist/index.mjs.map +1 -1
- package/dist/migrate-BRbYtFXG.cjs +93 -0
- package/dist/migrate-BRbYtFXG.cjs.map +1 -0
- package/dist/migrate-D3NAT7Ns.mjs +93 -0
- package/dist/migrate-D3NAT7Ns.mjs.map +1 -0
- package/dist/{migrate-CgjlYeun.cjs → migrate-D5_-ylI1.cjs} +3 -3
- package/dist/{migrate-CgjlYeun.cjs.map → migrate-D5_-ylI1.cjs.map} +1 -1
- package/dist/{migrate-BLL1RTAj.mjs → migrate-DrO2p9Rl.mjs} +3 -3
- package/dist/{migrate-BLL1RTAj.mjs.map → migrate-DrO2p9Rl.mjs.map} +1 -1
- package/dist/openapi.cjs +16 -6
- package/dist/openapi.cjs.map +1 -1
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +16 -6
- package/dist/openapi.mjs.map +1 -1
- package/dist/reconcile/public.d.cts +1 -1
- package/dist/reconcile/public.d.mts +1 -1
- package/dist/{resolve-DZNx7rLy.mjs → resolve-C1muFos5.mjs} +3 -3
- package/dist/{resolve-DZNx7rLy.mjs.map → resolve-C1muFos5.mjs.map} +1 -1
- package/dist/{resolve-fevXn-wZ.cjs → resolve-Fa1Ii0BK.cjs} +3 -3
- package/dist/{resolve-fevXn-wZ.cjs.map → resolve-Fa1Ii0BK.cjs.map} +1 -1
- package/dist/{rollback-Dw-FW3X2.cjs → rollback-C9N5lKVf.cjs} +5 -5
- package/dist/{rollback-Dw-FW3X2.cjs.map → rollback-C9N5lKVf.cjs.map} +1 -1
- package/dist/{rollback-CLi5Pln_.mjs → rollback-DeQzbRqM.mjs} +5 -5
- package/dist/{rollback-CLi5Pln_.mjs.map → rollback-DeQzbRqM.mjs.map} +1 -1
- package/dist/{runtime-BzZD5HHi.d.cts → runtime-BSvzPqXW.d.mts} +2 -2
- package/dist/{runtime-BzZD5HHi.d.cts.map → runtime-BSvzPqXW.d.mts.map} +1 -1
- package/dist/{runtime-Cm6J6L7n.d.mts → runtime-Cm7QA53H.d.cts} +2 -2
- package/dist/{runtime-Cm6J6L7n.d.mts.map → runtime-Cm7QA53H.d.cts.map} +1 -1
- package/dist/secretsManager-DUXW3fQt.cjs +70 -0
- package/dist/secretsManager-DUXW3fQt.cjs.map +1 -0
- package/dist/secretsManager-Ti0oZwsS.mjs +70 -0
- package/dist/secretsManager-Ti0oZwsS.mjs.map +1 -0
- package/dist/{sniffer-BmCvVyhq.mjs → sniffer-DR8AlRCk.mjs} +17 -17
- package/dist/sniffer-DR8AlRCk.mjs.map +1 -0
- package/dist/{sniffer-bMzrX4cO.cjs → sniffer-Y6GQOCXB.cjs} +17 -17
- package/dist/sniffer-Y6GQOCXB.cjs.map +1 -0
- package/dist/{state-kA4Fkufx.cjs → state-C2qi0iQw.cjs} +187 -24
- package/dist/state-C2qi0iQw.cjs.map +1 -0
- package/dist/{state-BrWIOce_.mjs → state-CUecOCNJ.mjs} +170 -25
- package/dist/state-CUecOCNJ.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-TzCChNrA.d.cts → types-BdptGBFS.d.cts} +59 -6
- package/dist/types-BdptGBFS.d.cts.map +1 -0
- package/dist/{types-Dp9lgx_S.d.mts → types-OxE0OAn2.d.mts} +59 -6
- package/dist/types-OxE0OAn2.d.mts.map +1 -0
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-vdrcRI-m.cjs → workspace-DOm81oUo.cjs} +54 -1
- package/dist/workspace-DOm81oUo.cjs.map +1 -0
- package/dist/{workspace-C7NqCsQF.mjs → workspace-QUTqYmVy.mjs} +43 -2
- package/dist/workspace-QUTqYmVy.mjs.map +1 -0
- package/package.json +16 -15
- package/dist/aws-DkHdTV-p.cjs.map +0 -1
- package/dist/aws-DojzQnLd.mjs.map +0 -1
- package/dist/bundler-_8AEZhrs.cjs.map +0 -1
- package/dist/bundler-xjp5RwRS.mjs.map +0 -1
- package/dist/compose-DdH2JQJD.mjs.map +0 -1
- package/dist/compose-UKyv_1yU.cjs.map +0 -1
- package/dist/github-BGdJ-Lnm.cjs.map +0 -1
- package/dist/github-BNngHoId.mjs.map +0 -1
- package/dist/sniffer-BmCvVyhq.mjs.map +0 -1
- package/dist/sniffer-bMzrX4cO.cjs.map +0 -1
- package/dist/state-BrWIOce_.mjs.map +0 -1
- package/dist/state-kA4Fkufx.cjs.map +0 -1
- package/dist/types-Dp9lgx_S.d.mts.map +0 -1
- package/dist/types-TzCChNrA.d.cts.map +0 -1
- package/dist/workspace-C7NqCsQF.mjs.map +0 -1
- package/dist/workspace-vdrcRI-m.cjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { k as assertDeployedStage } from "./workspace-
|
|
1
|
+
import { k as assertDeployedStage } from "./workspace-QUTqYmVy.mjs";
|
|
2
2
|
import { loadWorkspaceConfig } from "./config.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { Gt as secretsStoreFor, Qt as readKey, Wt as isRemoteStore, Xt as keystoreProject, Yt as getKeyPath } from "./state-CUecOCNJ.mjs";
|
|
4
4
|
import { execFileSync } from "node:child_process";
|
|
5
5
|
import { AttachRolePolicyCommand, CreateOpenIDConnectProviderCommand, CreateRoleCommand, GetRoleCommand, IAMClient, ListOpenIDConnectProvidersCommand, UpdateAssumeRolePolicyCommand } from "@aws-sdk/client-iam";
|
|
6
6
|
//#region src/deploy/github.ts
|
|
@@ -18,9 +18,9 @@ import { AttachRolePolicyCommand, CreateOpenIDConnectProviderCommand, CreateRole
|
|
|
18
18
|
* GitHub it creates that environment and gives it what the generated deploy
|
|
19
19
|
* workflow reads: `AWS_ROLE_ARN`, and — when the stage's secrets are kept in
|
|
20
20
|
* the local file — its key as `GKM_SECRETS_KEY`. With `secrets.store` set to
|
|
21
|
-
* SSM the deploy job
|
|
22
|
-
* GitHub, and this
|
|
23
|
-
* with the same profile. Re-running it converges rather than duplicating.
|
|
21
|
+
* SSM or Secrets Manager the deploy job reads them with the role instead, so
|
|
22
|
+
* no key is handed to GitHub, and this checks the stage's store in the same
|
|
23
|
+
* account, with the same profile. Re-running it converges rather than duplicating.
|
|
24
24
|
*/
|
|
25
25
|
const logger = console;
|
|
26
26
|
const GITHUB_OIDC_HOST = "token.actions.githubusercontent.com";
|
|
@@ -210,4 +210,4 @@ var SsoSessionExpired = class extends Error {
|
|
|
210
210
|
//#endregion
|
|
211
211
|
export { deployGithubCommand };
|
|
212
212
|
|
|
213
|
-
//# sourceMappingURL=github-
|
|
213
|
+
//# sourceMappingURL=github-CEaFDL6t.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-CEaFDL6t.mjs","names":[],"sources":["../src/deploy/github.ts"],"sourcesContent":["/**\n * `gkm deploy:github` — let GitHub Actions deploy one stage, with no keys.\n *\n * A stage usually lives in its own AWS account — staging in one, production in\n * another — so this runs once per stage, with that account's profile:\n *\n * gkm deploy:github --stage staging --profile acme-dev\n * gkm deploy:github --stage prod --profile acme-prod\n *\n * In the stage's account it makes sure GitHub's OIDC provider exists, and a\n * role that only this repository's `<stage>` environment can assume. On\n * GitHub it creates that environment and gives it what the generated deploy\n * workflow reads: `AWS_ROLE_ARN`, and — when the stage's secrets are kept in\n * the local file — its key as `GKM_SECRETS_KEY`. With `secrets.store` set to\n * SSM or Secrets Manager the deploy job reads them with the role instead, so\n * no key is handed to GitHub, and this checks the stage's store in the same\n * account, with the same profile. Re-running it converges rather than duplicating.\n */\n\nimport { execFileSync } from 'node:child_process';\nimport {\n\tAttachRolePolicyCommand,\n\tCreateOpenIDConnectProviderCommand,\n\tCreateRoleCommand,\n\tGetRoleCommand,\n\tIAMClient,\n\ttype IAMClientConfig,\n\tListOpenIDConnectProvidersCommand,\n\tUpdateAssumeRolePolicyCommand,\n} from '@aws-sdk/client-iam';\nimport { loadWorkspaceConfig } from '../config.js';\nimport { getKeyPath, keystoreProject, readKey } from '../secrets/keystore.js';\nimport { isRemoteStore, secretsStoreFor } from '../secrets/store.js';\nimport { assertDeployedStage } from '../workspace/stages.js';\n\nconst logger = console;\n\nconst GITHUB_OIDC_HOST = 'token.actions.githubusercontent.com';\nconst AUDIENCE = 'sts.amazonaws.com';\n\n/**\n * What SST needs to create a stack is most of AWS, so this is the default —\n * said out loud in the output, and replaceable with `--policy-arn`.\n */\nexport const DEFAULT_POLICY_ARN = 'arn:aws:iam::aws:policy/AdministratorAccess';\n\nexport interface DeployGithubOptions {\n\tstage: string;\n\t/** The AWS profile for the stage's account. */\n\tprofile?: string;\n\t/** `owner/name`; defaults to the repository `gh` sees here. */\n\trepo?: string;\n\t/** The policy the deploy role gets. */\n\tpolicyArn?: string;\n\tdryRun?: boolean;\n}\n\n/** Runs `gh` with the given arguments and optional stdin, returning stdout. */\nexport type Gh = (args: string[], input?: string) => string;\n\nconst defaultGh: Gh = (args, input) =>\n\texecFileSync('gh', args, {\n\t\tencoding: 'utf-8',\n\t\t...(input === undefined\n\t\t\t? {}\n\t\t\t: { input, stdio: ['pipe', 'pipe', 'pipe'] as const }),\n\t}).trim();\n\n/** The role a stage deploys as: `<project>-github-<stage>`, within IAM's 64. */\nexport function roleName(project: string, stage: string): string {\n\treturn `${project}-github-${stage}`\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9+=,.@_-]/g, '-')\n\t\t.slice(0, 64);\n}\n\n/**\n * Who may assume the role: a workflow job running in this repository's\n * `<stage>` environment, and nothing else — not another branch's job, not\n * another environment's. That is what keeps a staging deploy from using the\n * production role.\n */\nexport function trustPolicy(\n\tproviderArn: string,\n\trepo: string,\n\tstage: string,\n): string {\n\treturn JSON.stringify({\n\t\tVersion: '2012-10-17',\n\t\tStatement: [\n\t\t\t{\n\t\t\t\tEffect: 'Allow',\n\t\t\t\tPrincipal: { Federated: providerArn },\n\t\t\t\tAction: 'sts:AssumeRoleWithWebIdentity',\n\t\t\t\tCondition: {\n\t\t\t\t\tStringEquals: {\n\t\t\t\t\t\t[`${GITHUB_OIDC_HOST}:aud`]: AUDIENCE,\n\t\t\t\t\t\t[`${GITHUB_OIDC_HOST}:sub`]: `repo:${repo}:environment:${stage}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t});\n}\n\n/** GitHub's OIDC provider in this account, created if it is not there. */\nexport async function ensureOidcProvider(iam: IAMClient): Promise<string> {\n\tconst { OpenIDConnectProviderList = [] } = await iam.send(\n\t\tnew ListOpenIDConnectProvidersCommand({}),\n\t);\n\tconst existing = OpenIDConnectProviderList.find((p) =>\n\t\tp.Arn?.endsWith(`oidc-provider/${GITHUB_OIDC_HOST}`),\n\t)?.Arn;\n\tif (existing) return existing;\n\n\tconst created = await iam.send(\n\t\tnew CreateOpenIDConnectProviderCommand({\n\t\t\tUrl: `https://${GITHUB_OIDC_HOST}`,\n\t\t\tClientIDList: [AUDIENCE],\n\t\t}),\n\t);\n\treturn created.OpenIDConnectProviderArn!;\n}\n\n/** The deploy role, created or brought back to this trust and policy. */\nexport async function ensureRole(\n\tiam: IAMClient,\n\tname: string,\n\ttrust: string,\n\tpolicyArn: string,\n): Promise<string> {\n\tlet arn: string;\n\ttry {\n\t\tconst { Role } = await iam.send(new GetRoleCommand({ RoleName: name }));\n\t\tawait iam.send(\n\t\t\tnew UpdateAssumeRolePolicyCommand({\n\t\t\t\tRoleName: name,\n\t\t\t\tPolicyDocument: trust,\n\t\t\t}),\n\t\t);\n\t\tarn = Role!.Arn!;\n\t} catch (error) {\n\t\tif ((error as { name?: string }).name !== 'NoSuchEntityException') {\n\t\t\tthrow error;\n\t\t}\n\t\tconst { Role } = await iam.send(\n\t\t\tnew CreateRoleCommand({\n\t\t\t\tRoleName: name,\n\t\t\t\tAssumeRolePolicyDocument: trust,\n\t\t\t\tDescription: 'Deploys from GitHub Actions (gkm deploy:github)',\n\t\t\t\t// SST deploys can run long; the default hour is tight.\n\t\t\t\tMaxSessionDuration: 3600 * 2,\n\t\t\t}),\n\t\t);\n\t\tarn = Role!.Arn!;\n\t}\n\n\t// Attaching an attached policy is a no-op, so this converges too.\n\tawait iam.send(\n\t\tnew AttachRolePolicyCommand({ RoleName: name, PolicyArn: policyArn }),\n\t);\n\treturn arn;\n}\n\n/**\n * An IAM client for the stage's account.\n *\n * `fromIni` for a named profile, deliberately: it resolves exactly that\n * profile — keys, assume-role, `credential_process` or SSO, whichever\n * ~/.aws/config says — and never falls back to AWS_* in the environment. The\n * provider chain checks the environment first, so exported staging keys would\n * quietly win over `--profile prod` and the production role would land in the\n * staging account.\n */\nexport async function iamFor(\n\tprofile?: string,\n\tendpoint?: string,\n): Promise<IAMClient> {\n\tconst config: IAMClientConfig = { region: 'us-east-1' };\n\tif (profile) {\n\t\tconst { fromIni } = await import('@aws-sdk/credential-providers');\n\t\tconfig.credentials = fromIni({ profile });\n\t}\n\tif (endpoint) {\n\t\tconfig.endpoint = endpoint;\n\t\tconfig.credentials = { accessKeyId: 'test', secretAccessKey: 'test' };\n\t}\n\treturn new IAMClient(config);\n}\n\nexport async function deployGithubCommand(\n\toptions: DeployGithubOptions,\n\tdeps: { iam?: IAMClient; gh?: Gh; cwd?: string } = {},\n): Promise<{ roleArn?: string; repo: string }> {\n\tconst gh = deps.gh ?? defaultGh;\n\tconst { workspace } = await loadWorkspaceConfig(deps.cwd);\n\tassertDeployedStage(workspace.stages, options.stage);\n\n\tconst repo =\n\t\toptions.repo ??\n\t\tgh(['repo', 'view', '--json', 'nameWithOwner', '-q', '.nameWithOwner']);\n\tconst role = roleName(workspace.name, options.stage);\n\tconst policyArn = options.policyArn ?? DEFAULT_POLICY_ARN;\n\t// Read through the keystore so a key still at the place keys used to be kept\n\t// is found, and copied to where it is kept now.\n\tconst key = await readKey(options.stage, keystoreProject(workspace));\n\tconst keyPath = getKeyPath(options.stage, keystoreProject(workspace));\n\tconst hasKey = key !== null;\n\t// A stage whose secrets are in a store is read from there by the deploy job,\n\t// with the role; it needs no key on GitHub.\n\tconst remote = isRemoteStore(workspace, options.stage);\n\t// Read from the stage's own store, with the same credentials the role is\n\t// created with: what the deploy job will find there.\n\tconst store = await secretsStoreFor(workspace, options.stage, {\n\t\t...(options.profile ? { profile: options.profile } : {}),\n\t});\n\tconst hasSecrets = remote && (await store.read(options.stage)) !== null;\n\tconst via = options.profile\n\t\t? `profile \"${options.profile}\"`\n\t\t: 'the default credentials';\n\n\tlogger.log(`\\n🔐 GitHub → AWS for stage \"${options.stage}\"\\n`);\n\tlogger.log(` Repository: ${repo}`);\n\tlogger.log(` AWS profile: ${options.profile ?? '(default credentials)'}`);\n\tlogger.log(` Role: ${role}`);\n\tlogger.log(\n\t\t` Policy: ${policyArn}${options.policyArn ? '' : ' (default; --policy-arn to narrow)'}`,\n\t);\n\tlogger.log(` Trusted by: repo:${repo}:environment:${options.stage} only`);\n\tif (remote) {\n\t\tlogger.log(\n\t\t\t` Secrets: ${hasSecrets ? `in the store (${store.name}), read with ${via}` : `none in the store yet — gkm secrets:set <KEY> '…' --stage ${options.stage}`}`,\n\t\t);\n\t} else {\n\t\tlogger.log(\n\t\t\t` Secrets key: ${hasKey ? keyPath : `none at ${keyPath} — run gkm secrets:init --stage ${options.stage} first`}`,\n\t\t);\n\t}\n\n\tif (options.dryRun) {\n\t\tlogger.log('\\n --dry-run: nothing changed.\\n');\n\t\treturn { repo };\n\t}\n\n\tconst iam = deps.iam ?? (await iamFor(options.profile));\n\tconst providerArn = await ensureOidcProvider(iam).catch((error) => {\n\t\t// The first AWS call is where an expired SSO login surfaces; the SDK's\n\t\t// message does not say which profile, and this command knows.\n\t\tif (/SSO session/i.test(String(error?.message)) && options.profile) {\n\t\t\tthrow new SsoSessionExpired(options.profile);\n\t\t}\n\t\tthrow error;\n\t});\n\tconst roleArn = await ensureRole(\n\t\tiam,\n\t\trole,\n\t\ttrustPolicy(providerArn, repo, options.stage),\n\t\tpolicyArn,\n\t);\n\tlogger.log(`\\n ✓ AWS: ${roleArn}`);\n\n\t// The environment the generated deploy workflow runs the stage in.\n\tgh(['api', '--method', 'PUT', `repos/${repo}/environments/${options.stage}`]);\n\tgh([\n\t\t'variable',\n\t\t'set',\n\t\t'AWS_ROLE_ARN',\n\t\t'--env',\n\t\toptions.stage,\n\t\t'--repo',\n\t\trepo,\n\t\t'--body',\n\t\troleArn,\n\t]);\n\tlogger.log(` ✓ GitHub: environment \"${options.stage}\", AWS_ROLE_ARN`);\n\n\tif (remote) {\n\t\t// Nothing to send: the deploy job reads the stage's store itself.\n\t\tif (!hasSecrets) {\n\t\t\tlogger.log(\n\t\t\t\t` ⚠ The \"${options.stage}\" store holds no secrets yet; set them with gkm secrets:set <KEY> '…' --stage ${options.stage}${options.profile ? ` (AWS_PROFILE=${options.profile})` : ''}.`,\n\t\t\t);\n\t\t}\n\t} else if (hasKey) {\n\t\t// Through stdin, so the key is never an argument a process list shows.\n\t\tgh(\n\t\t\t[\n\t\t\t\t'secret',\n\t\t\t\t'set',\n\t\t\t\t'GKM_SECRETS_KEY',\n\t\t\t\t'--env',\n\t\t\t\toptions.stage,\n\t\t\t\t'--repo',\n\t\t\t\trepo,\n\t\t\t],\n\t\t\tkey!,\n\t\t);\n\t\tlogger.log(' ✓ GitHub: GKM_SECRETS_KEY');\n\t} else {\n\t\tlogger.log(\n\t\t\t` ⚠ No secrets key for \"${options.stage}\"; run gkm secrets:init --stage ${options.stage}, then this again.`,\n\t\t);\n\t}\n\n\tlogger.log(\n\t\t`\\n Protect it: add required reviewers to the \"${options.stage}\" environment in the repository settings.\\n`,\n\t);\n\treturn { roleArn, repo };\n}\n\n/** The profile's SSO login has lapsed; the fix is one command away. */\nexport class SsoSessionExpired extends Error {\n\tconstructor(readonly profile: string) {\n\t\tsuper(\n\t\t\t`The SSO session for profile \"${profile}\" has expired or is invalid. Run: aws sso login --profile ${profile}`,\n\t\t);\n\t\tthis.name = 'SsoSessionExpired';\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const require_workspace = require("./workspace-
|
|
1
|
+
const require_workspace = require("./workspace-DOm81oUo.cjs");
|
|
2
2
|
const require_config = require("./config.cjs");
|
|
3
|
-
const require_state = require("./state-
|
|
3
|
+
const require_state = require("./state-C2qi0iQw.cjs");
|
|
4
4
|
let node_child_process = require("node:child_process");
|
|
5
5
|
let _aws_sdk_client_iam = require("@aws-sdk/client-iam");
|
|
6
6
|
//#region src/deploy/github.ts
|
|
@@ -18,9 +18,9 @@ let _aws_sdk_client_iam = require("@aws-sdk/client-iam");
|
|
|
18
18
|
* GitHub it creates that environment and gives it what the generated deploy
|
|
19
19
|
* workflow reads: `AWS_ROLE_ARN`, and — when the stage's secrets are kept in
|
|
20
20
|
* the local file — its key as `GKM_SECRETS_KEY`. With `secrets.store` set to
|
|
21
|
-
* SSM the deploy job
|
|
22
|
-
* GitHub, and this
|
|
23
|
-
* with the same profile. Re-running it converges rather than duplicating.
|
|
21
|
+
* SSM or Secrets Manager the deploy job reads them with the role instead, so
|
|
22
|
+
* no key is handed to GitHub, and this checks the stage's store in the same
|
|
23
|
+
* account, with the same profile. Re-running it converges rather than duplicating.
|
|
24
24
|
*/
|
|
25
25
|
const logger = console;
|
|
26
26
|
const GITHUB_OIDC_HOST = "token.actions.githubusercontent.com";
|
|
@@ -210,4 +210,4 @@ var SsoSessionExpired = class extends Error {
|
|
|
210
210
|
//#endregion
|
|
211
211
|
exports.deployGithubCommand = deployGithubCommand;
|
|
212
212
|
|
|
213
|
-
//# sourceMappingURL=github-
|
|
213
|
+
//# sourceMappingURL=github-ClkdCOL9.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-ClkdCOL9.cjs","names":["execFileSync","ListOpenIDConnectProvidersCommand","CreateOpenIDConnectProviderCommand","GetRoleCommand","UpdateAssumeRolePolicyCommand","CreateRoleCommand","AttachRolePolicyCommand","IAMClient","loadWorkspaceConfig","readKey","keystoreProject","getKeyPath","isRemoteStore","secretsStoreFor"],"sources":["../src/deploy/github.ts"],"sourcesContent":["/**\n * `gkm deploy:github` — let GitHub Actions deploy one stage, with no keys.\n *\n * A stage usually lives in its own AWS account — staging in one, production in\n * another — so this runs once per stage, with that account's profile:\n *\n * gkm deploy:github --stage staging --profile acme-dev\n * gkm deploy:github --stage prod --profile acme-prod\n *\n * In the stage's account it makes sure GitHub's OIDC provider exists, and a\n * role that only this repository's `<stage>` environment can assume. On\n * GitHub it creates that environment and gives it what the generated deploy\n * workflow reads: `AWS_ROLE_ARN`, and — when the stage's secrets are kept in\n * the local file — its key as `GKM_SECRETS_KEY`. With `secrets.store` set to\n * SSM or Secrets Manager the deploy job reads them with the role instead, so\n * no key is handed to GitHub, and this checks the stage's store in the same\n * account, with the same profile. Re-running it converges rather than duplicating.\n */\n\nimport { execFileSync } from 'node:child_process';\nimport {\n\tAttachRolePolicyCommand,\n\tCreateOpenIDConnectProviderCommand,\n\tCreateRoleCommand,\n\tGetRoleCommand,\n\tIAMClient,\n\ttype IAMClientConfig,\n\tListOpenIDConnectProvidersCommand,\n\tUpdateAssumeRolePolicyCommand,\n} from '@aws-sdk/client-iam';\nimport { loadWorkspaceConfig } from '../config.js';\nimport { getKeyPath, keystoreProject, readKey } from '../secrets/keystore.js';\nimport { isRemoteStore, secretsStoreFor } from '../secrets/store.js';\nimport { assertDeployedStage } from '../workspace/stages.js';\n\nconst logger = console;\n\nconst GITHUB_OIDC_HOST = 'token.actions.githubusercontent.com';\nconst AUDIENCE = 'sts.amazonaws.com';\n\n/**\n * What SST needs to create a stack is most of AWS, so this is the default —\n * said out loud in the output, and replaceable with `--policy-arn`.\n */\nexport const DEFAULT_POLICY_ARN = 'arn:aws:iam::aws:policy/AdministratorAccess';\n\nexport interface DeployGithubOptions {\n\tstage: string;\n\t/** The AWS profile for the stage's account. */\n\tprofile?: string;\n\t/** `owner/name`; defaults to the repository `gh` sees here. */\n\trepo?: string;\n\t/** The policy the deploy role gets. */\n\tpolicyArn?: string;\n\tdryRun?: boolean;\n}\n\n/** Runs `gh` with the given arguments and optional stdin, returning stdout. */\nexport type Gh = (args: string[], input?: string) => string;\n\nconst defaultGh: Gh = (args, input) =>\n\texecFileSync('gh', args, {\n\t\tencoding: 'utf-8',\n\t\t...(input === undefined\n\t\t\t? {}\n\t\t\t: { input, stdio: ['pipe', 'pipe', 'pipe'] as const }),\n\t}).trim();\n\n/** The role a stage deploys as: `<project>-github-<stage>`, within IAM's 64. */\nexport function roleName(project: string, stage: string): string {\n\treturn `${project}-github-${stage}`\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9+=,.@_-]/g, '-')\n\t\t.slice(0, 64);\n}\n\n/**\n * Who may assume the role: a workflow job running in this repository's\n * `<stage>` environment, and nothing else — not another branch's job, not\n * another environment's. That is what keeps a staging deploy from using the\n * production role.\n */\nexport function trustPolicy(\n\tproviderArn: string,\n\trepo: string,\n\tstage: string,\n): string {\n\treturn JSON.stringify({\n\t\tVersion: '2012-10-17',\n\t\tStatement: [\n\t\t\t{\n\t\t\t\tEffect: 'Allow',\n\t\t\t\tPrincipal: { Federated: providerArn },\n\t\t\t\tAction: 'sts:AssumeRoleWithWebIdentity',\n\t\t\t\tCondition: {\n\t\t\t\t\tStringEquals: {\n\t\t\t\t\t\t[`${GITHUB_OIDC_HOST}:aud`]: AUDIENCE,\n\t\t\t\t\t\t[`${GITHUB_OIDC_HOST}:sub`]: `repo:${repo}:environment:${stage}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t});\n}\n\n/** GitHub's OIDC provider in this account, created if it is not there. */\nexport async function ensureOidcProvider(iam: IAMClient): Promise<string> {\n\tconst { OpenIDConnectProviderList = [] } = await iam.send(\n\t\tnew ListOpenIDConnectProvidersCommand({}),\n\t);\n\tconst existing = OpenIDConnectProviderList.find((p) =>\n\t\tp.Arn?.endsWith(`oidc-provider/${GITHUB_OIDC_HOST}`),\n\t)?.Arn;\n\tif (existing) return existing;\n\n\tconst created = await iam.send(\n\t\tnew CreateOpenIDConnectProviderCommand({\n\t\t\tUrl: `https://${GITHUB_OIDC_HOST}`,\n\t\t\tClientIDList: [AUDIENCE],\n\t\t}),\n\t);\n\treturn created.OpenIDConnectProviderArn!;\n}\n\n/** The deploy role, created or brought back to this trust and policy. */\nexport async function ensureRole(\n\tiam: IAMClient,\n\tname: string,\n\ttrust: string,\n\tpolicyArn: string,\n): Promise<string> {\n\tlet arn: string;\n\ttry {\n\t\tconst { Role } = await iam.send(new GetRoleCommand({ RoleName: name }));\n\t\tawait iam.send(\n\t\t\tnew UpdateAssumeRolePolicyCommand({\n\t\t\t\tRoleName: name,\n\t\t\t\tPolicyDocument: trust,\n\t\t\t}),\n\t\t);\n\t\tarn = Role!.Arn!;\n\t} catch (error) {\n\t\tif ((error as { name?: string }).name !== 'NoSuchEntityException') {\n\t\t\tthrow error;\n\t\t}\n\t\tconst { Role } = await iam.send(\n\t\t\tnew CreateRoleCommand({\n\t\t\t\tRoleName: name,\n\t\t\t\tAssumeRolePolicyDocument: trust,\n\t\t\t\tDescription: 'Deploys from GitHub Actions (gkm deploy:github)',\n\t\t\t\t// SST deploys can run long; the default hour is tight.\n\t\t\t\tMaxSessionDuration: 3600 * 2,\n\t\t\t}),\n\t\t);\n\t\tarn = Role!.Arn!;\n\t}\n\n\t// Attaching an attached policy is a no-op, so this converges too.\n\tawait iam.send(\n\t\tnew AttachRolePolicyCommand({ RoleName: name, PolicyArn: policyArn }),\n\t);\n\treturn arn;\n}\n\n/**\n * An IAM client for the stage's account.\n *\n * `fromIni` for a named profile, deliberately: it resolves exactly that\n * profile — keys, assume-role, `credential_process` or SSO, whichever\n * ~/.aws/config says — and never falls back to AWS_* in the environment. The\n * provider chain checks the environment first, so exported staging keys would\n * quietly win over `--profile prod` and the production role would land in the\n * staging account.\n */\nexport async function iamFor(\n\tprofile?: string,\n\tendpoint?: string,\n): Promise<IAMClient> {\n\tconst config: IAMClientConfig = { region: 'us-east-1' };\n\tif (profile) {\n\t\tconst { fromIni } = await import('@aws-sdk/credential-providers');\n\t\tconfig.credentials = fromIni({ profile });\n\t}\n\tif (endpoint) {\n\t\tconfig.endpoint = endpoint;\n\t\tconfig.credentials = { accessKeyId: 'test', secretAccessKey: 'test' };\n\t}\n\treturn new IAMClient(config);\n}\n\nexport async function deployGithubCommand(\n\toptions: DeployGithubOptions,\n\tdeps: { iam?: IAMClient; gh?: Gh; cwd?: string } = {},\n): Promise<{ roleArn?: string; repo: string }> {\n\tconst gh = deps.gh ?? defaultGh;\n\tconst { workspace } = await loadWorkspaceConfig(deps.cwd);\n\tassertDeployedStage(workspace.stages, options.stage);\n\n\tconst repo =\n\t\toptions.repo ??\n\t\tgh(['repo', 'view', '--json', 'nameWithOwner', '-q', '.nameWithOwner']);\n\tconst role = roleName(workspace.name, options.stage);\n\tconst policyArn = options.policyArn ?? DEFAULT_POLICY_ARN;\n\t// Read through the keystore so a key still at the place keys used to be kept\n\t// is found, and copied to where it is kept now.\n\tconst key = await readKey(options.stage, keystoreProject(workspace));\n\tconst keyPath = getKeyPath(options.stage, keystoreProject(workspace));\n\tconst hasKey = key !== null;\n\t// A stage whose secrets are in a store is read from there by the deploy job,\n\t// with the role; it needs no key on GitHub.\n\tconst remote = isRemoteStore(workspace, options.stage);\n\t// Read from the stage's own store, with the same credentials the role is\n\t// created with: what the deploy job will find there.\n\tconst store = await secretsStoreFor(workspace, options.stage, {\n\t\t...(options.profile ? { profile: options.profile } : {}),\n\t});\n\tconst hasSecrets = remote && (await store.read(options.stage)) !== null;\n\tconst via = options.profile\n\t\t? `profile \"${options.profile}\"`\n\t\t: 'the default credentials';\n\n\tlogger.log(`\\n🔐 GitHub → AWS for stage \"${options.stage}\"\\n`);\n\tlogger.log(` Repository: ${repo}`);\n\tlogger.log(` AWS profile: ${options.profile ?? '(default credentials)'}`);\n\tlogger.log(` Role: ${role}`);\n\tlogger.log(\n\t\t` Policy: ${policyArn}${options.policyArn ? '' : ' (default; --policy-arn to narrow)'}`,\n\t);\n\tlogger.log(` Trusted by: repo:${repo}:environment:${options.stage} only`);\n\tif (remote) {\n\t\tlogger.log(\n\t\t\t` Secrets: ${hasSecrets ? `in the store (${store.name}), read with ${via}` : `none in the store yet — gkm secrets:set <KEY> '…' --stage ${options.stage}`}`,\n\t\t);\n\t} else {\n\t\tlogger.log(\n\t\t\t` Secrets key: ${hasKey ? keyPath : `none at ${keyPath} — run gkm secrets:init --stage ${options.stage} first`}`,\n\t\t);\n\t}\n\n\tif (options.dryRun) {\n\t\tlogger.log('\\n --dry-run: nothing changed.\\n');\n\t\treturn { repo };\n\t}\n\n\tconst iam = deps.iam ?? (await iamFor(options.profile));\n\tconst providerArn = await ensureOidcProvider(iam).catch((error) => {\n\t\t// The first AWS call is where an expired SSO login surfaces; the SDK's\n\t\t// message does not say which profile, and this command knows.\n\t\tif (/SSO session/i.test(String(error?.message)) && options.profile) {\n\t\t\tthrow new SsoSessionExpired(options.profile);\n\t\t}\n\t\tthrow error;\n\t});\n\tconst roleArn = await ensureRole(\n\t\tiam,\n\t\trole,\n\t\ttrustPolicy(providerArn, repo, options.stage),\n\t\tpolicyArn,\n\t);\n\tlogger.log(`\\n ✓ AWS: ${roleArn}`);\n\n\t// The environment the generated deploy workflow runs the stage in.\n\tgh(['api', '--method', 'PUT', `repos/${repo}/environments/${options.stage}`]);\n\tgh([\n\t\t'variable',\n\t\t'set',\n\t\t'AWS_ROLE_ARN',\n\t\t'--env',\n\t\toptions.stage,\n\t\t'--repo',\n\t\trepo,\n\t\t'--body',\n\t\troleArn,\n\t]);\n\tlogger.log(` ✓ GitHub: environment \"${options.stage}\", AWS_ROLE_ARN`);\n\n\tif (remote) {\n\t\t// Nothing to send: the deploy job reads the stage's store itself.\n\t\tif (!hasSecrets) {\n\t\t\tlogger.log(\n\t\t\t\t` ⚠ The \"${options.stage}\" store holds no secrets yet; set them with gkm secrets:set <KEY> '…' --stage ${options.stage}${options.profile ? ` (AWS_PROFILE=${options.profile})` : ''}.`,\n\t\t\t);\n\t\t}\n\t} else if (hasKey) {\n\t\t// Through stdin, so the key is never an argument a process list shows.\n\t\tgh(\n\t\t\t[\n\t\t\t\t'secret',\n\t\t\t\t'set',\n\t\t\t\t'GKM_SECRETS_KEY',\n\t\t\t\t'--env',\n\t\t\t\toptions.stage,\n\t\t\t\t'--repo',\n\t\t\t\trepo,\n\t\t\t],\n\t\t\tkey!,\n\t\t);\n\t\tlogger.log(' ✓ GitHub: GKM_SECRETS_KEY');\n\t} else {\n\t\tlogger.log(\n\t\t\t` ⚠ No secrets key for \"${options.stage}\"; run gkm secrets:init --stage ${options.stage}, then this again.`,\n\t\t);\n\t}\n\n\tlogger.log(\n\t\t`\\n Protect it: add required reviewers to the \"${options.stage}\" environment in the repository settings.\\n`,\n\t);\n\treturn { roleArn, repo };\n}\n\n/** The profile's SSO login has lapsed; the fix is one command away. */\nexport class SsoSessionExpired extends Error {\n\tconstructor(readonly profile: string) {\n\t\tsuper(\n\t\t\t`The SSO session for profile \"${profile}\" has expired or is invalid. Run: aws sso login --profile ${profile}`,\n\t\t);\n\t\tthis.name = 'SsoSessionExpired';\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as WorkspaceInput, S as NormalizedWorkspace, T as WorkspaceConfig, a as Routes, k as Framework, l as AppsRecord, r as GkmConfig, v as InferredWorkspaceConfig, y as LoadedConfig } from "./types-
|
|
1
|
+
import { E as WorkspaceInput, S as NormalizedWorkspace, T as WorkspaceConfig, a as Routes, k as Framework, l as AppsRecord, r as GkmConfig, v as InferredWorkspaceConfig, y as LoadedConfig } from "./types-BdptGBFS.cjs";
|
|
2
2
|
//#region src/workspace/publicEnv.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* All public env-var prefixes the toolbox understands.
|
|
@@ -166,4 +166,4 @@ declare function getEndpointForStage(dokployConfig: {
|
|
|
166
166
|
} | undefined, stage: string): string | undefined;
|
|
167
167
|
//#endregion
|
|
168
168
|
export { constructPatterns as a, getAppGkmConfig as c, processConfig as d, workspaceConstructGlobs as f, stripPublicPrefix as g, getPublicEnvPrefix as h, assertNoMovedDeployKeys as i, getEndpointForStage as l, PUBLIC_ENV_PREFIXES as m, allConstructGlobs as n, defineWorkspace as o, wrapSingleAppAsWorkspace as p, appConstructGlobs as r, getAppBuildOrder as s, DokployRegistryMoved as t, normalizeWorkspace as u };
|
|
169
|
-
//# sourceMappingURL=index-
|
|
169
|
+
//# sourceMappingURL=index-Ccu0f_2m.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-Ccu0f_2m.d.cts","names":[],"sources":["../src/workspace/publicEnv.ts","../src/workspace/index.ts"],"mappings":";;;;;;;;;cASa;;;;;;;;;;;;;;;iBAoBG,mBAAmB,YAAY;;;;;iBAoB/B,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBC8ElB,sBAAsB,cAAc,YACnD,QAAQ,eAAe,SACrB,wBAAwB;;;;iBAiCX,mBACf,QAAQ,iBACR,cACE;;;;;iBAgDa,yBACf,QAAQ,WACR,cACE;;;;;;;;;;;;cA8DU,6BAA6B;WACpB;EAArB,YAAqB;;;iBAUN,wBAAwB;iBAOxB,cACf,QAAQ,YAAY,iBACpB,cACE;;;;;;;iBAgCa,wBACf,WAAW;;;;;;;;;;;;iBAkBI,kBACf,WAAW,qBACX;;;;;;;iBAsBe,kBAAkB,WAAW;;iBAa7B,kBAAkB,QAAQ;;;;;iBAS1B,gBACf,WAAW,qBACX,kBACE;;;;;iBAgCa,iBAAiB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoD5B,oBACf;EACK;EAAmB,YAAY;eAEpC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as WorkspaceInput, S as NormalizedWorkspace, T as WorkspaceConfig, a as Routes, k as Framework, l as AppsRecord, r as GkmConfig, v as InferredWorkspaceConfig, y as LoadedConfig } from "./types-
|
|
1
|
+
import { E as WorkspaceInput, S as NormalizedWorkspace, T as WorkspaceConfig, a as Routes, k as Framework, l as AppsRecord, r as GkmConfig, v as InferredWorkspaceConfig, y as LoadedConfig } from "./types-OxE0OAn2.mjs";
|
|
2
2
|
//#region src/workspace/publicEnv.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* All public env-var prefixes the toolbox understands.
|
|
@@ -166,4 +166,4 @@ declare function getEndpointForStage(dokployConfig: {
|
|
|
166
166
|
} | undefined, stage: string): string | undefined;
|
|
167
167
|
//#endregion
|
|
168
168
|
export { constructPatterns as a, getAppGkmConfig as c, processConfig as d, workspaceConstructGlobs as f, stripPublicPrefix as g, getPublicEnvPrefix as h, assertNoMovedDeployKeys as i, getEndpointForStage as l, PUBLIC_ENV_PREFIXES as m, allConstructGlobs as n, defineWorkspace as o, wrapSingleAppAsWorkspace as p, appConstructGlobs as r, getAppBuildOrder as s, DokployRegistryMoved as t, normalizeWorkspace as u };
|
|
169
|
-
//# sourceMappingURL=index-
|
|
169
|
+
//# sourceMappingURL=index-DOxmDKqv.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-DOxmDKqv.d.mts","names":[],"sources":["../src/workspace/publicEnv.ts","../src/workspace/index.ts"],"mappings":";;;;;;;;;cASa;;;;;;;;;;;;;;;iBAoBG,mBAAmB,YAAY;;;;;iBAoB/B,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBC8ElB,sBAAsB,cAAc,YACnD,QAAQ,eAAe,SACrB,wBAAwB;;;;iBAiCX,mBACf,QAAQ,iBACR,cACE;;;;;iBAgDa,yBACf,QAAQ,WACR,cACE;;;;;;;;;;;;cA8DU,6BAA6B;WACpB;EAArB,YAAqB;;;iBAUN,wBAAwB;iBAOxB,cACf,QAAQ,YAAY,iBACpB,cACE;;;;;;;iBAgCa,wBACf,WAAW;;;;;;;;;;;;iBAkBI,kBACf,WAAW,qBACX;;;;;;;iBAsBe,kBAAkB,WAAW;;iBAa7B,kBAAkB,QAAQ;;;;;iBAS1B,gBACf,WAAW,qBACX,kBACE;;;;;iBAgCa,iBAAiB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoD5B,oBACf;EACK;EAAmB,YAAY;eAEpC"}
|
package/dist/index.cjs
CHANGED
|
@@ -5,20 +5,20 @@ 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-DOm81oUo.cjs");
|
|
9
9
|
const require_config = require("./config.cjs");
|
|
10
|
-
const require_state = require("./state-
|
|
10
|
+
const require_state = require("./state-C2qi0iQw.cjs");
|
|
11
11
|
const require_EndpointGenerator = require("./EndpointGenerator-CP6sBvQV.cjs");
|
|
12
|
-
const require_sniffer = require("./sniffer-bMzrX4cO.cjs");
|
|
13
12
|
const require_openapi = require("./openapi.cjs");
|
|
14
13
|
const require_SubscriberGenerator = require("./SubscriberGenerator-CajwOa5W.cjs");
|
|
15
14
|
const require_appPorts = require("./appPorts-Cu79hJF6.cjs");
|
|
16
15
|
const require_drivers = require("./drivers-BdvtCKc7.cjs");
|
|
17
16
|
const require_emit = require("./emit-Dmc1nvdS.cjs");
|
|
18
|
-
const
|
|
19
|
-
const
|
|
17
|
+
const require_sniffer = require("./sniffer-Y6GQOCXB.cjs");
|
|
18
|
+
const require_deploy = require("./deploy-CT3R9de9.cjs");
|
|
19
|
+
const require_compose = require("./compose-h_6oNnHC.cjs");
|
|
20
20
|
const require_credentialSchemas = require("./credentialSchemas-DCR4Wd1W.cjs");
|
|
21
|
-
const require_LocalStateStore = require("./LocalStateStore-
|
|
21
|
+
const require_LocalStateStore = require("./LocalStateStore-B0NCde8Z.cjs");
|
|
22
22
|
const require_utils = require("./utils-D2Nk1Nv2.cjs");
|
|
23
23
|
const require_ready = require("./ready-BB9xS4S9.cjs");
|
|
24
24
|
let node_path = require("node:path");
|
|
@@ -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.76";
|
|
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-Y6GQOCXB.cjs")).then((n) => n.dokploy_api_exports);
|
|
140
140
|
return new DokployApi({
|
|
141
141
|
baseUrl: endpoint,
|
|
142
142
|
token
|
|
@@ -1533,10 +1533,10 @@ async function execCommand(commandArgs, options = {}) {
|
|
|
1533
1533
|
if (!commandArgs[0]) throw new NoCommandSpecified();
|
|
1534
1534
|
const defaultEnv = require_state.loadEnvFiles(".env");
|
|
1535
1535
|
if (defaultEnv.loaded.length > 0) logger$6.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
|
|
1536
|
-
const { credentials, secretsJsonPath, appName } = await require_state.prepareEntryCredentials({ cwd });
|
|
1536
|
+
const { credentials, secretsJsonPath, appName } = require_state.isImageBuild() ? await imageBuildEntry(cwd) : await require_state.prepareEntryCredentials({ cwd });
|
|
1537
1537
|
if (appName) logger$6.log(`📦 App: ${appName}`);
|
|
1538
1538
|
const secretCount = Object.keys(credentials).filter((k) => k !== "PORT").length;
|
|
1539
|
-
if (secretCount > 0) logger$6.log(`🔐 Loaded ${secretCount} secret(s)`);
|
|
1539
|
+
if (secretCount > 0 && !require_state.isImageBuild()) logger$6.log(`🔐 Loaded ${secretCount} secret(s)`);
|
|
1540
1540
|
const preloadDir = (0, node_path.join)(cwd, ".gkm");
|
|
1541
1541
|
await (0, node_fs_promises.mkdir)(preloadDir, { recursive: true });
|
|
1542
1542
|
const preloadPath = (0, node_path.join)(preloadDir, "credentials-preload.mjs");
|
|
@@ -1562,6 +1562,23 @@ async function execCommand(commandArgs, options = {}) {
|
|
|
1562
1562
|
});
|
|
1563
1563
|
if (exitCode !== 0) process.exit(exitCode);
|
|
1564
1564
|
}
|
|
1565
|
+
/**
|
|
1566
|
+
* `gkm exec` inside an image build: the public values the Dockerfile's build
|
|
1567
|
+
* args set, written where the preload reads them. No workspace is loaded, no
|
|
1568
|
+
* secret read and no address resolved.
|
|
1569
|
+
*/
|
|
1570
|
+
async function imageBuildEntry(cwd) {
|
|
1571
|
+
const credentials = require_state.imageBuildCredentials();
|
|
1572
|
+
logger$6.log(`🐳 Image build: ${Object.keys(credentials).length} public value(s) from the build args`);
|
|
1573
|
+
const dir = (0, node_path.join)(cwd, ".gkm");
|
|
1574
|
+
await (0, node_fs_promises.mkdir)(dir, { recursive: true });
|
|
1575
|
+
const secretsJsonPath = (0, node_path.join)(dir, "image-build-env.json");
|
|
1576
|
+
await (0, node_fs_promises.writeFile)(secretsJsonPath, JSON.stringify(credentials, null, 2));
|
|
1577
|
+
return {
|
|
1578
|
+
credentials,
|
|
1579
|
+
secretsJsonPath
|
|
1580
|
+
};
|
|
1581
|
+
}
|
|
1565
1582
|
//#endregion
|
|
1566
1583
|
//#region src/dev/index.ts
|
|
1567
1584
|
const logger$5 = console;
|
|
@@ -2042,9 +2059,9 @@ async function workspaceDevCommand(configured, options) {
|
|
|
2042
2059
|
for (const { id, port } of fakes) logger$5.log(`🎭 ${id} fake: http://localhost:${port}`);
|
|
2043
2060
|
logger$5.log(options.migrate || options.seed ? "🗄️ Migrating the databases" : "🗄️ Checking for pending migrations");
|
|
2044
2061
|
if (options.migrate || options.seed) {
|
|
2045
|
-
const { prepareDevDatabases } = await Promise.resolve().then(() => require("./migrate-
|
|
2062
|
+
const { prepareDevDatabases } = await Promise.resolve().then(() => require("./migrate-D5_-ylI1.cjs"));
|
|
2046
2063
|
await prepareDevDatabases(workspace, reconciled.env, { seed: !!options.seed });
|
|
2047
|
-
} else await Promise.resolve().then(() => require("./migrate-
|
|
2064
|
+
} else await Promise.resolve().then(() => require("./migrate-D5_-ylI1.cjs")).then(({ reportPendingMigrations }) => reportPendingMigrations(workspace, reconciled.env)).catch((error) => {
|
|
2048
2065
|
logger$5.log(`⚠️ Could not check for pending migrations: ${error instanceof Error ? error.message : String(error)}`);
|
|
2049
2066
|
});
|
|
2050
2067
|
const appUrls = {};
|
|
@@ -3052,7 +3069,7 @@ async function buildApp(input) {
|
|
|
3052
3069
|
if (production?.bundle && !input.skipBundle) {
|
|
3053
3070
|
const outputDir = (0, node_path.join)(appRoot, ".gkm", "server");
|
|
3054
3071
|
const entryPoint = await writeSurfaceServer(outputDir, production);
|
|
3055
|
-
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-
|
|
3072
|
+
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-Cf6OgaOe.cjs"));
|
|
3056
3073
|
await bundleServer({
|
|
3057
3074
|
entryPoint,
|
|
3058
3075
|
outputDir: (0, node_path.join)(outputDir, "dist"),
|
|
@@ -3176,7 +3193,7 @@ async function buildWorkers(input) {
|
|
|
3176
3193
|
});
|
|
3177
3194
|
logger$4.log(`Generated worker ${worker.id}: ${crons.length} crons, ${queues.length} queues, ${subscribers.length} subscribers`);
|
|
3178
3195
|
if (!input.bundle) continue;
|
|
3179
|
-
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-
|
|
3196
|
+
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-Cf6OgaOe.cjs"));
|
|
3180
3197
|
const outfile = require_state.workerBundleName(worker.id);
|
|
3181
3198
|
await bundleServer({
|
|
3182
3199
|
entryPoint,
|
|
@@ -3246,7 +3263,7 @@ async function buildForTarget(target, context, appRoot, workspaceRoot, endpointG
|
|
|
3246
3263
|
let masterKey;
|
|
3247
3264
|
if (context.production?.bundle && !skipBundle) {
|
|
3248
3265
|
logger$4.log(`\n📦 Bundling production server...`);
|
|
3249
|
-
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-
|
|
3266
|
+
const { bundleServer } = await Promise.resolve().then(() => require("./bundler-Cf6OgaOe.cjs"));
|
|
3250
3267
|
const allConstructs = [
|
|
3251
3268
|
...endpoints.map((e) => e.construct),
|
|
3252
3269
|
...functions.map((f) => f.construct),
|
|
@@ -4970,25 +4987,25 @@ function loadPackageJson() {
|
|
|
4970
4987
|
* Run: pnpm --filter @geekmidas/cli sync-versions
|
|
4971
4988
|
*/
|
|
4972
4989
|
const GEEKMIDAS_VERSIONS = {
|
|
4973
|
-
"@geekmidas/audit": "~10.0.0-alpha.
|
|
4974
|
-
"@geekmidas/auth": "~10.0.0-alpha.
|
|
4975
|
-
"@geekmidas/cache": "~10.0.0-alpha.
|
|
4976
|
-
"@geekmidas/client": "~10.0.0-alpha.
|
|
4977
|
-
"@geekmidas/cloud": "~10.0.0-alpha.
|
|
4978
|
-
"@geekmidas/constructs": "~10.0.0-alpha.
|
|
4979
|
-
"@geekmidas/db": "~10.0.0-alpha.
|
|
4980
|
-
"@geekmidas/emailkit": "~10.0.0-alpha.
|
|
4981
|
-
"@geekmidas/envkit": "~10.0.0-alpha.
|
|
4982
|
-
"@geekmidas/errors": "~10.0.0-alpha.
|
|
4983
|
-
"@geekmidas/events": "~10.0.0-alpha.
|
|
4984
|
-
"@geekmidas/logger": "~10.0.0-alpha.
|
|
4985
|
-
"@geekmidas/manifest": "~10.0.0-alpha.
|
|
4986
|
-
"@geekmidas/rate-limit": "~10.0.0-alpha.
|
|
4987
|
-
"@geekmidas/schema": "~10.0.0-alpha.
|
|
4988
|
-
"@geekmidas/services": "~10.0.0-alpha.
|
|
4989
|
-
"@geekmidas/storage": "~10.0.0-alpha.
|
|
4990
|
-
"@geekmidas/telescope": "~10.0.0-alpha.
|
|
4991
|
-
"@geekmidas/testkit": "~10.0.0-alpha.
|
|
4990
|
+
"@geekmidas/audit": "~10.0.0-alpha.76",
|
|
4991
|
+
"@geekmidas/auth": "~10.0.0-alpha.76",
|
|
4992
|
+
"@geekmidas/cache": "~10.0.0-alpha.76",
|
|
4993
|
+
"@geekmidas/client": "~10.0.0-alpha.76",
|
|
4994
|
+
"@geekmidas/cloud": "~10.0.0-alpha.76",
|
|
4995
|
+
"@geekmidas/constructs": "~10.0.0-alpha.76",
|
|
4996
|
+
"@geekmidas/db": "~10.0.0-alpha.76",
|
|
4997
|
+
"@geekmidas/emailkit": "~10.0.0-alpha.76",
|
|
4998
|
+
"@geekmidas/envkit": "~10.0.0-alpha.76",
|
|
4999
|
+
"@geekmidas/errors": "~10.0.0-alpha.76",
|
|
5000
|
+
"@geekmidas/events": "~10.0.0-alpha.76",
|
|
5001
|
+
"@geekmidas/logger": "~10.0.0-alpha.76",
|
|
5002
|
+
"@geekmidas/manifest": "~10.0.0-alpha.76",
|
|
5003
|
+
"@geekmidas/rate-limit": "~10.0.0-alpha.76",
|
|
5004
|
+
"@geekmidas/schema": "~10.0.0-alpha.76",
|
|
5005
|
+
"@geekmidas/services": "~10.0.0-alpha.76",
|
|
5006
|
+
"@geekmidas/storage": "~10.0.0-alpha.76",
|
|
5007
|
+
"@geekmidas/telescope": "~10.0.0-alpha.76",
|
|
5008
|
+
"@geekmidas/testkit": "~10.0.0-alpha.76",
|
|
4992
5009
|
"@geekmidas/cli": `~${loadPackageJson().version}`
|
|
4993
5010
|
};
|
|
4994
5011
|
//#endregion
|
|
@@ -7046,6 +7063,7 @@ function secretsStore(options) {
|
|
|
7046
7063
|
return `
|
|
7047
7064
|
// Deployed stages keep their secrets in SSM, in the account each stage
|
|
7048
7065
|
// deploys to: \`gkm secrets:set <KEY> '…' --stage <stage>\` writes there.
|
|
7066
|
+
// Past 8 KB a stage needs { provider: 'secrets-manager', region } instead.
|
|
7049
7067
|
store: { provider: 'ssm', region: '${options.region}' },`;
|
|
7050
7068
|
}
|
|
7051
7069
|
/**
|
|
@@ -10141,8 +10159,8 @@ ${dbPasswordEntries.map(([key, value]) => `${key}=${value}`).join("\n")}
|
|
|
10141
10159
|
//#region src/secrets/index.ts
|
|
10142
10160
|
const logger$2 = console;
|
|
10143
10161
|
/**
|
|
10144
|
-
* The store the stage named on the command line keeps its secrets in — SSM
|
|
10145
|
-
* its account, for a deployed stage kept there. Outside any workspace nothing
|
|
10162
|
+
* The store the stage named on the command line keeps its secrets in — SSM or
|
|
10163
|
+
* Secrets Manager in its account, for a deployed stage kept there. Outside any workspace nothing
|
|
10146
10164
|
* names a store, so it is the file.
|
|
10147
10165
|
*/
|
|
10148
10166
|
async function storeFor(stage) {
|
|
@@ -10378,7 +10396,7 @@ const logger$1 = console;
|
|
|
10378
10396
|
*
|
|
10379
10397
|
* Orchestrates:
|
|
10380
10398
|
* 1. Load workspace config
|
|
10381
|
-
* 2. Resolve secrets (local →
|
|
10399
|
+
* 2. Resolve secrets (local → the stage's store → generate fresh)
|
|
10382
10400
|
* 3. Write docker/.env from secrets
|
|
10383
10401
|
* 4. Start Docker services
|
|
10384
10402
|
*/
|
|
@@ -10546,7 +10564,7 @@ function reconcileSecrets(secrets, workspace, containers = []) {
|
|
|
10546
10564
|
/**
|
|
10547
10565
|
* Build a fresh StageSecrets object for a workspace: service credentials,
|
|
10548
10566
|
* connection URLs, and custom secrets. Pure — does not write to disk or touch
|
|
10549
|
-
*
|
|
10567
|
+
* any store. Service passwords are freshly randomized, so the result must be the same
|
|
10550
10568
|
* one used to start the matching Docker containers.
|
|
10551
10569
|
* @internal Exported for reuse by `gkm test` auto-setup.
|
|
10552
10570
|
*/
|
|
@@ -10779,7 +10797,7 @@ function testDatabases(reconciled) {
|
|
|
10779
10797
|
* starts without the reference data the app needs.
|
|
10780
10798
|
*/
|
|
10781
10799
|
async function migrateTestStage(workspace, env) {
|
|
10782
|
-
const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-
|
|
10800
|
+
const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-D5_-ylI1.cjs"));
|
|
10783
10801
|
const { discover } = await Promise.resolve().then(() => require("./discover-D1It5r_h.cjs")).then((n) => n.discover_exports);
|
|
10784
10802
|
const sources = {};
|
|
10785
10803
|
const manifest = await discover({
|
|
@@ -11212,7 +11230,7 @@ program.command("migrate").description("Apply each database construct's migratio
|
|
|
11212
11230
|
try {
|
|
11213
11231
|
const globalOptions = program.opts();
|
|
11214
11232
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11215
|
-
const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11233
|
+
const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-D5_-ylI1.cjs"));
|
|
11216
11234
|
await migrateCommand({
|
|
11217
11235
|
...options,
|
|
11218
11236
|
...construct ? { construct } : {}
|
|
@@ -11226,7 +11244,7 @@ program.command("seed").description("Migrate, then run each database construct's
|
|
|
11226
11244
|
try {
|
|
11227
11245
|
const globalOptions = program.opts();
|
|
11228
11246
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11229
|
-
const { seedCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11247
|
+
const { seedCommand } = await Promise.resolve().then(() => require("./migrate-D5_-ylI1.cjs"));
|
|
11230
11248
|
await seedCommand({
|
|
11231
11249
|
...options,
|
|
11232
11250
|
...construct ? { construct } : {}
|
|
@@ -11240,7 +11258,7 @@ program.command("migration").description("Write a construct's next migration: an
|
|
|
11240
11258
|
try {
|
|
11241
11259
|
const globalOptions = program.opts();
|
|
11242
11260
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11243
|
-
const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11261
|
+
const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-D5_-ylI1.cjs"));
|
|
11244
11262
|
await migrationCommand({
|
|
11245
11263
|
construct,
|
|
11246
11264
|
...name ? { name } : {}
|
|
@@ -11334,7 +11352,7 @@ program.command("secrets:add").description("Build the keys a stage must be given
|
|
|
11334
11352
|
try {
|
|
11335
11353
|
const globalOptions = program.opts();
|
|
11336
11354
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11337
|
-
const { secretsAddCommand } = await Promise.resolve().then(() => require("./add-
|
|
11355
|
+
const { secretsAddCommand } = await Promise.resolve().then(() => require("./add-j2yI3cbS.cjs"));
|
|
11338
11356
|
await secretsAddCommand(options);
|
|
11339
11357
|
} catch (error) {
|
|
11340
11358
|
console.error(formatError(error));
|
|
@@ -11345,7 +11363,7 @@ program.command("encryption:rotate").description("Add a new current key to an En
|
|
|
11345
11363
|
try {
|
|
11346
11364
|
const globalOptions = program.opts();
|
|
11347
11365
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11348
|
-
const { encryptionRotateCommand } = await Promise.resolve().then(() => require("./encryption-
|
|
11366
|
+
const { encryptionRotateCommand } = await Promise.resolve().then(() => require("./encryption-vS3Qzw73.cjs"));
|
|
11349
11367
|
await encryptionRotateCommand(construct, options);
|
|
11350
11368
|
} catch (error) {
|
|
11351
11369
|
console.error(formatError(error));
|
|
@@ -11356,7 +11374,7 @@ program.command("encryption:retire").description("Remove an old key from an Encr
|
|
|
11356
11374
|
try {
|
|
11357
11375
|
const globalOptions = program.opts();
|
|
11358
11376
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11359
|
-
const { encryptionRetireCommand } = await Promise.resolve().then(() => require("./encryption-
|
|
11377
|
+
const { encryptionRetireCommand } = await Promise.resolve().then(() => require("./encryption-vS3Qzw73.cjs"));
|
|
11360
11378
|
await encryptionRetireCommand(construct, key, options);
|
|
11361
11379
|
} catch (error) {
|
|
11362
11380
|
console.error(formatError(error));
|
|
@@ -11399,7 +11417,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
11399
11417
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11400
11418
|
const { loadWorkspaceConfig } = await Promise.resolve().then(() => require("./config.cjs"));
|
|
11401
11419
|
const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-CuCQBa5-.cjs"));
|
|
11402
|
-
const { secretsStoreFor } = await Promise.resolve().then(() => require("./state-
|
|
11420
|
+
const { secretsStoreFor } = await Promise.resolve().then(() => require("./state-C2qi0iQw.cjs")).then((n) => n.store_exports);
|
|
11403
11421
|
const { workspace } = await loadWorkspaceConfig();
|
|
11404
11422
|
const stage = options.stage ?? workspace.stages.local;
|
|
11405
11423
|
const store = await secretsStoreFor(workspace, stage);
|
|
@@ -11408,7 +11426,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
11408
11426
|
console.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
|
|
11409
11427
|
process.exit(1);
|
|
11410
11428
|
}
|
|
11411
|
-
const { derivedContainers } = await Promise.resolve().then(() => require("./state-
|
|
11429
|
+
const { derivedContainers } = await Promise.resolve().then(() => require("./state-C2qi0iQw.cjs")).then((n) => n.workspace_exports);
|
|
11412
11430
|
const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
|
|
11413
11431
|
if (!result) {
|
|
11414
11432
|
console.log(`\n✓ Secrets for stage "${stage}" are up-to-date`);
|
|
@@ -11422,8 +11440,19 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
11422
11440
|
process.exit(1);
|
|
11423
11441
|
}
|
|
11424
11442
|
});
|
|
11443
|
+
program.command("secrets:migrate").description("Copy a deployed stage's secrets from the configured store to another (file, ssm, secrets-manager)").requiredOption("--stage <stage>", "A deployed stage").requiredOption("--to <provider>", "file, ssm or secrets-manager").option("--region <region>", "The target's AWS region (default: the configured store's)").option("--profile <profile>", "AWS profile for the stage's account").option("--force", "Replace a stage the target already holds").action(async (options) => {
|
|
11444
|
+
try {
|
|
11445
|
+
const globalOptions = program.opts();
|
|
11446
|
+
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11447
|
+
const { secretsMigrateCommand } = await Promise.resolve().then(() => require("./migrate-BRbYtFXG.cjs"));
|
|
11448
|
+
await secretsMigrateCommand(options);
|
|
11449
|
+
} catch (error) {
|
|
11450
|
+
console.error(formatError(error));
|
|
11451
|
+
process.exit(1);
|
|
11452
|
+
}
|
|
11453
|
+
});
|
|
11425
11454
|
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) => {
|
|
11426
|
-
const { deployCli } = await Promise.resolve().then(() => require("./cli-
|
|
11455
|
+
const { deployCli } = await Promise.resolve().then(() => require("./cli-CNanUB7a.cjs"));
|
|
11427
11456
|
const globalOptions = program.opts();
|
|
11428
11457
|
const code = await deployCli({
|
|
11429
11458
|
cwd: (0, node_path.resolve)(globalOptions.cwd ?? process.cwd()),
|
|
@@ -11440,7 +11469,7 @@ program.command("deploy").description("Deploy a stage through its target").optio
|
|
|
11440
11469
|
});
|
|
11441
11470
|
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) => {
|
|
11442
11471
|
try {
|
|
11443
|
-
const { rollbackStage } = await Promise.resolve().then(() => require("./rollback-
|
|
11472
|
+
const { rollbackStage } = await Promise.resolve().then(() => require("./rollback-C9N5lKVf.cjs")).then((n) => n.rollback_exports);
|
|
11444
11473
|
const { terminalCredentials } = await Promise.resolve().then(() => require("./terminal-BL5E0xbR.cjs"));
|
|
11445
11474
|
const globalOptions = program.opts();
|
|
11446
11475
|
await rollbackStage({
|
|
@@ -11476,7 +11505,7 @@ program.command("deploy:github").description("Let GitHub Actions deploy a stage:
|
|
|
11476
11505
|
try {
|
|
11477
11506
|
const globalOptions = program.opts();
|
|
11478
11507
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11479
|
-
const { deployGithubCommand } = await Promise.resolve().then(() => require("./github-
|
|
11508
|
+
const { deployGithubCommand } = await Promise.resolve().then(() => require("./github-ClkdCOL9.cjs"));
|
|
11480
11509
|
await deployGithubCommand(options);
|
|
11481
11510
|
} catch (error) {
|
|
11482
11511
|
console.error(formatError(error));
|