rampway 0.2.1

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.
Files changed (143) hide show
  1. package/README.md +183 -0
  2. package/build/src/cli.d.ts +3 -0
  3. package/build/src/cli.d.ts.map +1 -0
  4. package/build/src/cli.js +104 -0
  5. package/build/src/cli.js.map +1 -0
  6. package/build/src/commands/context.d.ts +12 -0
  7. package/build/src/commands/context.d.ts.map +1 -0
  8. package/build/src/commands/context.js +16 -0
  9. package/build/src/commands/context.js.map +1 -0
  10. package/build/src/commands/deploy.d.ts +6 -0
  11. package/build/src/commands/deploy.d.ts.map +1 -0
  12. package/build/src/commands/deploy.js +14 -0
  13. package/build/src/commands/deploy.js.map +1 -0
  14. package/build/src/commands/doctor.d.ts +14 -0
  15. package/build/src/commands/doctor.d.ts.map +1 -0
  16. package/build/src/commands/doctor.js +54 -0
  17. package/build/src/commands/doctor.js.map +1 -0
  18. package/build/src/commands/init.d.ts +8 -0
  19. package/build/src/commands/init.d.ts.map +1 -0
  20. package/build/src/commands/init.js +42 -0
  21. package/build/src/commands/init.js.map +1 -0
  22. package/build/src/commands/plan.d.ts +6 -0
  23. package/build/src/commands/plan.d.ts.map +1 -0
  24. package/build/src/commands/plan.js +24 -0
  25. package/build/src/commands/plan.js.map +1 -0
  26. package/build/src/commands/releases.d.ts +27 -0
  27. package/build/src/commands/releases.d.ts.map +1 -0
  28. package/build/src/commands/releases.js +91 -0
  29. package/build/src/commands/releases.js.map +1 -0
  30. package/build/src/commands/rollback.d.ts +6 -0
  31. package/build/src/commands/rollback.d.ts.map +1 -0
  32. package/build/src/commands/rollback.js +12 -0
  33. package/build/src/commands/rollback.js.map +1 -0
  34. package/build/src/commands/rollbridge.d.ts +21 -0
  35. package/build/src/commands/rollbridge.d.ts.map +1 -0
  36. package/build/src/commands/rollbridge.js +69 -0
  37. package/build/src/commands/rollbridge.js.map +1 -0
  38. package/build/src/commands/validate.d.ts +6 -0
  39. package/build/src/commands/validate.d.ts.map +1 -0
  40. package/build/src/commands/validate.js +12 -0
  41. package/build/src/commands/validate.js.map +1 -0
  42. package/build/src/config/load-config.d.ts +10 -0
  43. package/build/src/config/load-config.d.ts.map +1 -0
  44. package/build/src/config/load-config.js +71 -0
  45. package/build/src/config/load-config.js.map +1 -0
  46. package/build/src/config/validate-config.d.ts +7 -0
  47. package/build/src/config/validate-config.d.ts.map +1 -0
  48. package/build/src/config/validate-config.js +117 -0
  49. package/build/src/config/validate-config.js.map +1 -0
  50. package/build/src/core/deploy-runner.d.ts +46 -0
  51. package/build/src/core/deploy-runner.d.ts.map +1 -0
  52. package/build/src/core/deploy-runner.js +221 -0
  53. package/build/src/core/deploy-runner.js.map +1 -0
  54. package/build/src/core/expo-web-artifacts.d.ts +10 -0
  55. package/build/src/core/expo-web-artifacts.d.ts.map +1 -0
  56. package/build/src/core/expo-web-artifacts.js +16 -0
  57. package/build/src/core/expo-web-artifacts.js.map +1 -0
  58. package/build/src/core/git-source.d.ts +22 -0
  59. package/build/src/core/git-source.d.ts.map +1 -0
  60. package/build/src/core/git-source.js +63 -0
  61. package/build/src/core/git-source.js.map +1 -0
  62. package/build/src/core/health-checks.d.ts +8 -0
  63. package/build/src/core/health-checks.d.ts.map +1 -0
  64. package/build/src/core/health-checks.js +19 -0
  65. package/build/src/core/health-checks.js.map +1 -0
  66. package/build/src/core/hooks.d.ts +12 -0
  67. package/build/src/core/hooks.d.ts.map +1 -0
  68. package/build/src/core/hooks.js +26 -0
  69. package/build/src/core/hooks.js.map +1 -0
  70. package/build/src/core/locks.d.ts +16 -0
  71. package/build/src/core/locks.d.ts.map +1 -0
  72. package/build/src/core/locks.js +32 -0
  73. package/build/src/core/locks.js.map +1 -0
  74. package/build/src/core/node-package-tasks.d.ts +26 -0
  75. package/build/src/core/node-package-tasks.d.ts.map +1 -0
  76. package/build/src/core/node-package-tasks.js +143 -0
  77. package/build/src/core/node-package-tasks.js.map +1 -0
  78. package/build/src/core/path-change-gate.d.ts +15 -0
  79. package/build/src/core/path-change-gate.d.ts.map +1 -0
  80. package/build/src/core/path-change-gate.js +95 -0
  81. package/build/src/core/path-change-gate.js.map +1 -0
  82. package/build/src/core/paths.d.ts +7 -0
  83. package/build/src/core/paths.d.ts.map +1 -0
  84. package/build/src/core/paths.js +20 -0
  85. package/build/src/core/paths.js.map +1 -0
  86. package/build/src/core/redaction.d.ts +22 -0
  87. package/build/src/core/redaction.d.ts.map +1 -0
  88. package/build/src/core/redaction.js +39 -0
  89. package/build/src/core/redaction.js.map +1 -0
  90. package/build/src/core/release-id.d.ts +6 -0
  91. package/build/src/core/release-id.d.ts.map +1 -0
  92. package/build/src/core/release-id.js +20 -0
  93. package/build/src/core/release-id.js.map +1 -0
  94. package/build/src/core/release-manager.d.ts +49 -0
  95. package/build/src/core/release-manager.d.ts.map +1 -0
  96. package/build/src/core/release-manager.js +115 -0
  97. package/build/src/core/release-manager.js.map +1 -0
  98. package/build/src/core/task-runner.d.ts +38 -0
  99. package/build/src/core/task-runner.d.ts.map +1 -0
  100. package/build/src/core/task-runner.js +102 -0
  101. package/build/src/core/task-runner.js.map +1 -0
  102. package/build/src/core/velocious-migrate.d.ts +11 -0
  103. package/build/src/core/velocious-migrate.d.ts.map +1 -0
  104. package/build/src/core/velocious-migrate.js +20 -0
  105. package/build/src/core/velocious-migrate.js.map +1 -0
  106. package/build/src/runtimes/index.d.ts +56 -0
  107. package/build/src/runtimes/index.d.ts.map +1 -0
  108. package/build/src/runtimes/index.js +132 -0
  109. package/build/src/runtimes/index.js.map +1 -0
  110. package/build/src/runtimes/none-runtime.d.ts +22 -0
  111. package/build/src/runtimes/none-runtime.d.ts.map +1 -0
  112. package/build/src/runtimes/none-runtime.js +23 -0
  113. package/build/src/runtimes/none-runtime.js.map +1 -0
  114. package/build/src/runtimes/rollbridge-runtime.d.ts +137 -0
  115. package/build/src/runtimes/rollbridge-runtime.d.ts.map +1 -0
  116. package/build/src/runtimes/rollbridge-runtime.js +224 -0
  117. package/build/src/runtimes/rollbridge-runtime.js.map +1 -0
  118. package/build/src/tasks.d.ts +5 -0
  119. package/build/src/tasks.d.ts.map +1 -0
  120. package/build/src/tasks.js +5 -0
  121. package/build/src/tasks.js.map +1 -0
  122. package/build/src/test-helpers.d.ts +25 -0
  123. package/build/src/test-helpers.d.ts.map +1 -0
  124. package/build/src/test-helpers.js +40 -0
  125. package/build/src/test-helpers.js.map +1 -0
  126. package/build/src/transports/local-transport.d.ts +67 -0
  127. package/build/src/transports/local-transport.d.ts.map +1 -0
  128. package/build/src/transports/local-transport.js +121 -0
  129. package/build/src/transports/local-transport.js.map +1 -0
  130. package/build/src/transports/ssh-transport.d.ts +189 -0
  131. package/build/src/transports/ssh-transport.d.ts.map +1 -0
  132. package/build/src/transports/ssh-transport.js +369 -0
  133. package/build/src/transports/ssh-transport.js.map +1 -0
  134. package/build/src/types.d.ts +290 -0
  135. package/build/src/types.d.ts.map +1 -0
  136. package/build/src/types.js +8 -0
  137. package/build/src/types.js.map +1 -0
  138. package/docs/config-reference.md +264 -0
  139. package/docs/migration-from-capistrano.md +167 -0
  140. package/docs/roadmap.md +27 -0
  141. package/examples/local/rampway.config.mjs +20 -0
  142. package/examples/monorepo/rampway.config.mjs +73 -0
  143. package/package.json +92 -0
package/README.md ADDED
@@ -0,0 +1,183 @@
1
+ # Rampway Deploy
2
+
3
+ Rampway is a JavaScript-native release-directory deployment tool: the useful parts of Capistrano, built for Node/Expo/Velocious projects and designed to hand runtime changes to Rollbridge.
4
+
5
+ Package: `rampway`
6
+ CLI: `rampway`
7
+ Config: `rampway.config.mjs`
8
+
9
+ ## Current MVP
10
+
11
+ This initial scaffold includes:
12
+
13
+ - ESM config loading and validation
14
+ - deterministic deploy plans
15
+ - local release-directory deploys for tests/dogfooding
16
+ - linked file/dir checks and symlink creation
17
+ - deploy lock acquisition/release
18
+ - release metadata (`REVISION`, `TRESTLE_RELEASE.json`)
19
+ - atomic `current` symlink publishing
20
+ - safe cleanup
21
+ - rollback to previous or selected release
22
+ - JSONL deploy reports at `shared/log/rampway-deployments.jsonl`
23
+ - secret redaction helpers
24
+ - basic runtime adapter interface with `none` and Rollbridge validate/deploy/status/logs/recover helpers
25
+
26
+ SSH transport command execution supports both local-copy and remote-git deployments. `remote-git` prepares each release checkout on the target host, so the target needs `git` and access to the configured repository.
27
+
28
+ Full config reference: [docs/config-reference.md](docs/config-reference.md)
29
+ Migrating from Capistrano: [docs/migration-from-capistrano.md](docs/migration-from-capistrano.md)
30
+
31
+ ## Commands
32
+
33
+ ```bash
34
+ rampway init
35
+ rampway validate production
36
+ rampway plan production
37
+ rampway plan production --json
38
+ rampway deploy production
39
+ rampway status production
40
+ rampway releases production
41
+ rampway releases production --json
42
+ rampway rollback production
43
+ rampway doctor production
44
+ rampway doctor production --json
45
+
46
+ # Rollbridge runtime helpers for the current release
47
+ rampway rollbridge-validate production
48
+ rampway rollbridge-status production
49
+ rampway rollbridge-logs production
50
+ rampway rollbridge-recover production --yes
51
+ ```
52
+
53
+ For local development without installing the package globally:
54
+
55
+ ```bash
56
+ node src/cli.js init
57
+ node src/cli.js validate --config examples/local/rampway.config.mjs local
58
+ node src/cli.js plan --config examples/local/rampway.config.mjs local
59
+ node src/cli.js deploy --config examples/local/rampway.config.mjs local --yes
60
+
61
+ # Monorepo example with backend + frontend stages
62
+ node src/cli.js validate --config examples/monorepo/rampway.config.mjs local
63
+ node src/cli.js plan --config examples/monorepo/rampway.config.mjs local
64
+ ```
65
+
66
+ ## Config example
67
+
68
+ Reusable Node package install helpers can be imported from `rampway/tasks` when writing `rampway.config.mjs`:
69
+
70
+ ```js
71
+ import {npmInstall, pnpmInstall, checkExpoWebArtifacts, velociousMigrate, onlyIfChanged} from "rampway/tasks"
72
+ ```
73
+
74
+ ```js
75
+ // rampway.config.mjs
76
+ export default {
77
+ application: "routergeist",
78
+ stages: {
79
+ production: {
80
+ repo: "git@github.com:kaspernj/routergeist.git",
81
+ branch: "master",
82
+ deployTo: "/home/dev/routergeist",
83
+ strategy: "remote-git",
84
+ transport: {type: "ssh"},
85
+ hosts: [{host: "server.example", user: "dev", roles: ["app", "web", "db"]}],
86
+ keepReleases: 5,
87
+ linkedFiles: [
88
+ {path: "backend/src/config/secrets.js", required: true}
89
+ ],
90
+ linkedDirs: ["log", "tmp/pids", "tmp/cache", "storage"],
91
+ tasks: {
92
+ install: [
93
+ npmInstall({cwd: "backend", production: true}),
94
+ pnpmInstall({cwd: "app", production: true})
95
+ ],
96
+ migrate: [
97
+ velociousMigrate({cwd: "backend", env: {NODE_ENV: "production"}})
98
+ ],
99
+ build: [
100
+ "cd app && npm run web:export",
101
+ checkExpoWebArtifacts({dir: "app/dist"}),
102
+ {command: "npm run assets:verify", cwd: "app", env: {NODE_ENV: "production"}}
103
+ ]
104
+ },
105
+ runtime: {
106
+ type: "rollbridge",
107
+ command: "npx rollbridge",
108
+ packageDir: "backend",
109
+ config: "config/rollbridge.production.mjs",
110
+ healthPath: "/health",
111
+ daemonLogPath: "/home/dev/routergeist/shared/log/rollbridge.log",
112
+ daemonPidPath: "/home/dev/routergeist/shared/tmp/pids/rollbridge.pid",
113
+ socketPath: "/tmp/rollbridge-routergeist.sock",
114
+ versionPath: "/home/dev/routergeist/shared/tmp/rollbridge-version"
115
+ }
116
+ }
117
+ }
118
+ }
119
+ ```
120
+
121
+ `npmInstall`, `pnpmInstall`, `yarnInstall`, `bunInstall`, and `nodePackageInstall` return normal task entries with the right install command for common Node package managers. They accept `cwd`, `env`, `optional`, `production`, and lockfile options such as `clean: false` for `npm install` instead of `npm ci`, or `frozenLockfile: false` for package managers that need explicit CI lockfile opt-outs (`--no-frozen-lockfile` for pnpm and `--no-immutable` for Yarn). Yarn production installs are intentionally not guessed; use a custom task command when that project needs a specific Yarn workspace/plugin flow.
122
+
123
+ `checkExpoWebArtifacts` returns a task entry that fails if the Expo web build directory does not contain an `index.html`. It accepts `dir` (default `"dist"`), `cwd`, and `optional`.
124
+
125
+ `velociousMigrate` returns a task entry that runs `npx velocious db:migrate`. It accepts `command` (override), `cwd`, `env`, and `optional`.
126
+
127
+ `onlyIfChanged(paths, task)` wraps a task entry so it is skipped when none of the given relative paths have changed since the previous deploy. On the first deploy (no previous release), all tasks run regardless.
128
+
129
+ Task entries can be strings or objects.
130
+
131
+ - `command` — required shell command to run.
132
+ - `cwd` — optional release-relative working directory.
133
+ - `env` — optional environment variables passed to the command.
134
+ - `optional` — when `true`, the deploy records the task failure and continues.
135
+
136
+ Task groups run in config order. Required task failures stop the deploy before publish. Deploy failures include whether `current` changed and recovery hints for the affected stage, such as rerunning a before-publish failure, inspecting a newly created failed release directory, or inspecting `rampway status`, `rampway releases`, and `rampway rollback` after a failure that happened after publish. Existing release-id collisions do not suggest deleting the release directory.
137
+
138
+ ## Deployment reports
139
+
140
+ Every successful deploy or rollback appends one JSON object per line to `shared/log/rampway-deployments.jsonl`. Deploy events include:
141
+
142
+ - `event: "deploy"`
143
+ - `application`, `stage`, `releaseId`, `revision`, and `branch`
144
+ - `deployedAt` and `durationMs`
145
+ - `previousRelease`
146
+ - `healthChecks: "passed"`
147
+ - sanitized runtime status
148
+ - `cleanupRemoved` release IDs
149
+
150
+ Rollback events include `event: "rollback"`, the target `releaseId`, `rolledBackAt`, and `previousRelease`. Reports intentionally record runtime result summaries, not runtime configuration secrets.
151
+
152
+ ## Releasing
153
+
154
+ Tag pushes trigger the `.github/workflows/release.yml` workflow, which validates the package, publishes it to npm, and then creates a GitHub Release with auto-generated notes. Bump the version locally and push tags:
155
+
156
+ ```bash
157
+ npm run release:patch # 0.1.0 → 0.1.1
158
+ npm run release:minor # 0.1.1 → 0.2.0
159
+ npm run release:major # 0.2.0 → 1.0.0
160
+ ```
161
+
162
+ Each command runs `npm version` (updating `package.json` and creating a `v`-prefixed tag) and pushes the commit and tag. The workflow picks up the tag, publishes the package, and creates the GitHub Release only after publishing succeeds.
163
+
164
+ Publishing requires an npm access token stored as the repository secret `NPM_TOKEN`.
165
+
166
+ ## Runtime adapters
167
+
168
+ Rampway resolves runtimes through a small adapter registry. Built-in adapters are `none` and `rollbridge`; future adapters can register a runtime type without changing the deploy lifecycle core. Runtime adapters implement `plan()` and `deploy(...)`; optional maintenance methods such as `status`, `logs`, and `recover` can be exposed by adapter-specific commands.
169
+
170
+ Rollbridge runtime options:
171
+
172
+ - `command` — shell command used to invoke Rollbridge, defaulting to `npx rollbridge`.
173
+ - `packageDir` — release-relative directory where Rollbridge commands run.
174
+ - `config` — optional Rollbridge config path passed as `--config`.
175
+ - `daemonLogPath`, `daemonPidPath`, and `daemonStartTimeoutMs` — optional daemon flags forwarded to `rollbridge deploy`.
176
+ - `versionPath` — optional shared file where Rampway records the deployed Rollbridge package version.
177
+ - `socketPath` — optional Rollbridge socket removed after a version-change shutdown if a stale daemon leaves it behind.
178
+
179
+ When `versionPath` is configured, Rampway reads the release's installed Rollbridge package version before deploy. If it differs from the recorded version and the current runtime is responsive, Rampway shuts down the current Rollbridge daemon, removes configured stale daemon artifacts, deploys the new release, and records the new version.
180
+
181
+ ## Safety model
182
+
183
+ Rampway prepares a complete release before flipping `current`. If a deploy fails before publish, `current` remains unchanged. Rollbridge runtime deploys are validated and health-checked with `rollbridge status` before `current` is updated. Cleanup never removes the current release. Rollback changes `current` to a previously prepared release and records a deployment event.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.js"],"names":[],"mappings":""}
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { validateCommand } from "./commands/validate.js";
5
+ import { planCommand } from "./commands/plan.js";
6
+ import { doctorCommand } from "./commands/doctor.js";
7
+ import { deployCommand } from "./commands/deploy.js";
8
+ import { releasesCommand, statusCommand } from "./commands/releases.js";
9
+ import { rollbackCommand } from "./commands/rollback.js";
10
+ import { rollbridgeValidateCommand, rollbridgeStatusCommand, rollbridgeLogsCommand, rollbridgeRecoverCommand } from "./commands/rollbridge.js";
11
+ import { initCommand } from "./commands/init.js";
12
+ /** @type {Record<string, Function>} */
13
+ const COMMANDS = {
14
+ init: initCommand,
15
+ validate: validateCommand,
16
+ plan: planCommand,
17
+ deploy: deployCommand,
18
+ releases: releasesCommand,
19
+ status: statusCommand,
20
+ rollback: rollbackCommand,
21
+ "rollbridge-validate": rollbridgeValidateCommand,
22
+ "rollbridge-status": rollbridgeStatusCommand,
23
+ "rollbridge-logs": rollbridgeLogsCommand,
24
+ "rollbridge-recover": rollbridgeRecoverCommand,
25
+ doctor: doctorCommand
26
+ };
27
+ /**
28
+ * @param {string[]} argv
29
+ * @returns {Promise<void>}
30
+ */
31
+ async function main(argv) {
32
+ let { command, stageName, options } = parseArgs(argv);
33
+ // Stage-first Capistrano-style invocation: `rampway production deploy`
34
+ // (the first positional matches a known deploy/<stage>.js file and the second is a valid command)
35
+ if (command && stageName && !COMMANDS[command] && COMMANDS[stageName] && stageFileExists(command, options.config)) {
36
+ [command, stageName] = [stageName, command];
37
+ }
38
+ if (!COMMANDS[command])
39
+ throw new Error(`Unknown command '${command}'. Supported: ${Object.keys(COMMANDS).join(", ")}`);
40
+ if (!stageName && command !== "init")
41
+ throw new Error(`Usage: rampway <command> <stage> OR rampway <stage> <command> [--config path]`);
42
+ await COMMANDS[command]({ stageName, options });
43
+ }
44
+ /**
45
+ * @param {string} stageName
46
+ * @param {string} [configPath]
47
+ * @returns {boolean}
48
+ */
49
+ function stageFileExists(stageName, configPath) {
50
+ if (configPath)
51
+ return false;
52
+ // Capistrano-style: stage configs live in deploy/environments/<stage>.js.
53
+ // Walk up from cwd to find the project root that contains deploy/config.js.
54
+ let dir = process.cwd();
55
+ for (let i = 0; i < 5; i++) {
56
+ const candidate = path.join(dir, "deploy", "environments", `${stageName}.js`);
57
+ try {
58
+ if (fs.statSync(candidate).isFile())
59
+ return true;
60
+ }
61
+ catch { /* continue */ }
62
+ const parent = path.dirname(dir);
63
+ if (parent === dir)
64
+ break;
65
+ dir = parent;
66
+ }
67
+ return false;
68
+ }
69
+ /**
70
+ * @param {string[]} argv
71
+ * @returns {{command: string, stageName: string, options: import('#types').CommandOptions}}
72
+ */
73
+ function parseArgs(argv) {
74
+ const positional = [];
75
+ /** @type {Record<string, string|boolean>} */
76
+ const options = {};
77
+ for (let index = 0; index < argv.length; index += 1) {
78
+ const arg = argv[index];
79
+ if (arg.startsWith("--")) {
80
+ const name = arg.slice(2);
81
+ if (["yes", "dry-run", "force", "allow-dirty", "json"].includes(name))
82
+ options[toCamel(name)] = true;
83
+ else {
84
+ index += 1;
85
+ options[toCamel(name)] = argv[index];
86
+ }
87
+ }
88
+ else
89
+ positional.push(arg);
90
+ }
91
+ return { command: positional[0], stageName: positional[1], options };
92
+ }
93
+ /**
94
+ * @param {string} name
95
+ * @returns {string}
96
+ */
97
+ function toCamel(name) {
98
+ return name.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
99
+ }
100
+ main(process.argv.slice(2)).catch(error => {
101
+ console.error(error.message);
102
+ process.exitCode = 1;
103
+ });
104
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @param {import('#types').CommandOptions} options
3
+ * @param {string} stageName
4
+ * @returns {Promise<{config: object, configPath: string, stage: import('#types').StageConfig, transport: import('#types').Transport}>}
5
+ */
6
+ export function commandContext(options: import("#types").CommandOptions, stageName: string): Promise<{
7
+ config: object;
8
+ configPath: string;
9
+ stage: import("#types").StageConfig;
10
+ transport: import("#types").Transport;
11
+ }>;
12
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/commands/context.js"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wCAJW,OAAO,QAAQ,EAAE,cAAc,aAC/B,MAAM,GACJ,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,QAAQ,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,OAAO,QAAQ,EAAE,SAAS,CAAA;CAAC,CAAC,CAOrI"}
@@ -0,0 +1,16 @@
1
+ import { loadConfig } from "../config/load-config.js";
2
+ import { validateConfig } from "../config/validate-config.js";
3
+ import { LocalTransport } from "../transports/local-transport.js";
4
+ import { SshTransport } from "../transports/ssh-transport.js";
5
+ /**
6
+ * @param {import('#types').CommandOptions} options
7
+ * @param {string} stageName
8
+ * @returns {Promise<{config: object, configPath: string, stage: import('#types').StageConfig, transport: import('#types').Transport}>}
9
+ */
10
+ export async function commandContext(options, stageName) {
11
+ const { config, configPath } = await loadConfig(options.config, stageName);
12
+ const stage = validateConfig(/** @type {Record<string, unknown>} */ (config), stageName);
13
+ const transport = stage.transport.type === "ssh" ? SshTransport.fromStage(stage) : new LocalTransport();
14
+ return { config, configPath, stage, transport };
15
+ }
16
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/commands/context.js"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAC,cAAc,EAAC,MAAM,8BAA8B,CAAA;AAC3D,OAAO,EAAC,cAAc,EAAC,MAAM,kCAAkC,CAAA;AAC/D,OAAO,EAAC,YAAY,EAAC,MAAM,gCAAgC,CAAA;AAE3D;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAO,EAAE,SAAS;IACrD,MAAM,EAAC,MAAM,EAAE,UAAU,EAAC,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACxE,MAAM,KAAK,GAAG,cAAc,CAAC,sCAAsC,CAAC,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAA;IACxF,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,cAAc,EAAE,CAAA;IACvG,OAAO,EAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAC,CAAA;AAC/C,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @param {import('#types').CommandArgs} args
3
+ * @returns {Promise<void>}
4
+ */
5
+ export function deployCommand({ stageName, options, commandContext }: import("#types").CommandArgs): Promise<void>;
6
+ //# sourceMappingURL=deploy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/commands/deploy.js"],"names":[],"mappings":"AAGA;;;GAGG;AACH,sEAHW,OAAO,QAAQ,EAAE,WAAW,GAC1B,OAAO,CAAC,IAAI,CAAC,CAOzB"}
@@ -0,0 +1,14 @@
1
+ import { commandContext as defaultCommandContext } from "./context.js";
2
+ import { deploy } from "../core/deploy-runner.js";
3
+ /**
4
+ * @param {import('#types').CommandArgs} args
5
+ * @returns {Promise<void>}
6
+ */
7
+ export async function deployCommand({ stageName, options, commandContext = defaultCommandContext }) {
8
+ const { stage, transport } = await commandContext(options, stageName);
9
+ if (!options.yes && stageName === "production")
10
+ throw new Error("Refusing production deploy without --yes in non-interactive MVP mode.");
11
+ const report = await deploy({ transport, stage, sourcePath: options.source ?? process.cwd(), revision: options.revision ?? options.branch ?? stage.revision ?? stage.branch, branch: options.branch ?? stage.branch, dryRun: options.dryRun, force: options.force });
12
+ console.log(JSON.stringify(report, null, 2));
13
+ }
14
+ //# sourceMappingURL=deploy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../../src/commands/deploy.js"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,IAAI,qBAAqB,EAAC,MAAM,cAAc,CAAA;AACpE,OAAO,EAAC,MAAM,EAAC,MAAM,0BAA0B,CAAA;AAE/C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAC,SAAS,EAAE,OAAO,EAAE,cAAc,GAAG,qBAAqB,EAAC;IAC9F,MAAM,EAAC,KAAK,EAAE,SAAS,EAAC,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IACnE,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,SAAS,KAAK,YAAY;QAAE,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAA;IACxI,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,EAAC,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAC,CAAC,CAAA;IAClQ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;AAC9C,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @param {import('#types').CommandArgs} args
3
+ * @returns {Promise<void>}
4
+ */
5
+ export function doctorCommand({ stageName, options, commandContext }: import("#types").CommandArgs): Promise<void>;
6
+ /**
7
+ * @param {{configPath: string, stage: import('#types').StageConfig}} opts
8
+ * @returns {import('#types').DoctorReport}
9
+ */
10
+ export function doctorReport({ configPath, stage }: {
11
+ configPath: string;
12
+ stage: import("#types").StageConfig;
13
+ }): import("#types").DoctorReport;
14
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor.js"],"names":[],"mappings":"AAIA;;;GAGG;AACH,sEAHW,OAAO,QAAQ,EAAE,WAAW,GAC1B,OAAO,CAAC,IAAI,CAAC,CAyBzB;AAED;;;GAGG;AACH,oDAHW;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,QAAQ,EAAE,WAAW,CAAA;CAAC,GACvD,OAAO,QAAQ,EAAE,YAAY,CAqBzC"}
@@ -0,0 +1,54 @@
1
+ import { commandContext as defaultCommandContext } from "./context.js";
2
+ const DEPLOYABLE_STRATEGIES = new Set(["local-copy", "remote-git"]);
3
+ /**
4
+ * @param {import('#types').CommandArgs} args
5
+ * @returns {Promise<void>}
6
+ */
7
+ export async function doctorCommand({ stageName, options, commandContext = defaultCommandContext }) {
8
+ const { configPath, stage } = await commandContext(options, stageName);
9
+ const report = doctorReport({ configPath, stage });
10
+ if (options.json) {
11
+ console.log(JSON.stringify(report, null, 2));
12
+ return;
13
+ }
14
+ console.log("Rampway doctor");
15
+ console.log(`Config: ok (${report.configPath})`);
16
+ console.log(`Application: ${report.application}`);
17
+ console.log(`Stage: ${report.stage}`);
18
+ console.log(`Transport: ${report.transport.type}`);
19
+ console.log(`Strategy: ${report.strategy}`);
20
+ console.log(`Deploy path: ${report.deployTo}`);
21
+ console.log(`Runtime: ${report.runtime.type}`);
22
+ console.log(`Linked files: ${report.linkedFiles}`);
23
+ console.log(`Linked dirs: ${report.linkedDirs}`);
24
+ console.log(`Task groups: ${report.taskGroups}`);
25
+ console.log(`Health checks: ${report.healthChecks}`);
26
+ console.log(`Result: ${report.ok ? "ok" : "warnings"}`);
27
+ for (const warning of report.warnings)
28
+ console.log(`Warning: ${warning}`);
29
+ }
30
+ /**
31
+ * @param {{configPath: string, stage: import('#types').StageConfig}} opts
32
+ * @returns {import('#types').DoctorReport}
33
+ */
34
+ export function doctorReport({ configPath, stage }) {
35
+ const warnings = [];
36
+ if (!DEPLOYABLE_STRATEGIES.has(stage.strategy))
37
+ warnings.push(`Strategy '${stage.strategy}' validates but deploy is not implemented yet`);
38
+ return {
39
+ ok: warnings.length === 0,
40
+ configPath,
41
+ application: stage.application,
42
+ stage: stage.stageName,
43
+ deployTo: stage.deployTo,
44
+ transport: { type: stage.transport.type },
45
+ strategy: stage.strategy,
46
+ runtime: { type: stage.runtime.type },
47
+ linkedFiles: stage.linkedFiles.length,
48
+ linkedDirs: stage.linkedDirs.length,
49
+ taskGroups: Object.keys(stage.tasks).length,
50
+ healthChecks: stage.healthChecks.length,
51
+ warnings
52
+ };
53
+ }
54
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/commands/doctor.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @param {{dir?: string}} [opts]
3
+ * @returns {Promise<import('#types').InitResult>}
4
+ */
5
+ export function initCommand({ dir }?: {
6
+ dir?: string;
7
+ }): Promise<import("#types").InitResult>;
8
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/commands/init.js"],"names":[],"mappings":"AA4BA;;;GAGG;AACH,sCAHW;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAC,GACZ,OAAO,CAAC,OAAO,QAAQ,EAAE,UAAU,CAAC,CAWhD"}
@@ -0,0 +1,42 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ const TEMPLATE = `export default {
4
+ application: "my-app",
5
+ stages: {
6
+ production: {
7
+ deployTo: "/home/dev/my-app",
8
+ strategy: "local-copy",
9
+ transport: {type: "ssh"},
10
+ hosts: [{host: "server.example", user: "dev", roles: ["app", "web"]}],
11
+ keepReleases: 5,
12
+ linkedFiles: [
13
+ {path: ".env", required: true}
14
+ ],
15
+ linkedDirs: ["log", "tmp/pids", "tmp/cache"],
16
+ tasks: {
17
+ install: ["npm ci --omit=dev"],
18
+ migrate: ["NODE_ENV=production npm run db:migrate"],
19
+ build: ["npm run build"]
20
+ },
21
+ runtime: {type: "none"},
22
+ healthChecks: [{name: "package", path: "package.json"}]
23
+ }
24
+ }
25
+ }
26
+ `;
27
+ /**
28
+ * @param {{dir?: string}} [opts]
29
+ * @returns {Promise<import('#types').InitResult>}
30
+ */
31
+ export async function initCommand({ dir = process.cwd() } = {}) {
32
+ const configPath = path.join(dir, "rampway.config.mjs");
33
+ try {
34
+ await fs.access(configPath);
35
+ return { created: false, path: configPath };
36
+ }
37
+ catch {
38
+ await fs.writeFile(configPath, TEMPLATE);
39
+ return { created: true, path: configPath };
40
+ }
41
+ }
42
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/init.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;CAuBhB,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,EAAC,GAAG,EAAE;IAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAA;IACvD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAC3B,OAAO,EAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAC,CAAA;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;QACxC,OAAO,EAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAC,CAAA;IAC1C,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @param {import('#types').CommandArgs} args
3
+ * @returns {Promise<void>}
4
+ */
5
+ export function planCommand({ stageName, options, commandContext }: import("#types").CommandArgs): Promise<void>;
6
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/commands/plan.js"],"names":[],"mappings":"AAGA;;;GAGG;AACH,oEAHW,OAAO,QAAQ,EAAE,WAAW,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoBzB"}
@@ -0,0 +1,24 @@
1
+ import { commandContext as defaultCommandContext } from "./context.js";
2
+ import { createDeployPlanDetails } from "../core/deploy-runner.js";
3
+ /**
4
+ * @param {import('#types').CommandArgs} args
5
+ * @returns {Promise<void>}
6
+ */
7
+ export async function planCommand({ stageName, options, commandContext = defaultCommandContext }) {
8
+ const { stage } = await commandContext(options, stageName);
9
+ const revision = options.revision ?? options.branch ?? stage.revision ?? stage.branch;
10
+ const releaseId = options.releaseId ?? "<timestamp>";
11
+ const steps = createDeployPlanDetails(stage, { revision, releaseId });
12
+ const payload = { application: stage.application, stage: stage.stageName, revision, releaseId, steps };
13
+ if (options.json) {
14
+ console.log(JSON.stringify(payload, null, 2));
15
+ return;
16
+ }
17
+ console.log(`Plan for ${stage.application} ${stage.stageName}`);
18
+ console.log(`Revision: ${revision}`);
19
+ console.log(`Release: ${releaseId}`);
20
+ steps.forEach((step, index) => {
21
+ console.log(`${index + 1}. [${step.phase}] ${step.detail}`);
22
+ });
23
+ }
24
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/commands/plan.js"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,IAAI,qBAAqB,EAAC,MAAM,cAAc,CAAA;AACpE,OAAO,EAAC,uBAAuB,EAAC,MAAM,0BAA0B,CAAA;AAEhE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAC,SAAS,EAAE,OAAO,EAAE,cAAc,GAAG,qBAAqB,EAAC;IAC5F,MAAM,EAAC,KAAK,EAAC,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;IACxD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAA;IACrF,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,aAAa,CAAA;IACpD,MAAM,KAAK,GAAG,uBAAuB,CAAC,KAAK,EAAE,EAAC,QAAQ,EAAE,SAAS,EAAC,CAAC,CAAA;IACnE,MAAM,OAAO,GAAG,EAAC,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAC,CAAA;IAEpG,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QAC7C,OAAM;IACR,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC,CAAA;IAC/D,OAAO,CAAC,GAAG,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAA;IACpC,OAAO,CAAC,GAAG,CAAC,YAAY,SAAS,EAAE,CAAC,CAAA;IACpC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IAC7D,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @param {import('#types').CommandArgs} args
3
+ * @returns {Promise<void>}
4
+ */
5
+ export function releasesCommand({ stageName, options, commandContext }: import("#types").CommandArgs): Promise<void>;
6
+ /**
7
+ * @param {{stage: import('#types').StageConfig, transport: import('#types').Transport}} opts
8
+ * @returns {Promise<import('#types').ReleasesReport>}
9
+ */
10
+ export function releasesReport({ stage, transport }: {
11
+ stage: import("#types").StageConfig;
12
+ transport: import("#types").Transport;
13
+ }): Promise<import("#types").ReleasesReport>;
14
+ /**
15
+ * @param {import('#types').CommandArgs} args
16
+ * @returns {Promise<void>}
17
+ */
18
+ export function statusCommand({ stageName, options, commandContext }: import("#types").CommandArgs): Promise<void>;
19
+ /**
20
+ * @param {{stage: import('#types').StageConfig, transport: import('#types').Transport}} opts
21
+ * @returns {Promise<import('#types').StatusReport>}
22
+ */
23
+ export function statusReport({ stage, transport }: {
24
+ stage: import("#types").StageConfig;
25
+ transport: import("#types").Transport;
26
+ }): Promise<import("#types").StatusReport>;
27
+ //# sourceMappingURL=releases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"releases.d.ts","sourceRoot":"","sources":["../../../src/commands/releases.js"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wEAHW,OAAO,QAAQ,EAAE,WAAW,GAC1B,OAAO,CAAC,IAAI,CAAC,CAiBzB;AAED;;;GAGG;AACH,qDAHW;IAAC,KAAK,EAAE,OAAO,QAAQ,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,OAAO,QAAQ,EAAE,SAAS,CAAA;CAAC,GAC1E,OAAO,CAAC,OAAO,QAAQ,EAAE,cAAc,CAAC,CAiBpD;AAED;;;GAGG;AACH,sEAHW,OAAO,QAAQ,EAAE,WAAW,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoBzB;AAED;;;GAGG;AACH,mDAHW;IAAC,KAAK,EAAE,OAAO,QAAQ,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,OAAO,QAAQ,EAAE,SAAS,CAAA;CAAC,GAC1E,OAAO,CAAC,OAAO,QAAQ,EAAE,YAAY,CAAC,CAsBlD"}