@geekmidas/cli 10.0.0-alpha.89 → 10.0.0-alpha.90
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/{GoDaddyProvider--36rw8cP.mjs → GoDaddyProvider-DSStJVAv.mjs} +2 -2
- package/dist/{GoDaddyProvider--36rw8cP.mjs.map → GoDaddyProvider-DSStJVAv.mjs.map} +1 -1
- package/dist/{GoDaddyProvider-DnRor066.cjs → GoDaddyProvider-DqZ1qD_F.cjs} +2 -2
- package/dist/{GoDaddyProvider-DnRor066.cjs.map → GoDaddyProvider-DqZ1qD_F.cjs.map} +1 -1
- package/dist/{LegacyStateStore-BaBoYl59.cjs → LegacyStateStore-DXmNA7hy.cjs} +2 -2
- package/dist/{LegacyStateStore-BaBoYl59.cjs.map → LegacyStateStore-DXmNA7hy.cjs.map} +1 -1
- package/dist/{LegacyStateStore-CO7bzJCU.mjs → LegacyStateStore-ZkdmiUFZ.mjs} +2 -2
- package/dist/{LegacyStateStore-CO7bzJCU.mjs.map → LegacyStateStore-ZkdmiUFZ.mjs.map} +1 -1
- package/dist/{LocalStateStore-CUWh2BWU.cjs → LocalStateStore-BBeTlRTH.cjs} +2 -2
- package/dist/{LocalStateStore-CUWh2BWU.cjs.map → LocalStateStore-BBeTlRTH.cjs.map} +1 -1
- package/dist/{LocalStateStore-C_hYDv6I.mjs → LocalStateStore-CU-O0SBp.mjs} +2 -2
- package/dist/{LocalStateStore-C_hYDv6I.mjs.map → LocalStateStore-CU-O0SBp.mjs.map} +1 -1
- package/dist/{S3StateStore-O8EYfjfG.cjs → S3StateStore-Br8VMY22.cjs} +2 -2
- package/dist/{S3StateStore-O8EYfjfG.cjs.map → S3StateStore-Br8VMY22.cjs.map} +1 -1
- package/dist/{S3StateStore-hIm8Rrmu.mjs → S3StateStore-bwxcI_wQ.mjs} +2 -2
- package/dist/{S3StateStore-hIm8Rrmu.mjs.map → S3StateStore-bwxcI_wQ.mjs.map} +1 -1
- package/dist/{SSMStateStore-IvcjTk8h.mjs → SSMStateStore-CsOS0W1y.mjs} +2 -2
- package/dist/{SSMStateStore-IvcjTk8h.mjs.map → SSMStateStore-CsOS0W1y.mjs.map} +1 -1
- package/dist/{SSMStateStore-DIzbiqCz.cjs → SSMStateStore-DoZE1Wi1.cjs} +2 -2
- package/dist/{SSMStateStore-DIzbiqCz.cjs.map → SSMStateStore-DoZE1Wi1.cjs.map} +1 -1
- package/dist/{add-C9qX4Juc.cjs → add-CNMF0Q3m.cjs} +2 -2
- package/dist/{add-C9qX4Juc.cjs.map → add-CNMF0Q3m.cjs.map} +1 -1
- package/dist/{add-v3tCbrpE.mjs → add-DHk1roh_.mjs} +2 -2
- package/dist/{add-v3tCbrpE.mjs.map → add-DHk1roh_.mjs.map} +1 -1
- package/dist/{bundler-C4NmpRTD.cjs → bundler-BQJiB7Ub.cjs} +3 -3
- package/dist/{bundler-C4NmpRTD.cjs.map → bundler-BQJiB7Ub.cjs.map} +1 -1
- package/dist/{bundler-C_fCgcVO.mjs → bundler-D6eBfVkl.mjs} +3 -3
- package/dist/{bundler-C_fCgcVO.mjs.map → bundler-D6eBfVkl.mjs.map} +1 -1
- package/dist/{cli-C85Dut8K.cjs → cli-BE9mqeX8.cjs} +2 -2
- package/dist/{cli-C85Dut8K.cjs.map → cli-BE9mqeX8.cjs.map} +1 -1
- package/dist/{cli-REdO9X5b.mjs → cli-DD-Yk-I5.mjs} +2 -2
- package/dist/{cli-REdO9X5b.mjs.map → cli-DD-Yk-I5.mjs.map} +1 -1
- package/dist/{compose-Dn0oAgQ0.mjs → compose-Bhmf0n4o.mjs} +2 -2
- package/dist/{compose-Dn0oAgQ0.mjs.map → compose-Bhmf0n4o.mjs.map} +1 -1
- package/dist/{compose-BvrhDwJ6.cjs → compose-CvpU6ooi.cjs} +2 -2
- package/dist/{compose-BvrhDwJ6.cjs.map → compose-CvpU6ooi.cjs.map} +1 -1
- package/dist/deploy/public.cjs +5 -5
- package/dist/deploy/public.mjs +5 -5
- package/dist/{deploy-DbBGo3a6.cjs → deploy-CuHasEA4.cjs} +3 -3
- package/dist/{deploy-DbBGo3a6.cjs.map → deploy-CuHasEA4.cjs.map} +1 -1
- package/dist/{deploy-BaERRh0Q.mjs → deploy-QNtx_eWR.mjs} +3 -3
- package/dist/{deploy-BaERRh0Q.mjs.map → deploy-QNtx_eWR.mjs.map} +1 -1
- package/dist/{dokploy-CMmD_ddX.mjs → dokploy-CYcMLh9-.mjs} +2 -2
- package/dist/{dokploy-CMmD_ddX.mjs.map → dokploy-CYcMLh9-.mjs.map} +1 -1
- package/dist/{dokploy-DwAaKA9B.cjs → dokploy-DIowwyIB.cjs} +2 -2
- package/dist/{dokploy-DwAaKA9B.cjs.map → dokploy-DIowwyIB.cjs.map} +1 -1
- package/dist/{encryption-BQmhq9_y.mjs → encryption-BrEef7Jk.mjs} +2 -2
- package/dist/{encryption-BQmhq9_y.mjs.map → encryption-BrEef7Jk.mjs.map} +1 -1
- package/dist/{encryption-BrN_9_CM.cjs → encryption-CjYdUb2s.cjs} +2 -2
- package/dist/{encryption-BrN_9_CM.cjs.map → encryption-CjYdUb2s.cjs.map} +1 -1
- package/dist/{engine-DILocOOH.mjs → engine-2h4k5ICq.mjs} +2 -2
- package/dist/{engine-DILocOOH.mjs.map → engine-2h4k5ICq.mjs.map} +1 -1
- package/dist/{engine-DgHoFBMw.cjs → engine-BhJ7ZP9K.cjs} +2 -2
- package/dist/{engine-DgHoFBMw.cjs.map → engine-BhJ7ZP9K.cjs.map} +1 -1
- package/dist/{github-Bf7pz6AV.cjs → github-B5Bw4HIu.cjs} +2 -2
- package/dist/{github-Bf7pz6AV.cjs.map → github-B5Bw4HIu.cjs.map} +1 -1
- package/dist/{github-xzg99wz8.mjs → github-BCDF6xVH.mjs} +2 -2
- package/dist/{github-xzg99wz8.mjs.map → github-BCDF6xVH.mjs.map} +1 -1
- package/dist/index.cjs +89 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +89 -46
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-DPF7ZF8M.cjs → migrate-CGaancHY.cjs} +2 -2
- package/dist/{migrate-DPF7ZF8M.cjs.map → migrate-CGaancHY.cjs.map} +1 -1
- package/dist/{migrate-CpmO5qnl.mjs → migrate-DWZz9kah.mjs} +2 -2
- package/dist/{migrate-CpmO5qnl.mjs.map → migrate-DWZz9kah.mjs.map} +1 -1
- package/dist/{migrate-CKLJ73OO.mjs → migrate-DbtcuOr_.mjs} +2 -2
- package/dist/{migrate-CKLJ73OO.mjs.map → migrate-DbtcuOr_.mjs.map} +1 -1
- package/dist/{migrate-7xayVtzL.cjs → migrate-q2YYLJLE.cjs} +2 -2
- package/dist/{migrate-7xayVtzL.cjs.map → migrate-q2YYLJLE.cjs.map} +1 -1
- package/dist/{resolve-dlKPFNgv.cjs → resolve-Cns0v6dN.cjs} +3 -3
- package/dist/{resolve-dlKPFNgv.cjs.map → resolve-Cns0v6dN.cjs.map} +1 -1
- package/dist/{resolve-Dv_weZoh.mjs → resolve-DNg0icnh.mjs} +3 -3
- package/dist/{resolve-Dv_weZoh.mjs.map → resolve-DNg0icnh.mjs.map} +1 -1
- package/dist/{rollback-DpSU2DsD.mjs → rollback-CFrNLmxs.mjs} +3 -3
- package/dist/{rollback-DpSU2DsD.mjs.map → rollback-CFrNLmxs.mjs.map} +1 -1
- package/dist/{rollback-65VVIdBM.cjs → rollback-UIjS25F1.cjs} +3 -3
- package/dist/{rollback-65VVIdBM.cjs.map → rollback-UIjS25F1.cjs.map} +1 -1
- package/dist/{seeds-CN6tB-va.cjs → seeds-CkIPFGNO.cjs} +65 -13
- package/dist/seeds-CkIPFGNO.cjs.map +1 -0
- package/dist/{seeds-perzdN81.mjs → seeds-odfgSCmu.mjs} +65 -13
- package/dist/seeds-odfgSCmu.mjs.map +1 -0
- package/dist/target/public.cjs +1 -1
- package/dist/target/public.mjs +1 -1
- package/package.json +15 -15
- package/dist/seeds-CN6tB-va.cjs.map +0 -1
- package/dist/seeds-perzdN81.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rollback-
|
|
1
|
+
{"version":3,"file":"rollback-CFrNLmxs.mjs","names":[],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport { createStateStore } from '../../deploy/StateStore';\nimport {\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(store, input.stage, () =>\n\t\t\t\tcreateEmptyState(input.stage, '', ''),\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":"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"}
|
|
@@ -3,9 +3,9 @@ const require_credentials = require("./credentials-BKfIugu2.cjs");
|
|
|
3
3
|
const require_sandbox = require("./sandbox-CL--ZDui.cjs");
|
|
4
4
|
const require_workspace = require("./workspace-CwW3Gkru.cjs");
|
|
5
5
|
const require_config = require("./config.cjs");
|
|
6
|
-
const require_seeds = require("./seeds-
|
|
6
|
+
const require_seeds = require("./seeds-CkIPFGNO.cjs");
|
|
7
7
|
const require_local = require("./local-BjxDfPvy.cjs");
|
|
8
|
-
const require_engine = require("./engine-
|
|
8
|
+
const require_engine = require("./engine-BhJ7ZP9K.cjs");
|
|
9
9
|
let node_path = require("node:path");
|
|
10
10
|
//#region src/target/dokploy/rollback.ts
|
|
11
11
|
/**
|
|
@@ -158,4 +158,4 @@ Object.defineProperty(exports, "rollback_exports", {
|
|
|
158
158
|
}
|
|
159
159
|
});
|
|
160
160
|
|
|
161
|
-
//# sourceMappingURL=rollback-
|
|
161
|
+
//# sourceMappingURL=rollback-UIjS25F1.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rollback-
|
|
1
|
+
{"version":3,"file":"rollback-UIjS25F1.cjs","names":["storedCredentials","LocalSandbox","findWorkspaceRoot","resolve","withSandbox","loadWorkspaceConfig","createStateStore","DeployJournal","createEmptyState","dokployApi","verifySettings","restoreImage"],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport { createStateStore } from '../../deploy/StateStore';\nimport {\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(store, input.stage, () =>\n\t\t\t\tcreateEmptyState(input.stage, '', ''),\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DA,IAAa,mBAAb,cAAsC,MAAM;CAEjC;CAEA;CAHV,YACC,OAEA,MACC;EACD,MACC,oDAAoD,KAAK,KAAK,IAAI,KAAK,8BAA8B,mCACnE,MAAM,YACzC;EAPS,KAAA,QAAA;EAEA,KAAA,OAAA;EAMT,KAAK,OAAO;CACb;AACD;;AAGA,IAAa,oBAAb,cAAuC,MAAM;CAElC;CACA;CAFV,YACC,OACA,KACC;EACD,MACC,IAAI,IAAI,+BAA+B,MAAM,oIAE9C;EANS,KAAA,QAAA;EACA,KAAA,MAAA;EAMT,KAAK,OAAO;CACb;AACD;;AAGA,IAAa,qBAAb,cAAwC,MAAM;CACxB;CAArB,YAAY,OAAwB;EACnC,MACC,IAAI,MAAM,6JAEX;EAJoB,KAAA,QAAA;EAKpB,KAAK,OAAO;CACb;AACD;;;;;AAMA,eAAsB,cACrB,OACwB;CACxB,MAAM,SAAS,MAAM,UAAU,IAAI,gBAAgB,CAAC,CAAC;CACrD,MAAM,MAAM,MAAM,cAAc,CAAC;CACjC,MAAM,cAAc,MAAM,eAAeA,oBAAAA,kBAAkB;CAC3D,MAAM,UACL,MAAM,WACN,IAAIC,cAAAA,aAAa,EAAE,MAAMC,eAAAA,mBAAAA,GAAkBC,UAAAA,QAAAA,CAAQ,MAAM,GAAG,CAAC,EAAE,CAAC;CAEjE,OAAOC,gBAAAA,YAAY,SAAS,YAAY;EACvC,MAAM,EAAE,cAAc,MAAMC,eAAAA,qBAAAA,GAAoBF,UAAAA,QAAAA,CAAQ,MAAM,GAAG,GAAG,EACnE,QACD,CAAC;EACD,kBAAA,oBAAoB,UAAU,QAAQ,MAAM,KAAK;EAEjD,MAAM,QAAQ,MAAMG,cAAAA,iBAAiB;GACpC,QAAQ,UAAU;GAClB,eAAe,UAAU;GACzB,eAAe,UAAU;EAC1B,CAAC;EACD,IAAI,CAAE,MAAM,MAAM,KAAK,MAAM,KAAK,GACjC,MAAM,IAAI,mBAAmB,MAAM,KAAK;EAGzC,MAAM,OAAO,MAAM,MAAM,KAAK,MAAM,OAAO,EAAE,WAAW,WAAW,CAAC;EACpE,IAAI;GACH,MAAM,UAAU,MAAMC,cAAAA,cAAc,KAAK,OAAO,MAAM,aACrDC,cAAAA,iBAAiB,MAAM,OAAO,IAAI,EAAE,CACrC;GACA,MAAM,EAAE,UAAU;GAClB,MAAM,WAAW,MAAM,YAAY,CAAC;GACpC,MAAM,aAAa,OAAO,KAAK,QAAQ,CAAC,CAAC,QACvC,QAAQ,SAAS,IAAI,CAAE,QACzB;GAEA,IAAI;GACJ,IAAI,MAAM,QAAQ;IACjB,OAAO;IACP,IAAI,KAAK,WAAW,GACnB,MAAM,IAAI,iBAAiB,MAAM,OAAO,UAAU;GAEpD,OAAO,IAAI,MAAM,KAAK;IACrB,IAAI,CAAC,SAAS,MAAM,IAAI,EAAE,UACzB,MAAM,IAAI,kBAAkB,MAAM,OAAO,MAAM,GAAG;IAEnD,OAAO,CAAC,MAAM,GAAG;GAClB,OACC,MAAM,IAAI,iBAAiB,MAAM,OAAO,UAAU;GAGnD,MAAM,EAAE,QAAQ,MAAMC,eAAAA,WAAW,WAAW;IAAE;IAAa;GAAO,CAAC;GACnE,MAAM,SAASC,eAAAA,eAAe,UAAU,OAAO,SAAS,MAAM;GAC9D,MAAM,SAAuB,CAAC;GAE9B,KAAK,MAAM,OAAO,MAAM;IACvB,OAAO,eAAe;IACtB,MAAM,EAAE,SAAS,aAAa,SAAS;IACvC,MAAM,gBAAgB,MAAM,aAAa;IACzC,IAAI,CAAC,YAAY,CAAC,eACjB,MAAM,IAAI,kBAAkB,MAAM,OAAO,GAAG;IAG7C,IAAI,KAAK,IAAI,IAAI,QAAQ,IAAI,KAAK,SAAS,KAAK;IAChD,MAAMC,eAAAA,aAAa,KAAK;KACvB;KACA,OAAO;KACP,YAAY,MAAM;KAClB;KACA;IACD,CAAC;IACD,cAAA,eAAe,OAAO,KAAK,QAAQ;IACnC,MAAM,QAAQ,KAAK;IACnB,IAAI,QAAQ,IAAI,cAAc,SAAS,KAAK;IAC5C,OAAO,KAAK;KAAE;KAAK,MAAM;KAAS,IAAI;IAAS,CAAC;GACjD;GAEA,OAAO;EACR,UAAU;GACT,MAAM,KAAK,QAAQ;EACpB;CACD,CAAC;AACF"}
|
|
@@ -6,7 +6,7 @@ const require_workspace = require("./workspace-CwW3Gkru.cjs");
|
|
|
6
6
|
const require_config = require("./config.cjs");
|
|
7
7
|
const require_EndpointGenerator = require("./EndpointGenerator-CwLjBCFE.cjs");
|
|
8
8
|
const require_SubscriberGenerator = require("./SubscriberGenerator-BVn7cQ-2.cjs");
|
|
9
|
-
const require_resolve = require("./resolve-
|
|
9
|
+
const require_resolve = require("./resolve-Cns0v6dN.cjs");
|
|
10
10
|
let node_path = require("node:path");
|
|
11
11
|
let node_fs = require("node:fs");
|
|
12
12
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -4088,8 +4088,9 @@ function carrierClient(port, credentials) {
|
|
|
4088
4088
|
* what a developer runs by hand when something is wrong, so the two cannot
|
|
4089
4089
|
* disagree, and it keeps Docker out of this package's dependencies.
|
|
4090
4090
|
*
|
|
4091
|
-
* Every call is scoped to the generated compose file. Nothing here
|
|
4092
|
-
* container this project did not generate
|
|
4091
|
+
* Every call that acts is scoped to the generated compose file. Nothing here
|
|
4092
|
+
* can touch a container this project did not generate; `publisher` only reads
|
|
4093
|
+
* who holds a port.
|
|
4093
4094
|
*/
|
|
4094
4095
|
const run = (0, node_util.promisify)(node_child_process.execFile);
|
|
4095
4096
|
/**
|
|
@@ -4147,6 +4148,20 @@ const dockerCli = {
|
|
|
4147
4148
|
return;
|
|
4148
4149
|
}
|
|
4149
4150
|
},
|
|
4151
|
+
async publisher(port) {
|
|
4152
|
+
try {
|
|
4153
|
+
const { stdout } = await run("docker", [
|
|
4154
|
+
"ps",
|
|
4155
|
+
"--filter",
|
|
4156
|
+
`publish=${port}`,
|
|
4157
|
+
"--format",
|
|
4158
|
+
"{{.Label \"com.docker.compose.project\"}}"
|
|
4159
|
+
]);
|
|
4160
|
+
return stdout.trim().split("\n")[0] || void 0;
|
|
4161
|
+
} catch {
|
|
4162
|
+
return;
|
|
4163
|
+
}
|
|
4164
|
+
},
|
|
4150
4165
|
async up(composePath, services, options = {}) {
|
|
4151
4166
|
const args = [
|
|
4152
4167
|
"compose",
|
|
@@ -4622,6 +4637,28 @@ function keptPorts(saved = {}, observed = {}) {
|
|
|
4622
4637
|
}
|
|
4623
4638
|
return kept;
|
|
4624
4639
|
}
|
|
4640
|
+
/**
|
|
4641
|
+
* The kept ports, among those the plan publishes, that something other than
|
|
4642
|
+
* this project now holds.
|
|
4643
|
+
*
|
|
4644
|
+
* A saved port is only a memory of a free one. Another checkout's stack — the
|
|
4645
|
+
* same project name hashes to the same block — can bind it in the meantime,
|
|
4646
|
+
* and keeping it unchecked fails `docker compose up` with "port is already
|
|
4647
|
+
* allocated". An observed port is ours by definition and is never asked
|
|
4648
|
+
* about; neither is a saved one the plan no longer publishes, which is only
|
|
4649
|
+
* kept for when it returns.
|
|
4650
|
+
*/
|
|
4651
|
+
async function heldElsewhere(kept, keys, observed, probe, ours) {
|
|
4652
|
+
const held = [];
|
|
4653
|
+
for (const key of [...keys].sort()) {
|
|
4654
|
+
const port = kept[key];
|
|
4655
|
+
if (port === void 0 || key in observed) continue;
|
|
4656
|
+
if (await probe(port)) continue;
|
|
4657
|
+
if (await ours(port)) continue;
|
|
4658
|
+
held.push(key);
|
|
4659
|
+
}
|
|
4660
|
+
return held;
|
|
4661
|
+
}
|
|
4625
4662
|
/** The window was exhausted. */
|
|
4626
4663
|
var NoPortAvailable = class extends Error {
|
|
4627
4664
|
/** Where the search started. */
|
|
@@ -4655,18 +4692,22 @@ async function nextFree(from, taken, probe) {
|
|
|
4655
4692
|
* Binds rather than connects: a refused connection says nothing about whether
|
|
4656
4693
|
* the port can be *published*, which is the question Docker will ask. Binds on
|
|
4657
4694
|
* `0.0.0.0` for the same reason — a port free on loopback can still be taken on
|
|
4658
|
-
* the address Docker publishes to.
|
|
4695
|
+
* the address Docker publishes to — and then on `127.0.0.1`, because on macOS
|
|
4696
|
+
* a wildcard bind succeeds beside a listener on loopback alone.
|
|
4659
4697
|
*
|
|
4660
4698
|
* Inherently racy, and that is acceptable: Docker failing to bind stays the real
|
|
4661
4699
|
* check. This exists so the common case surfaces as a message at reconcile
|
|
4662
4700
|
* rather than as a connection failure ten minutes later.
|
|
4663
4701
|
*/
|
|
4664
|
-
function isPortFree(port) {
|
|
4702
|
+
async function isPortFree(port) {
|
|
4703
|
+
return await canBind(port, "0.0.0.0") && await canBind(port, "127.0.0.1");
|
|
4704
|
+
}
|
|
4705
|
+
function canBind(port, host) {
|
|
4665
4706
|
return new Promise((resolve) => {
|
|
4666
4707
|
const server = (0, node_net.createServer)();
|
|
4667
4708
|
server.once("error", () => resolve(false));
|
|
4668
4709
|
server.once("listening", () => server.close(() => resolve(true)));
|
|
4669
|
-
server.listen(port,
|
|
4710
|
+
server.listen(port, host);
|
|
4670
4711
|
});
|
|
4671
4712
|
}
|
|
4672
4713
|
//#endregion
|
|
@@ -5156,7 +5197,16 @@ async function reconcile(options) {
|
|
|
5156
5197
|
const running = exports ? plan.containers : plan.containers.filter((c) => c !== TELEMETRY_CONTAINER);
|
|
5157
5198
|
const composePath = (0, node_path.join)(root, COMPOSE_PATH);
|
|
5158
5199
|
const observed = await observedPorts(docker, composePath, plan.containers, plan.fakes);
|
|
5159
|
-
const
|
|
5200
|
+
const keys = portKeys(plan.containers, plan.fakes);
|
|
5201
|
+
const kept = keptPorts(options.saved, observed);
|
|
5202
|
+
const composeProject = process.env.COMPOSE_PROJECT_NAME || project;
|
|
5203
|
+
const held = await heldElsewhere(kept, keys, observed, probe, async (port) => await docker.publisher?.(port) === composeProject);
|
|
5204
|
+
const ports = await allocate(project, keys, Object.fromEntries(Object.entries(kept).filter(([key]) => !held.includes(key))), probe);
|
|
5205
|
+
const moved = held.map((key) => ({
|
|
5206
|
+
key,
|
|
5207
|
+
from: kept[key],
|
|
5208
|
+
to: ports[key]
|
|
5209
|
+
}));
|
|
5160
5210
|
const compose = composeFor(plan, {
|
|
5161
5211
|
project,
|
|
5162
5212
|
ports,
|
|
@@ -5193,6 +5243,7 @@ async function reconcile(options) {
|
|
|
5193
5243
|
plan,
|
|
5194
5244
|
compose,
|
|
5195
5245
|
ports,
|
|
5246
|
+
moved,
|
|
5196
5247
|
services,
|
|
5197
5248
|
env: envWith(options.credentials),
|
|
5198
5249
|
credentials: options.credentials,
|
|
@@ -5781,6 +5832,7 @@ async function reconcileWorkspace(workspace, options) {
|
|
|
5781
5832
|
...options.progress ? { progress: options.progress } : {}
|
|
5782
5833
|
});
|
|
5783
5834
|
await savePortState(workspace.root, { ...result.ports });
|
|
5835
|
+
for (const { key, from, to } of result.moved) console.log(`⚠️ Port ${from} (${key}) is held by another process; moved to ${to}.`);
|
|
5784
5836
|
if (result.credentials !== credentials) await saveLocalCredentials(workspace, result.credentials);
|
|
5785
5837
|
for (const outcome of result.logins) if (outcome.notice) console.log(outcome.notice);
|
|
5786
5838
|
return {
|
|
@@ -7218,17 +7270,17 @@ function isStateStore(value) {
|
|
|
7218
7270
|
async function createStateStore(options) {
|
|
7219
7271
|
const { config, workspaceRoot, workspaceName } = options;
|
|
7220
7272
|
if (!config || config.provider === "local") {
|
|
7221
|
-
const { LocalStateStore } = await Promise.resolve().then(() => require("./LocalStateStore-
|
|
7273
|
+
const { LocalStateStore } = await Promise.resolve().then(() => require("./LocalStateStore-BBeTlRTH.cjs")).then((n) => n.LocalStateStore_exports);
|
|
7222
7274
|
return new LocalStateStore(workspaceRoot);
|
|
7223
7275
|
}
|
|
7224
7276
|
if (isStateStore(config.provider)) return config.provider;
|
|
7225
7277
|
if (isStateProvider(config.provider)) {
|
|
7226
|
-
const { LegacyStateStore } = await Promise.resolve().then(() => require("./LegacyStateStore-
|
|
7278
|
+
const { LegacyStateStore } = await Promise.resolve().then(() => require("./LegacyStateStore-DXmNA7hy.cjs"));
|
|
7227
7279
|
return new LegacyStateStore(config.provider, { warn: options.warn });
|
|
7228
7280
|
}
|
|
7229
7281
|
if (config.provider === "ssm") {
|
|
7230
7282
|
if (!workspaceName) throw new StateStoreNeedsWorkspaceName("ssm");
|
|
7231
|
-
const { SSMStateStore } = await Promise.resolve().then(() => require("./SSMStateStore-
|
|
7283
|
+
const { SSMStateStore } = await Promise.resolve().then(() => require("./SSMStateStore-DoZE1Wi1.cjs"));
|
|
7232
7284
|
const ssm = config;
|
|
7233
7285
|
return SSMStateStore.create({
|
|
7234
7286
|
workspaceName,
|
|
@@ -7238,7 +7290,7 @@ async function createStateStore(options) {
|
|
|
7238
7290
|
}
|
|
7239
7291
|
if (config.provider === "s3") {
|
|
7240
7292
|
if (!workspaceName) throw new StateStoreNeedsWorkspaceName("s3");
|
|
7241
|
-
const { S3StateStore } = await Promise.resolve().then(() => require("./S3StateStore-
|
|
7293
|
+
const { S3StateStore } = await Promise.resolve().then(() => require("./S3StateStore-Br8VMY22.cjs"));
|
|
7242
7294
|
const s3 = config;
|
|
7243
7295
|
return S3StateStore.create({
|
|
7244
7296
|
workspaceName,
|
|
@@ -7286,7 +7338,7 @@ async function createDnsProvider(options) {
|
|
|
7286
7338
|
});
|
|
7287
7339
|
}
|
|
7288
7340
|
if (provider === "godaddy") {
|
|
7289
|
-
const { GoDaddyProvider } = await Promise.resolve().then(() => require("./GoDaddyProvider-
|
|
7341
|
+
const { GoDaddyProvider } = await Promise.resolve().then(() => require("./GoDaddyProvider-DqZ1qD_F.cjs"));
|
|
7290
7342
|
return new GoDaddyProvider(options.godaddy ?? {});
|
|
7291
7343
|
}
|
|
7292
7344
|
if (provider === "cloudflare") throw new DnsProviderNotImplemented("cloudflare");
|
|
@@ -10505,4 +10557,4 @@ Object.defineProperty(exports, "workspace_exports", {
|
|
|
10505
10557
|
}
|
|
10506
10558
|
});
|
|
10507
10559
|
|
|
10508
|
-
//# sourceMappingURL=seeds-
|
|
10560
|
+
//# sourceMappingURL=seeds-CkIPFGNO.cjs.map
|