@geekmidas/cli 10.0.0-alpha.74 → 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-D_78eaHM.cjs → LegacyStateStore-DwngfJxr.cjs} +2 -2
- package/dist/{LegacyStateStore-D_78eaHM.cjs.map → LegacyStateStore-DwngfJxr.cjs.map} +1 -1
- package/dist/{LegacyStateStore-DTo7z924.mjs → LegacyStateStore-dyq07_Ir.mjs} +2 -2
- package/dist/{LegacyStateStore-DTo7z924.mjs.map → LegacyStateStore-dyq07_Ir.mjs.map} +1 -1
- package/dist/{LocalStateStore-BhrlQIXD.cjs → LocalStateStore-B0NCde8Z.cjs} +2 -2
- package/dist/{LocalStateStore-BhrlQIXD.cjs.map → LocalStateStore-B0NCde8Z.cjs.map} +1 -1
- package/dist/{LocalStateStore-CNjgkRk4.mjs → LocalStateStore-DLxCCatI.mjs} +2 -2
- package/dist/{LocalStateStore-CNjgkRk4.mjs.map → LocalStateStore-DLxCCatI.mjs.map} +1 -1
- package/dist/{S3StateStore-oCxRs6HM.cjs → S3StateStore-BOenb-3o.cjs} +2 -2
- package/dist/{S3StateStore-oCxRs6HM.cjs.map → S3StateStore-BOenb-3o.cjs.map} +1 -1
- package/dist/{S3StateStore-g2P7T_Mo.mjs → S3StateStore-CGK_4hlo.mjs} +2 -2
- package/dist/{S3StateStore-g2P7T_Mo.mjs.map → S3StateStore-CGK_4hlo.mjs.map} +1 -1
- package/dist/{SSMStateStore-CYenunmK.mjs → SSMStateStore-B_5_RqY-.mjs} +2 -2
- package/dist/{SSMStateStore-CYenunmK.mjs.map → SSMStateStore-B_5_RqY-.mjs.map} +1 -1
- package/dist/{SSMStateStore-DXp0m7XI.cjs → SSMStateStore-DYeD__7p.cjs} +2 -2
- package/dist/{SSMStateStore-DXp0m7XI.cjs.map → SSMStateStore-DYeD__7p.cjs.map} +1 -1
- package/dist/{add-BTH7WaH3.mjs → add-B7IMXzou.mjs} +3 -3
- package/dist/{add-BTH7WaH3.mjs.map → add-B7IMXzou.mjs.map} +1 -1
- package/dist/{add-Djrr12Xc.cjs → add-j2yI3cbS.cjs} +3 -3
- package/dist/{add-Djrr12Xc.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-utHuESvL.cjs → bundler-Cf6OgaOe.cjs} +5 -5
- package/dist/bundler-Cf6OgaOe.cjs.map +1 -0
- package/dist/{bundler-BUojOkof.mjs → bundler-DO6bHhnb.mjs} +5 -5
- package/dist/bundler-DO6bHhnb.mjs.map +1 -0
- package/dist/{cli-CyYceKTS.mjs → cli-BCPOHmg9.mjs} +3 -3
- package/dist/{cli-CyYceKTS.mjs.map → cli-BCPOHmg9.mjs.map} +1 -1
- package/dist/{cli-Bx0sUzxH.cjs → cli-CNanUB7a.cjs} +3 -3
- package/dist/{cli-Bx0sUzxH.cjs.map → cli-CNanUB7a.cjs.map} +1 -1
- package/dist/{compose-DZp8DJ0A.mjs → compose-Dq4VCtu5.mjs} +221 -153
- package/dist/compose-Dq4VCtu5.mjs.map +1 -0
- package/dist/{compose-iuw8wfHk.cjs → compose-h_6oNnHC.cjs} +243 -151
- 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 +7 -6
- package/dist/deploy/public.d.cts +14 -3
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts +14 -3
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +7 -7
- package/dist/{deploy-eWorhvQp.cjs → deploy-CT3R9de9.cjs} +27 -5
- package/dist/deploy-CT3R9de9.cjs.map +1 -0
- package/dist/{deploy-C17K7Imy.mjs → deploy-CVXEx7Nm.mjs} +22 -6
- package/dist/deploy-CVXEx7Nm.mjs.map +1 -0
- package/dist/{dokploy-DKa49Nqm.mjs → dokploy-CYm2ozFs.mjs} +2 -2
- package/dist/{dokploy-DKa49Nqm.mjs.map → dokploy-CYm2ozFs.mjs.map} +1 -1
- package/dist/{dokploy-DKzcI-RL.cjs → dokploy-eSGmlhhj.cjs} +2 -2
- package/dist/{dokploy-DKzcI-RL.cjs.map → dokploy-eSGmlhhj.cjs.map} +1 -1
- package/dist/{encryption-sTMz3aWi.mjs → encryption-DC0rsR1W.mjs} +3 -3
- package/dist/{encryption-sTMz3aWi.mjs.map → encryption-DC0rsR1W.mjs.map} +1 -1
- package/dist/{encryption-DSkJdoyk.cjs → encryption-vS3Qzw73.cjs} +3 -3
- package/dist/{encryption-DSkJdoyk.cjs.map → encryption-vS3Qzw73.cjs.map} +1 -1
- package/dist/{engine-B1b4I34Z.mjs → engine-BOO5TWZd.mjs} +193 -5
- package/dist/engine-BOO5TWZd.mjs.map +1 -0
- package/dist/{engine-Bh76sAHy.cjs → engine-C0N2d1i5.cjs} +196 -8
- package/dist/engine-C0N2d1i5.cjs.map +1 -0
- package/dist/{github-C9ODoyZU.mjs → github-CEaFDL6t.mjs} +6 -6
- package/dist/github-CEaFDL6t.mjs.map +1 -0
- package/dist/{github-BvN3CfxM.cjs → github-ClkdCOL9.cjs} +6 -6
- package/dist/github-ClkdCOL9.cjs.map +1 -0
- package/dist/{index-B-1lLGzy.d.mts → 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-vMidfqhU.d.cts → index-DOxmDKqv.d.mts} +2 -2
- package/dist/{index-vMidfqhU.d.cts.map → index-DOxmDKqv.d.mts.map} +1 -1
- package/dist/index.cjs +106 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +105 -51
- 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-B0FCZNkp.cjs → migrate-D5_-ylI1.cjs} +3 -3
- package/dist/{migrate-B0FCZNkp.cjs.map → migrate-D5_-ylI1.cjs.map} +1 -1
- package/dist/{migrate-CTtJhGV9.mjs → migrate-DrO2p9Rl.mjs} +3 -3
- package/dist/{migrate-CTtJhGV9.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-DSAXj_47.mjs → resolve-C1muFos5.mjs} +3 -3
- package/dist/{resolve-DSAXj_47.mjs.map → resolve-C1muFos5.mjs.map} +1 -1
- package/dist/{resolve-D_BU-wKA.cjs → resolve-Fa1Ii0BK.cjs} +3 -3
- package/dist/{resolve-D_BU-wKA.cjs.map → resolve-Fa1Ii0BK.cjs.map} +1 -1
- package/dist/{rollback-DJy3t696.cjs → rollback-C9N5lKVf.cjs} +5 -5
- package/dist/{rollback-DJy3t696.cjs.map → rollback-C9N5lKVf.cjs.map} +1 -1
- package/dist/{rollback-CWYTUhfW.mjs → rollback-DeQzbRqM.mjs} +5 -5
- package/dist/{rollback-CWYTUhfW.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-BFmdZpZ2.mjs → sniffer-DR8AlRCk.mjs} +67 -15
- package/dist/sniffer-DR8AlRCk.mjs.map +1 -0
- package/dist/{sniffer-C-T7dSMN.cjs → sniffer-Y6GQOCXB.cjs} +83 -13
- package/dist/sniffer-Y6GQOCXB.cjs.map +1 -0
- package/dist/{state-DCwRWyh-.cjs → state-C2qi0iQw.cjs} +241 -334
- package/dist/state-C2qi0iQw.cjs.map +1 -0
- package/dist/{state-DpkxSwzI.mjs → state-CUecOCNJ.mjs} +213 -306
- 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 +18 -17
- package/dist/aws-DkHdTV-p.cjs.map +0 -1
- package/dist/aws-DojzQnLd.mjs.map +0 -1
- package/dist/bundler-BUojOkof.mjs.map +0 -1
- package/dist/bundler-utHuESvL.cjs.map +0 -1
- package/dist/compose-DZp8DJ0A.mjs.map +0 -1
- package/dist/compose-iuw8wfHk.cjs.map +0 -1
- package/dist/deploy-C17K7Imy.mjs.map +0 -1
- package/dist/deploy-eWorhvQp.cjs.map +0 -1
- package/dist/engine-B1b4I34Z.mjs.map +0 -1
- package/dist/engine-Bh76sAHy.cjs.map +0 -1
- package/dist/github-BvN3CfxM.cjs.map +0 -1
- package/dist/github-C9ODoyZU.mjs.map +0 -1
- package/dist/sniffer-BFmdZpZ2.mjs.map +0 -1
- package/dist/sniffer-C-T7dSMN.cjs.map +0 -1
- package/dist/state-DCwRWyh-.cjs.map +0 -1
- package/dist/state-DpkxSwzI.mjs.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 { Gt as
|
|
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-C-T7dSMN.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),
|
|
@@ -3269,7 +3286,7 @@ async function buildForTarget(target, context, appRoot, workspaceRoot, endpointG
|
|
|
3269
3286
|
await (0, node_fs_promises.writeFile)(keyPath, `${masterKey}\n`, { mode: 384 });
|
|
3270
3287
|
await (0, node_fs_promises.chmod)(keyPath, 384);
|
|
3271
3288
|
logger$4.log(`\n🔐 Secrets encrypted for deployment`);
|
|
3272
|
-
logger$4.log(` Run with GKM_MASTER_KEY set to the key in ${(0, node_path.relative)(appRoot, keyPath)} (fingerprint ${
|
|
3289
|
+
logger$4.log(` Run with GKM_MASTER_KEY set to the key in ${(0, node_path.relative)(appRoot, keyPath)} (fingerprint ${require_sniffer.keyFingerprint(masterKey)})`);
|
|
3273
3290
|
}
|
|
3274
3291
|
}
|
|
3275
3292
|
return {
|
|
@@ -3490,9 +3507,16 @@ var ComposeModeConflict = class extends Error {
|
|
|
3490
3507
|
this.name = "ComposeModeConflict";
|
|
3491
3508
|
}
|
|
3492
3509
|
};
|
|
3510
|
+
/** Each pushed image as `<ref>@sha256:…`, by app. */
|
|
3511
|
+
function pushedDigests(run) {
|
|
3512
|
+
return Object.fromEntries(Object.entries(run.images).filter(([, image]) => image.digest).sort(([a], [b]) => a.localeCompare(b)).map(([app, image]) => [app, require_compose.pinnedRef(image.ref, image.digest)]));
|
|
3513
|
+
}
|
|
3493
3514
|
/** `gkm compose`. */
|
|
3494
3515
|
async function composeCommand(options, deps = {}) {
|
|
3495
3516
|
if (options.build && options.pull) throw new ComposeModeConflict();
|
|
3517
|
+
if (options.push && !options.build) throw new require_compose.ComposePushNeedsBuild();
|
|
3518
|
+
const pulls = !options.build && (options.pull || options.tag !== void 0);
|
|
3519
|
+
if (options.digestsFile && !options.push && !pulls) throw new require_compose.ComposePinNeedsPull();
|
|
3496
3520
|
const allowDevServices = require_state.parseDevServices(options.allowDevServices);
|
|
3497
3521
|
const cwd = (0, node_path.resolve)(options.cwd ?? process.cwd());
|
|
3498
3522
|
const { workspace } = await require_config.loadWorkspaceConfig(cwd);
|
|
@@ -3512,6 +3536,10 @@ async function composeCommand(options, deps = {}) {
|
|
|
3512
3536
|
let finished;
|
|
3513
3537
|
const mode = options.build ? "build" : options.pull ? "pull" : void 0;
|
|
3514
3538
|
const tag = options.tag ?? (options.pull ? "latest" : void 0);
|
|
3539
|
+
const pin = options.digestsFile && pulls ? {
|
|
3540
|
+
file: options.digestsFile,
|
|
3541
|
+
digests: require_compose.parseDigests(options.digestsFile, await (0, node_fs_promises.readFile)((0, node_path.resolve)(cwd, options.digestsFile), "utf-8"))
|
|
3542
|
+
} : void 0;
|
|
3515
3543
|
const result = await require_deploy.deploy({
|
|
3516
3544
|
cwd,
|
|
3517
3545
|
stage,
|
|
@@ -3519,12 +3547,15 @@ async function composeCommand(options, deps = {}) {
|
|
|
3519
3547
|
targets: { compose: require_compose.composeTarget({
|
|
3520
3548
|
...deps,
|
|
3521
3549
|
...mode ? { mode } : {},
|
|
3550
|
+
...options.push ? { push: true } : {},
|
|
3551
|
+
...pin ? { pin } : {},
|
|
3522
3552
|
report: (done) => {
|
|
3523
3553
|
finished = done;
|
|
3524
3554
|
}
|
|
3525
3555
|
}) },
|
|
3526
3556
|
...tag ? { tag } : {},
|
|
3527
3557
|
...options.dryRun ? { dryRun: true } : {},
|
|
3558
|
+
...options.push ? { buildOnly: true } : {},
|
|
3528
3559
|
...allowDevServices.length > 0 ? { allowDevServices } : {},
|
|
3529
3560
|
logger: {
|
|
3530
3561
|
info: (message) => console.log(message),
|
|
@@ -3533,6 +3564,17 @@ async function composeCommand(options, deps = {}) {
|
|
|
3533
3564
|
}
|
|
3534
3565
|
}).result;
|
|
3535
3566
|
if (!finished) return void 0;
|
|
3567
|
+
if (options.push && !options.dryRun) {
|
|
3568
|
+
const digests = pushedDigests(finished);
|
|
3569
|
+
console.log(`\n✅ Pushed ${Object.keys(digests).length} image(s):`);
|
|
3570
|
+
for (const [app, ref] of Object.entries(digests)) console.log(` ${app.padEnd(12)} ${ref}`);
|
|
3571
|
+
if (options.digestsFile) {
|
|
3572
|
+
const file = (0, node_path.resolve)(cwd, options.digestsFile);
|
|
3573
|
+
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(file), { recursive: true });
|
|
3574
|
+
await (0, node_fs_promises.writeFile)(file, `${JSON.stringify(digests, null, 2)}\n`);
|
|
3575
|
+
console.log(`\n📝 Wrote the digests to ${options.digestsFile}`);
|
|
3576
|
+
}
|
|
3577
|
+
}
|
|
3536
3578
|
return {
|
|
3537
3579
|
stack: finished.stack,
|
|
3538
3580
|
files: finished.files,
|
|
@@ -4945,25 +4987,25 @@ function loadPackageJson() {
|
|
|
4945
4987
|
* Run: pnpm --filter @geekmidas/cli sync-versions
|
|
4946
4988
|
*/
|
|
4947
4989
|
const GEEKMIDAS_VERSIONS = {
|
|
4948
|
-
"@geekmidas/audit": "~10.0.0-alpha.
|
|
4949
|
-
"@geekmidas/auth": "~10.0.0-alpha.
|
|
4950
|
-
"@geekmidas/cache": "~10.0.0-alpha.
|
|
4951
|
-
"@geekmidas/client": "~10.0.0-alpha.
|
|
4952
|
-
"@geekmidas/cloud": "~10.0.0-alpha.
|
|
4953
|
-
"@geekmidas/constructs": "~10.0.0-alpha.
|
|
4954
|
-
"@geekmidas/db": "~10.0.0-alpha.
|
|
4955
|
-
"@geekmidas/emailkit": "~10.0.0-alpha.
|
|
4956
|
-
"@geekmidas/envkit": "~10.0.0-alpha.
|
|
4957
|
-
"@geekmidas/errors": "~10.0.0-alpha.
|
|
4958
|
-
"@geekmidas/events": "~10.0.0-alpha.
|
|
4959
|
-
"@geekmidas/logger": "~10.0.0-alpha.
|
|
4960
|
-
"@geekmidas/manifest": "~10.0.0-alpha.
|
|
4961
|
-
"@geekmidas/rate-limit": "~10.0.0-alpha.
|
|
4962
|
-
"@geekmidas/schema": "~10.0.0-alpha.
|
|
4963
|
-
"@geekmidas/services": "~10.0.0-alpha.
|
|
4964
|
-
"@geekmidas/storage": "~10.0.0-alpha.
|
|
4965
|
-
"@geekmidas/telescope": "~10.0.0-alpha.
|
|
4966
|
-
"@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",
|
|
4967
5009
|
"@geekmidas/cli": `~${loadPackageJson().version}`
|
|
4968
5010
|
};
|
|
4969
5011
|
//#endregion
|
|
@@ -7021,6 +7063,7 @@ function secretsStore(options) {
|
|
|
7021
7063
|
return `
|
|
7022
7064
|
// Deployed stages keep their secrets in SSM, in the account each stage
|
|
7023
7065
|
// deploys to: \`gkm secrets:set <KEY> '…' --stage <stage>\` writes there.
|
|
7066
|
+
// Past 8 KB a stage needs { provider: 'secrets-manager', region } instead.
|
|
7024
7067
|
store: { provider: 'ssm', region: '${options.region}' },`;
|
|
7025
7068
|
}
|
|
7026
7069
|
/**
|
|
@@ -10116,8 +10159,8 @@ ${dbPasswordEntries.map(([key, value]) => `${key}=${value}`).join("\n")}
|
|
|
10116
10159
|
//#region src/secrets/index.ts
|
|
10117
10160
|
const logger$2 = console;
|
|
10118
10161
|
/**
|
|
10119
|
-
* The store the stage named on the command line keeps its secrets in — SSM
|
|
10120
|
-
* 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
|
|
10121
10164
|
* names a store, so it is the file.
|
|
10122
10165
|
*/
|
|
10123
10166
|
async function storeFor(stage) {
|
|
@@ -10353,7 +10396,7 @@ const logger$1 = console;
|
|
|
10353
10396
|
*
|
|
10354
10397
|
* Orchestrates:
|
|
10355
10398
|
* 1. Load workspace config
|
|
10356
|
-
* 2. Resolve secrets (local →
|
|
10399
|
+
* 2. Resolve secrets (local → the stage's store → generate fresh)
|
|
10357
10400
|
* 3. Write docker/.env from secrets
|
|
10358
10401
|
* 4. Start Docker services
|
|
10359
10402
|
*/
|
|
@@ -10521,7 +10564,7 @@ function reconcileSecrets(secrets, workspace, containers = []) {
|
|
|
10521
10564
|
/**
|
|
10522
10565
|
* Build a fresh StageSecrets object for a workspace: service credentials,
|
|
10523
10566
|
* connection URLs, and custom secrets. Pure — does not write to disk or touch
|
|
10524
|
-
*
|
|
10567
|
+
* any store. Service passwords are freshly randomized, so the result must be the same
|
|
10525
10568
|
* one used to start the matching Docker containers.
|
|
10526
10569
|
* @internal Exported for reuse by `gkm test` auto-setup.
|
|
10527
10570
|
*/
|
|
@@ -10754,7 +10797,7 @@ function testDatabases(reconciled) {
|
|
|
10754
10797
|
* starts without the reference data the app needs.
|
|
10755
10798
|
*/
|
|
10756
10799
|
async function migrateTestStage(workspace, env) {
|
|
10757
|
-
const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-
|
|
10800
|
+
const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-D5_-ylI1.cjs"));
|
|
10758
10801
|
const { discover } = await Promise.resolve().then(() => require("./discover-D1It5r_h.cjs")).then((n) => n.discover_exports);
|
|
10759
10802
|
const sources = {};
|
|
10760
10803
|
const manifest = await discover({
|
|
@@ -11187,7 +11230,7 @@ program.command("migrate").description("Apply each database construct's migratio
|
|
|
11187
11230
|
try {
|
|
11188
11231
|
const globalOptions = program.opts();
|
|
11189
11232
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11190
|
-
const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11233
|
+
const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-D5_-ylI1.cjs"));
|
|
11191
11234
|
await migrateCommand({
|
|
11192
11235
|
...options,
|
|
11193
11236
|
...construct ? { construct } : {}
|
|
@@ -11201,7 +11244,7 @@ program.command("seed").description("Migrate, then run each database construct's
|
|
|
11201
11244
|
try {
|
|
11202
11245
|
const globalOptions = program.opts();
|
|
11203
11246
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11204
|
-
const { seedCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11247
|
+
const { seedCommand } = await Promise.resolve().then(() => require("./migrate-D5_-ylI1.cjs"));
|
|
11205
11248
|
await seedCommand({
|
|
11206
11249
|
...options,
|
|
11207
11250
|
...construct ? { construct } : {}
|
|
@@ -11215,7 +11258,7 @@ program.command("migration").description("Write a construct's next migration: an
|
|
|
11215
11258
|
try {
|
|
11216
11259
|
const globalOptions = program.opts();
|
|
11217
11260
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11218
|
-
const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
11261
|
+
const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-D5_-ylI1.cjs"));
|
|
11219
11262
|
await migrationCommand({
|
|
11220
11263
|
construct,
|
|
11221
11264
|
...name ? { name } : {}
|
|
@@ -11260,7 +11303,7 @@ program.command("docker").description("Generate Docker deployment files").option
|
|
|
11260
11303
|
process.exit(1);
|
|
11261
11304
|
}
|
|
11262
11305
|
});
|
|
11263
|
-
program.command("compose").description("Run the workspace's APIs and sites for a stage as one Docker Compose stack behind Caddy").requiredOption("--stage <stage>", "Stage to run — always named, so a stack is never a deployed stage by accident").option("--tag <tag>", "Run the images CI pushed at this tag (sites: <tag>-<stage>); nothing is built").option("--build", "Build images from this checkout, tagged with the commit").option("--pull", "Pull images (at --tag, or latest) rather than build them").option("--dry-run", "Write the files and print the plan; start nothing").option("--down", "Stop the stage's stack (its volumes are kept)").option("--allow-dev-services <list>", "Deployed stage: run MinIO and/or Mailpit (minio,mailpit) for mail and buckets the stage's secrets don't configure. Not production-grade").action(async (options) => {
|
|
11306
|
+
program.command("compose").description("Run the workspace's APIs and sites for a stage as one Docker Compose stack behind Caddy").requiredOption("--stage <stage>", "Stage to run — always named, so a stack is never a deployed stage by accident").option("--tag <tag>", "Run the images CI pushed at this tag (sites: <tag>-<stage>); nothing is built").option("--build", "Build images from this checkout, tagged with the commit").option("--pull", "Pull images (at --tag, or latest) rather than build them").option("--push", "With --build: push every image to deploy.registry and start nothing (for CI)").option("--digests-file <path>", "With --push: write each image as <ref>@sha256:… (JSON). With --tag: run the images at those digests").option("--dry-run", "Write the files and print the plan; start nothing").option("--down", "Stop the stage's stack (its volumes are kept)").option("--allow-dev-services <list>", "Deployed stage: run MinIO and/or Mailpit (minio,mailpit) for mail and buckets the stage's secrets don't configure. Not production-grade").action(async (options) => {
|
|
11264
11307
|
try {
|
|
11265
11308
|
const globalOptions = program.opts();
|
|
11266
11309
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
@@ -11309,7 +11352,7 @@ program.command("secrets:add").description("Build the keys a stage must be given
|
|
|
11309
11352
|
try {
|
|
11310
11353
|
const globalOptions = program.opts();
|
|
11311
11354
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11312
|
-
const { secretsAddCommand } = await Promise.resolve().then(() => require("./add-
|
|
11355
|
+
const { secretsAddCommand } = await Promise.resolve().then(() => require("./add-j2yI3cbS.cjs"));
|
|
11313
11356
|
await secretsAddCommand(options);
|
|
11314
11357
|
} catch (error) {
|
|
11315
11358
|
console.error(formatError(error));
|
|
@@ -11320,7 +11363,7 @@ program.command("encryption:rotate").description("Add a new current key to an En
|
|
|
11320
11363
|
try {
|
|
11321
11364
|
const globalOptions = program.opts();
|
|
11322
11365
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11323
|
-
const { encryptionRotateCommand } = await Promise.resolve().then(() => require("./encryption-
|
|
11366
|
+
const { encryptionRotateCommand } = await Promise.resolve().then(() => require("./encryption-vS3Qzw73.cjs"));
|
|
11324
11367
|
await encryptionRotateCommand(construct, options);
|
|
11325
11368
|
} catch (error) {
|
|
11326
11369
|
console.error(formatError(error));
|
|
@@ -11331,7 +11374,7 @@ program.command("encryption:retire").description("Remove an old key from an Encr
|
|
|
11331
11374
|
try {
|
|
11332
11375
|
const globalOptions = program.opts();
|
|
11333
11376
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11334
|
-
const { encryptionRetireCommand } = await Promise.resolve().then(() => require("./encryption-
|
|
11377
|
+
const { encryptionRetireCommand } = await Promise.resolve().then(() => require("./encryption-vS3Qzw73.cjs"));
|
|
11335
11378
|
await encryptionRetireCommand(construct, key, options);
|
|
11336
11379
|
} catch (error) {
|
|
11337
11380
|
console.error(formatError(error));
|
|
@@ -11374,7 +11417,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
11374
11417
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11375
11418
|
const { loadWorkspaceConfig } = await Promise.resolve().then(() => require("./config.cjs"));
|
|
11376
11419
|
const { reconcileMissingSecrets } = await Promise.resolve().then(() => require("./reconcile-CuCQBa5-.cjs"));
|
|
11377
|
-
const { secretsStoreFor } = await Promise.resolve().then(() => require("./state-
|
|
11420
|
+
const { secretsStoreFor } = await Promise.resolve().then(() => require("./state-C2qi0iQw.cjs")).then((n) => n.store_exports);
|
|
11378
11421
|
const { workspace } = await loadWorkspaceConfig();
|
|
11379
11422
|
const stage = options.stage ?? workspace.stages.local;
|
|
11380
11423
|
const store = await secretsStoreFor(workspace, stage);
|
|
@@ -11383,7 +11426,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
11383
11426
|
console.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
|
|
11384
11427
|
process.exit(1);
|
|
11385
11428
|
}
|
|
11386
|
-
const { derivedContainers } = await Promise.resolve().then(() => require("./state-
|
|
11429
|
+
const { derivedContainers } = await Promise.resolve().then(() => require("./state-C2qi0iQw.cjs")).then((n) => n.workspace_exports);
|
|
11387
11430
|
const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
|
|
11388
11431
|
if (!result) {
|
|
11389
11432
|
console.log(`\n✓ Secrets for stage "${stage}" are up-to-date`);
|
|
@@ -11397,8 +11440,19 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
11397
11440
|
process.exit(1);
|
|
11398
11441
|
}
|
|
11399
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
|
+
});
|
|
11400
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) => {
|
|
11401
|
-
const { deployCli } = await Promise.resolve().then(() => require("./cli-
|
|
11455
|
+
const { deployCli } = await Promise.resolve().then(() => require("./cli-CNanUB7a.cjs"));
|
|
11402
11456
|
const globalOptions = program.opts();
|
|
11403
11457
|
const code = await deployCli({
|
|
11404
11458
|
cwd: (0, node_path.resolve)(globalOptions.cwd ?? process.cwd()),
|
|
@@ -11415,7 +11469,7 @@ program.command("deploy").description("Deploy a stage through its target").optio
|
|
|
11415
11469
|
});
|
|
11416
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) => {
|
|
11417
11471
|
try {
|
|
11418
|
-
const { rollbackStage } = await Promise.resolve().then(() => require("./rollback-
|
|
11472
|
+
const { rollbackStage } = await Promise.resolve().then(() => require("./rollback-C9N5lKVf.cjs")).then((n) => n.rollback_exports);
|
|
11419
11473
|
const { terminalCredentials } = await Promise.resolve().then(() => require("./terminal-BL5E0xbR.cjs"));
|
|
11420
11474
|
const globalOptions = program.opts();
|
|
11421
11475
|
await rollbackStage({
|
|
@@ -11451,7 +11505,7 @@ program.command("deploy:github").description("Let GitHub Actions deploy a stage:
|
|
|
11451
11505
|
try {
|
|
11452
11506
|
const globalOptions = program.opts();
|
|
11453
11507
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
11454
|
-
const { deployGithubCommand } = await Promise.resolve().then(() => require("./github-
|
|
11508
|
+
const { deployGithubCommand } = await Promise.resolve().then(() => require("./github-ClkdCOL9.cjs"));
|
|
11455
11509
|
await deployGithubCommand(options);
|
|
11456
11510
|
} catch (error) {
|
|
11457
11511
|
console.error(formatError(error));
|