@devalade/shipnode 2.0.0
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/cli/commands/backup.d.ts +14 -0
- package/dist/cli/commands/backup.d.ts.map +1 -0
- package/dist/cli/commands/backup.js +144 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/ci.d.ts +5 -0
- package/dist/cli/commands/ci.d.ts.map +1 -0
- package/dist/cli/commands/ci.js +222 -0
- package/dist/cli/commands/ci.js.map +1 -0
- package/dist/cli/commands/cloudflare.d.ts +10 -0
- package/dist/cli/commands/cloudflare.d.ts.map +1 -0
- package/dist/cli/commands/cloudflare.js +166 -0
- package/dist/cli/commands/cloudflare.js.map +1 -0
- package/dist/cli/commands/config.d.ts +10 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +99 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/deploy.d.ts +6 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -0
- package/dist/cli/commands/deploy.js +95 -0
- package/dist/cli/commands/deploy.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +5 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +86 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/eject.d.ts +2 -0
- package/dist/cli/commands/eject.d.ts.map +1 -0
- package/dist/cli/commands/eject.js +74 -0
- package/dist/cli/commands/eject.js.map +1 -0
- package/dist/cli/commands/env.d.ts +4 -0
- package/dist/cli/commands/env.d.ts.map +1 -0
- package/dist/cli/commands/env.js +50 -0
- package/dist/cli/commands/env.js.map +1 -0
- package/dist/cli/commands/harden.d.ts +4 -0
- package/dist/cli/commands/harden.d.ts.map +1 -0
- package/dist/cli/commands/harden.js +110 -0
- package/dist/cli/commands/harden.js.map +1 -0
- package/dist/cli/commands/help.d.ts +2 -0
- package/dist/cli/commands/help.d.ts.map +1 -0
- package/dist/cli/commands/help.js +99 -0
- package/dist/cli/commands/help.js.map +1 -0
- package/dist/cli/commands/init.d.ts +5 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +246 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +5 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +17 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/metrics.d.ts +4 -0
- package/dist/cli/commands/metrics.d.ts.map +1 -0
- package/dist/cli/commands/metrics.js +21 -0
- package/dist/cli/commands/metrics.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +4 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +71 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/commands/restart.d.ts +4 -0
- package/dist/cli/commands/restart.d.ts.map +1 -0
- package/dist/cli/commands/restart.js +14 -0
- package/dist/cli/commands/restart.js.map +1 -0
- package/dist/cli/commands/rollback.d.ts +5 -0
- package/dist/cli/commands/rollback.d.ts.map +1 -0
- package/dist/cli/commands/rollback.js +49 -0
- package/dist/cli/commands/rollback.js.map +1 -0
- package/dist/cli/commands/run.d.ts +5 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +69 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +4 -0
- package/dist/cli/commands/setup.d.ts.map +1 -0
- package/dist/cli/commands/setup.js +46 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/status.d.ts +4 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +49 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +4 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +14 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/commands/unlock.d.ts +4 -0
- package/dist/cli/commands/unlock.d.ts.map +1 -0
- package/dist/cli/commands/unlock.js +27 -0
- package/dist/cli/commands/unlock.js.map +1 -0
- package/dist/cli/commands/upgrade.d.ts +2 -0
- package/dist/cli/commands/upgrade.d.ts.map +1 -0
- package/dist/cli/commands/upgrade.js +63 -0
- package/dist/cli/commands/upgrade.js.map +1 -0
- package/dist/cli/commands/user.d.ts +17 -0
- package/dist/cli/commands/user.d.ts.map +1 -0
- package/dist/cli/commands/user.js +98 -0
- package/dist/cli/commands/user.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +218 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/prompt.d.ts +2 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +11 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/runner.d.ts +34 -0
- package/dist/cli/runner.d.ts.map +1 -0
- package/dist/cli/runner.js +44 -0
- package/dist/cli/runner.js.map +1 -0
- package/dist/cli/ui.d.ts +9 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/ui.js +26 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/config/assembly.d.ts +14 -0
- package/dist/config/assembly.d.ts.map +1 -0
- package/dist/config/assembly.js +62 -0
- package/dist/config/assembly.js.map +1 -0
- package/dist/config/builder.d.ts +33 -0
- package/dist/config/builder.d.ts.map +1 -0
- package/dist/config/builder.js +119 -0
- package/dist/config/builder.js.map +1 -0
- package/dist/config/loader.d.ts +3 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +20 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +416 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +75 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/domain/deploy/backend-strategy.d.ts +15 -0
- package/dist/domain/deploy/backend-strategy.d.ts.map +1 -0
- package/dist/domain/deploy/backend-strategy.js +110 -0
- package/dist/domain/deploy/backend-strategy.js.map +1 -0
- package/dist/domain/deploy/frontend-strategy.d.ts +13 -0
- package/dist/domain/deploy/frontend-strategy.d.ts.map +1 -0
- package/dist/domain/deploy/frontend-strategy.js +64 -0
- package/dist/domain/deploy/frontend-strategy.js.map +1 -0
- package/dist/domain/deploy/orchestrator.d.ts +34 -0
- package/dist/domain/deploy/orchestrator.d.ts.map +1 -0
- package/dist/domain/deploy/orchestrator.js +149 -0
- package/dist/domain/deploy/orchestrator.js.map +1 -0
- package/dist/domain/deploy/strategy.d.ts +44 -0
- package/dist/domain/deploy/strategy.d.ts.map +1 -0
- package/dist/domain/deploy/strategy.js +2 -0
- package/dist/domain/deploy/strategy.js.map +1 -0
- package/dist/domain/framework/detector.d.ts +7 -0
- package/dist/domain/framework/detector.d.ts.map +1 -0
- package/dist/domain/framework/detector.js +109 -0
- package/dist/domain/framework/detector.js.map +1 -0
- package/dist/domain/release/manager.d.ts +22 -0
- package/dist/domain/release/manager.d.ts.map +1 -0
- package/dist/domain/release/manager.js +100 -0
- package/dist/domain/release/manager.js.map +1 -0
- package/dist/domain/remote/executor.d.ts +16 -0
- package/dist/domain/remote/executor.d.ts.map +1 -0
- package/dist/domain/remote/executor.js +2 -0
- package/dist/domain/remote/executor.js.map +1 -0
- package/dist/domain/validation/ip.d.ts +5 -0
- package/dist/domain/validation/ip.d.ts.map +1 -0
- package/dist/domain/validation/ip.js +38 -0
- package/dist/domain/validation/ip.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/ssh/connection.d.ts +19 -0
- package/dist/infrastructure/ssh/connection.d.ts.map +1 -0
- package/dist/infrastructure/ssh/connection.js +89 -0
- package/dist/infrastructure/ssh/connection.js.map +1 -0
- package/dist/services/caddy.service.d.ts +12 -0
- package/dist/services/caddy.service.d.ts.map +1 -0
- package/dist/services/caddy.service.js +56 -0
- package/dist/services/caddy.service.js.map +1 -0
- package/dist/services/deploy.service.d.ts +19 -0
- package/dist/services/deploy.service.d.ts.map +1 -0
- package/dist/services/deploy.service.js +53 -0
- package/dist/services/deploy.service.js.map +1 -0
- package/dist/services/health.service.d.ts +13 -0
- package/dist/services/health.service.d.ts.map +1 -0
- package/dist/services/health.service.js +38 -0
- package/dist/services/health.service.js.map +1 -0
- package/dist/shared/constants.d.ts +127 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/constants.js +85 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/errors.d.ts +27 -0
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/errors.js +53 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/types.d.ts +116 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +2 -0
- package/dist/shared/types.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import { pathExists } from 'fs-extra';
|
|
3
|
+
import { resolve } from 'path';
|
|
4
|
+
import { getInstallCommand, getRunCommand, detectPkgManager } from '../framework/detector.js';
|
|
5
|
+
import { RSYNC_DEFAULT_EXCLUDES } from '../../shared/constants.js';
|
|
6
|
+
export class BackendStrategy {
|
|
7
|
+
config;
|
|
8
|
+
cwd;
|
|
9
|
+
name = 'backend';
|
|
10
|
+
constructor(config, cwd) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
this.cwd = cwd;
|
|
13
|
+
}
|
|
14
|
+
async stage(ctx) {
|
|
15
|
+
const excludes = [...RSYNC_DEFAULT_EXCLUDES];
|
|
16
|
+
const ignoreFile = resolve(this.cwd, '.shipnodeignore');
|
|
17
|
+
const hasIgnoreFile = await pathExists(ignoreFile);
|
|
18
|
+
const args = [
|
|
19
|
+
'-avz',
|
|
20
|
+
'--progress',
|
|
21
|
+
'-e', `ssh -p ${this.config.ssh.port}`,
|
|
22
|
+
...excludes.flatMap((e) => ['--exclude', e]),
|
|
23
|
+
...(hasIgnoreFile ? ['--exclude-from', ignoreFile] : []),
|
|
24
|
+
`${this.cwd}/`,
|
|
25
|
+
`${this.config.ssh.user}@${this.config.ssh.host}:${ctx.workDir}/`,
|
|
26
|
+
];
|
|
27
|
+
await execa('rsync', args);
|
|
28
|
+
}
|
|
29
|
+
async setupEnvironment(ctx) {
|
|
30
|
+
const pkgManager = await this.resolvePkgManager();
|
|
31
|
+
const installCmd = getInstallCommand(pkgManager);
|
|
32
|
+
const runCmd = getRunCommand(pkgManager);
|
|
33
|
+
const commands = [
|
|
34
|
+
`cd "${ctx.workDir}"`,
|
|
35
|
+
`export PATH="$HOME/.local/bin:$HOME/.local/share/mise/shims:$PATH"`,
|
|
36
|
+
`mise use -y "node@${this.config.nodeVersion}"`,
|
|
37
|
+
`mise install -y`,
|
|
38
|
+
];
|
|
39
|
+
if (this.config.sharedDirs || this.config.sharedFiles) {
|
|
40
|
+
commands.push(this.getLinkSharedResourcesCommand(ctx.workDir));
|
|
41
|
+
}
|
|
42
|
+
if (this.config.envFile) {
|
|
43
|
+
commands.push(`ln -sf "${this.config.remotePath}/shared/.env" .env`);
|
|
44
|
+
}
|
|
45
|
+
commands.push(installCmd);
|
|
46
|
+
if (!ctx.skipBuild) {
|
|
47
|
+
commands.push(`if [ -f package.json ] && jq -e '.scripts.build' package.json >/dev/null 2>&1; then ${runCmd} build; fi`);
|
|
48
|
+
}
|
|
49
|
+
commands.push(`if [ -d build ] && [ -f .env ]; then ln -sf "${ctx.workDir}/.env" build/.env; fi`);
|
|
50
|
+
await ctx.executor.exec(commands.join(' && '));
|
|
51
|
+
}
|
|
52
|
+
async startApp(ctx) {
|
|
53
|
+
if (!this.config.pm2)
|
|
54
|
+
return;
|
|
55
|
+
const ecosystemContent = this.generateEcosystemFile();
|
|
56
|
+
const ecosystemPath = this.config.zeroDowntime
|
|
57
|
+
? `${this.config.remotePath}/shared/ecosystem.config.cjs`
|
|
58
|
+
: `${ctx.workDir}/ecosystem.config.cjs`;
|
|
59
|
+
const escaped = ecosystemContent.replace(/'/g, "'\"'\"'");
|
|
60
|
+
await ctx.executor.exec(`echo '${escaped}' > "${ecosystemPath}"`);
|
|
61
|
+
const cdPath = this.config.zeroDowntime ? `${this.config.remotePath}/current` : ctx.workDir;
|
|
62
|
+
await ctx.executor.exec(`cd "${cdPath}" && ` +
|
|
63
|
+
`export PATH="$HOME/.local/bin:$HOME/.local/share/mise/shims:$PATH" && ` +
|
|
64
|
+
`mise exec -- pm2 startOrReload "${ecosystemPath}" --update-env && ` +
|
|
65
|
+
`mise exec -- pm2 save`);
|
|
66
|
+
}
|
|
67
|
+
generateEcosystemFile() {
|
|
68
|
+
if (!this.config.pm2)
|
|
69
|
+
return '';
|
|
70
|
+
const port = this.config.backend?.port ?? 3000;
|
|
71
|
+
const name = this.config.pm2.name;
|
|
72
|
+
const instances = this.config.pm2.instances ?? 1;
|
|
73
|
+
const maxMemory = this.config.pm2.maxMemory ?? '512M';
|
|
74
|
+
return `module.exports = {
|
|
75
|
+
apps: [{
|
|
76
|
+
name: '${name}',
|
|
77
|
+
script: 'index',
|
|
78
|
+
instances: ${instances},
|
|
79
|
+
exec_mode: 'cluster',
|
|
80
|
+
max_memory_restart: '${maxMemory}',
|
|
81
|
+
env: {
|
|
82
|
+
NODE_ENV: 'production',
|
|
83
|
+
PORT: ${port},
|
|
84
|
+
},
|
|
85
|
+
}],
|
|
86
|
+
};`;
|
|
87
|
+
}
|
|
88
|
+
getLinkSharedResourcesCommand(workDir) {
|
|
89
|
+
const commands = [];
|
|
90
|
+
if (this.config.sharedDirs) {
|
|
91
|
+
for (const dir of this.config.sharedDirs) {
|
|
92
|
+
commands.push(`mkdir -p "${this.config.remotePath}/shared/${dir}"`);
|
|
93
|
+
commands.push(`ln -sfn "${this.config.remotePath}/shared/${dir}" "${workDir}/${dir}"`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (this.config.sharedFiles) {
|
|
97
|
+
for (const file of this.config.sharedFiles) {
|
|
98
|
+
commands.push(`ln -sf "${this.config.remotePath}/shared/${file}" "${workDir}/${file}"`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return commands.join(' && ');
|
|
102
|
+
}
|
|
103
|
+
async resolvePkgManager() {
|
|
104
|
+
if (this.config.pkgManager)
|
|
105
|
+
return this.config.pkgManager;
|
|
106
|
+
const detected = await detectPkgManager(this.cwd);
|
|
107
|
+
return detected ?? 'npm';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=backend-strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend-strategy.js","sourceRoot":"","sources":["../../../src/domain/deploy/backend-strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC9F,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGnE,MAAM,OAAO,eAAe;IAIhB;IACA;IAJD,IAAI,GAAG,SAAS,CAAC;IAE1B,YACU,MAAsB,EACtB,GAAW;QADX,WAAM,GAAN,MAAM,CAAgB;QACtB,QAAG,GAAH,GAAG,CAAQ;IAClB,CAAC;IAEJ,KAAK,CAAC,KAAK,CAAC,GAAoB;QAC9B,MAAM,QAAQ,GAAG,CAAC,GAAG,sBAAsB,CAAC,CAAC;QAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QACxD,MAAM,aAAa,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;QAEnD,MAAM,IAAI,GAAG;YACX,MAAM;YACN,YAAY;YACZ,IAAI,EAAE,UAAU,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE;YACtC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;YAC5C,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,IAAI,CAAC,GAAG,GAAG;YACd,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,GAAG;SAClE,CAAC;QAEF,MAAM,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,GAAoB;QACzC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAClD,MAAM,UAAU,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;QAEzC,MAAM,QAAQ,GAAG;YACf,OAAO,GAAG,CAAC,OAAO,GAAG;YACrB,oEAAoE;YACpE,qBAAqB,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG;YAC/C,iBAAiB;SAClB,CAAC;QAEF,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACtD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,UAAU,oBAAoB,CAAC,CAAC;QACvE,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE1B,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;YACnB,QAAQ,CAAC,IAAI,CAAC,uFAAuF,MAAM,YAAY,CAAC,CAAC;QAC3H,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,gDAAgD,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC;QAElG,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAoB;QACjC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG;YAAE,OAAO;QAE7B,MAAM,gBAAgB,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACtD,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY;YAC5C,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,8BAA8B;YACzD,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,uBAAuB,CAAC;QAE1C,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC1D,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,OAAO,QAAQ,aAAa,GAAG,CAAC,CAAC;QAElE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;QAC5F,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,CACrB,OAAO,MAAM,OAAO;YACpB,wEAAwE;YACxE,mCAAmC,aAAa,oBAAoB;YACpE,uBAAuB,CACxB,CAAC;IACJ,CAAC;IAEO,qBAAqB;QAC3B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QAEhC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,IAAI,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;QAClC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,CAAC;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC;QAEtD,OAAO;;aAEE,IAAI;;iBAEA,SAAS;;2BAEC,SAAS;;;cAGtB,IAAI;;;GAGf,CAAC;IACF,CAAC;IAEO,6BAA6B,CAAC,OAAe;QACnD,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YAC3B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;gBACzC,QAAQ,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,MAAM,CAAC,UAAU,WAAW,GAAG,GAAG,CAAC,CAAC;gBACpE,QAAQ,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,MAAM,CAAC,UAAU,WAAW,GAAG,MAAM,OAAO,IAAI,GAAG,GAAG,CAAC,CAAC;YACzF,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC5B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;gBAC3C,QAAQ,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,UAAU,WAAW,IAAI,MAAM,OAAO,IAAI,IAAI,GAAG,CAAC,CAAC;YAC1F,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC7B,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;QAC1D,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClD,OAAO,QAAQ,IAAI,KAAK,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ShipnodeConfig } from '../../shared/types.js';
|
|
2
|
+
import type { DeploymentStrategy, StrategyContext } from './strategy.js';
|
|
3
|
+
export declare class FrontendStrategy implements DeploymentStrategy {
|
|
4
|
+
private config;
|
|
5
|
+
private cwd;
|
|
6
|
+
readonly name = "frontend";
|
|
7
|
+
constructor(config: ShipnodeConfig, cwd: string);
|
|
8
|
+
stage(ctx: StrategyContext): Promise<void>;
|
|
9
|
+
private buildFrontend;
|
|
10
|
+
private detectFrontendBuildDir;
|
|
11
|
+
private resolvePkgManager;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=frontend-strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontend-strategy.d.ts","sourceRoot":"","sources":["../../../src/domain/deploy/frontend-strategy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEzE,qBAAa,gBAAiB,YAAW,kBAAkB;IAIvD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,GAAG;IAJb,QAAQ,CAAC,IAAI,cAAc;gBAGjB,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,MAAM;IAGf,KAAK,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;YAwBlC,aAAa;YAUb,sBAAsB;YAWtB,iBAAiB;CAKhC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import { pathExists } from 'fs-extra';
|
|
3
|
+
import { resolve } from 'path';
|
|
4
|
+
import { getRunCommand, detectPkgManager } from '../framework/detector.js';
|
|
5
|
+
export class FrontendStrategy {
|
|
6
|
+
config;
|
|
7
|
+
cwd;
|
|
8
|
+
name = 'frontend';
|
|
9
|
+
constructor(config, cwd) {
|
|
10
|
+
this.config = config;
|
|
11
|
+
this.cwd = cwd;
|
|
12
|
+
}
|
|
13
|
+
async stage(ctx) {
|
|
14
|
+
if (!ctx.skipBuild) {
|
|
15
|
+
await this.buildFrontend();
|
|
16
|
+
}
|
|
17
|
+
const buildDir = await this.detectFrontendBuildDir();
|
|
18
|
+
const ignoreFile = resolve(this.cwd, '.shipnodeignore');
|
|
19
|
+
const hasIgnoreFile = await pathExists(ignoreFile);
|
|
20
|
+
await execa('rsync', [
|
|
21
|
+
'-avz',
|
|
22
|
+
'--progress',
|
|
23
|
+
'--delete',
|
|
24
|
+
'-e', `ssh -p ${this.config.ssh.port}`,
|
|
25
|
+
'--exclude', 'shared/',
|
|
26
|
+
'--exclude', '.shipnode/',
|
|
27
|
+
'--exclude', 'releases/',
|
|
28
|
+
'--exclude', 'current',
|
|
29
|
+
...(hasIgnoreFile ? ['--exclude-from', ignoreFile] : []),
|
|
30
|
+
`${this.cwd}/${buildDir}/`,
|
|
31
|
+
`${this.config.ssh.user}@${this.config.ssh.host}:${ctx.workDir}/`,
|
|
32
|
+
]);
|
|
33
|
+
}
|
|
34
|
+
async buildFrontend() {
|
|
35
|
+
const pkgManager = await this.resolvePkgManager();
|
|
36
|
+
const runCmd = getRunCommand(pkgManager);
|
|
37
|
+
await execa(runCmd.split(' ')[0], [...runCmd.split(' ').slice(1), 'build'], {
|
|
38
|
+
cwd: this.cwd,
|
|
39
|
+
stdio: 'inherit',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
async detectFrontendBuildDir() {
|
|
43
|
+
if (this.config.buildDir)
|
|
44
|
+
return this.config.buildDir;
|
|
45
|
+
if (await pathExists(`${this.cwd}/build`))
|
|
46
|
+
return 'build';
|
|
47
|
+
if (await pathExists(`${this.cwd}/public`))
|
|
48
|
+
return 'public';
|
|
49
|
+
if (await pathExists(`${this.cwd}/dist`))
|
|
50
|
+
return 'dist';
|
|
51
|
+
if (await pathExists(`${this.cwd}/out`))
|
|
52
|
+
return 'out';
|
|
53
|
+
if (await pathExists(`${this.cwd}/.output`))
|
|
54
|
+
return '.output';
|
|
55
|
+
return 'dist';
|
|
56
|
+
}
|
|
57
|
+
async resolvePkgManager() {
|
|
58
|
+
if (this.config.pkgManager)
|
|
59
|
+
return this.config.pkgManager;
|
|
60
|
+
const detected = await detectPkgManager(this.cwd);
|
|
61
|
+
return detected ?? 'npm';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=frontend-strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontend-strategy.js","sourceRoot":"","sources":["../../../src/domain/deploy/frontend-strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAG3E,MAAM,OAAO,gBAAgB;IAIjB;IACA;IAJD,IAAI,GAAG,UAAU,CAAC;IAE3B,YACU,MAAsB,EACtB,GAAW;QADX,WAAM,GAAN,MAAM,CAAgB;QACtB,QAAG,GAAH,GAAG,CAAQ;IAClB,CAAC;IAEJ,KAAK,CAAC,KAAK,CAAC,GAAoB;QAC9B,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;YACnB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;QACrD,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;QACxD,MAAM,aAAa,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;QAEnD,MAAM,KAAK,CAAC,OAAO,EAAE;YACnB,MAAM;YACN,YAAY;YACZ,UAAU;YACV,IAAI,EAAE,UAAU,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE;YACtC,WAAW,EAAE,SAAS;YACtB,WAAW,EAAE,YAAY;YACzB,WAAW,EAAE,WAAW;YACxB,WAAW,EAAE,SAAS;YACtB,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,GAAG,IAAI,CAAC,GAAG,IAAI,QAAQ,GAAG;YAC1B,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,GAAG;SAClE,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;QAEzC,MAAM,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE;YAC1E,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,sBAAsB;QAClC,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QACtD,IAAI,MAAM,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,QAAQ,CAAC;YAAE,OAAO,OAAO,CAAC;QAC1D,IAAI,MAAM,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC;YAAE,OAAO,QAAQ,CAAC;QAC5D,IAAI,MAAM,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC;YAAE,OAAO,MAAM,CAAC;QACxD,IAAI,MAAM,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;QACtD,IAAI,MAAM,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,UAAU,CAAC;YAAE,OAAO,SAAS,CAAC;QAE9D,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC7B,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;QAC1D,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClD,OAAO,QAAQ,IAAI,KAAK,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ShipnodeConfig } from '../../shared/types.js';
|
|
2
|
+
import type { RemoteExecutor } from '../remote/executor.js';
|
|
3
|
+
import { ReleaseManager, DeployLock } from '../release/manager.js';
|
|
4
|
+
import { HealthCheckService } from '../../services/health.service.js';
|
|
5
|
+
import { CaddyService } from '../../services/caddy.service.js';
|
|
6
|
+
import type { DeploymentStrategy } from './strategy.js';
|
|
7
|
+
/**
|
|
8
|
+
* The release orchestrator owns the invariant deployment sequence.
|
|
9
|
+
*
|
|
10
|
+
* It knows nothing about app-specific details (those live in the
|
|
11
|
+
* DeploymentStrategy). It knows everything about lock management,
|
|
12
|
+
* release directories, symlinks, health checks, hooks, and cleanup.
|
|
13
|
+
*
|
|
14
|
+
* This is a deep module: a small interface (`deploy`) hides a lot of
|
|
15
|
+
* behaviour (the full zero-downtime or legacy lifecycle).
|
|
16
|
+
*/
|
|
17
|
+
export declare class DeployOrchestrator {
|
|
18
|
+
private config;
|
|
19
|
+
private executor;
|
|
20
|
+
private releases;
|
|
21
|
+
private lock;
|
|
22
|
+
private healthCheck;
|
|
23
|
+
private caddy;
|
|
24
|
+
constructor(config: ShipnodeConfig, executor: RemoteExecutor, releases: ReleaseManager, lock: DeployLock, healthCheck: HealthCheckService, caddy: CaddyService);
|
|
25
|
+
deploy(strategy: DeploymentStrategy, options: {
|
|
26
|
+
cwd: string;
|
|
27
|
+
skipBuild: boolean;
|
|
28
|
+
gitCommit?: string;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
private deployZeroDowntime;
|
|
31
|
+
private deployLegacy;
|
|
32
|
+
private runHook;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../../src/domain/deploy/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,uBAAuB,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,eAAe,CAAC;AAEzE;;;;;;;;;GASG;AACH,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,KAAK;gBALL,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,kBAAkB,EAC/B,KAAK,EAAE,YAAY;IAGvB,MAAM,CACV,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAC/D,OAAO,CAAC,IAAI,CAAC;YAQF,kBAAkB;YA4ElB,YAAY;YA8CZ,OAAO;CAmBtB"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { DeployError } from '../../shared/errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* The release orchestrator owns the invariant deployment sequence.
|
|
4
|
+
*
|
|
5
|
+
* It knows nothing about app-specific details (those live in the
|
|
6
|
+
* DeploymentStrategy). It knows everything about lock management,
|
|
7
|
+
* release directories, symlinks, health checks, hooks, and cleanup.
|
|
8
|
+
*
|
|
9
|
+
* This is a deep module: a small interface (`deploy`) hides a lot of
|
|
10
|
+
* behaviour (the full zero-downtime or legacy lifecycle).
|
|
11
|
+
*/
|
|
12
|
+
export class DeployOrchestrator {
|
|
13
|
+
config;
|
|
14
|
+
executor;
|
|
15
|
+
releases;
|
|
16
|
+
lock;
|
|
17
|
+
healthCheck;
|
|
18
|
+
caddy;
|
|
19
|
+
constructor(config, executor, releases, lock, healthCheck, caddy) {
|
|
20
|
+
this.config = config;
|
|
21
|
+
this.executor = executor;
|
|
22
|
+
this.releases = releases;
|
|
23
|
+
this.lock = lock;
|
|
24
|
+
this.healthCheck = healthCheck;
|
|
25
|
+
this.caddy = caddy;
|
|
26
|
+
}
|
|
27
|
+
async deploy(strategy, options) {
|
|
28
|
+
if (this.config.zeroDowntime) {
|
|
29
|
+
await this.deployZeroDowntime(strategy, options);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
await this.deployLegacy(strategy, options);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async deployZeroDowntime(strategy, options) {
|
|
36
|
+
const deployStart = Date.now();
|
|
37
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
38
|
+
await this.lock.acquire();
|
|
39
|
+
try {
|
|
40
|
+
const releasePath = await this.releases.createReleasePath(timestamp);
|
|
41
|
+
await this.releases.setupReleaseStructure();
|
|
42
|
+
const ctx = {
|
|
43
|
+
config: this.config,
|
|
44
|
+
executor: this.executor,
|
|
45
|
+
workDir: releasePath,
|
|
46
|
+
cwd: options.cwd,
|
|
47
|
+
skipBuild: options.skipBuild,
|
|
48
|
+
};
|
|
49
|
+
await strategy.stage(ctx);
|
|
50
|
+
if (strategy.setupEnvironment) {
|
|
51
|
+
await strategy.setupEnvironment(ctx);
|
|
52
|
+
}
|
|
53
|
+
await this.runHook('preDeploy');
|
|
54
|
+
await this.releases.switchSymlink(releasePath);
|
|
55
|
+
if (strategy.startApp) {
|
|
56
|
+
const startCtx = {
|
|
57
|
+
...ctx,
|
|
58
|
+
workDir: `${this.config.remotePath}/current`,
|
|
59
|
+
};
|
|
60
|
+
await strategy.startApp(startCtx);
|
|
61
|
+
}
|
|
62
|
+
let healthAttempts;
|
|
63
|
+
let healthResponseMs;
|
|
64
|
+
if (this.config.app === 'backend' && this.config.healthCheck.enabled) {
|
|
65
|
+
const healthResult = await this.healthCheck.perform();
|
|
66
|
+
healthAttempts = healthResult.attempts;
|
|
67
|
+
healthResponseMs = healthResult.responseMs;
|
|
68
|
+
}
|
|
69
|
+
const duration = Math.round((Date.now() - deployStart) / 1000);
|
|
70
|
+
await this.releases.recordRelease({
|
|
71
|
+
timestamp,
|
|
72
|
+
status: 'success',
|
|
73
|
+
duration,
|
|
74
|
+
gitCommit: options.gitCommit,
|
|
75
|
+
healthAttempts,
|
|
76
|
+
healthResponseMs,
|
|
77
|
+
});
|
|
78
|
+
await this.runHook('postDeploy');
|
|
79
|
+
await this.releases.cleanupOldReleases();
|
|
80
|
+
if (this.config.domain) {
|
|
81
|
+
if (this.config.app === 'backend') {
|
|
82
|
+
await this.caddy.configureBackend();
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
await this.caddy.configureFrontend();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
await this.lock.release();
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
await this.lock.release();
|
|
94
|
+
}
|
|
95
|
+
async deployLegacy(strategy, options) {
|
|
96
|
+
const deployStart = Date.now();
|
|
97
|
+
const ctx = {
|
|
98
|
+
config: this.config,
|
|
99
|
+
executor: this.executor,
|
|
100
|
+
workDir: this.config.remotePath,
|
|
101
|
+
cwd: options.cwd,
|
|
102
|
+
skipBuild: options.skipBuild,
|
|
103
|
+
};
|
|
104
|
+
await strategy.stage(ctx);
|
|
105
|
+
if (strategy.setupEnvironment) {
|
|
106
|
+
await strategy.setupEnvironment(ctx);
|
|
107
|
+
}
|
|
108
|
+
await this.runHook('preDeploy');
|
|
109
|
+
if (strategy.startApp) {
|
|
110
|
+
await strategy.startApp(ctx);
|
|
111
|
+
}
|
|
112
|
+
const duration = Math.round((Date.now() - deployStart) / 1000);
|
|
113
|
+
await this.releases.recordRelease({
|
|
114
|
+
timestamp: new Date().toISOString().replace(/[:.]/g, '-'),
|
|
115
|
+
status: 'success',
|
|
116
|
+
duration,
|
|
117
|
+
gitCommit: options.gitCommit,
|
|
118
|
+
});
|
|
119
|
+
await this.runHook('postDeploy');
|
|
120
|
+
if (this.config.domain) {
|
|
121
|
+
if (this.config.app === 'backend') {
|
|
122
|
+
await this.caddy.configureBackend();
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
await this.caddy.configureFrontend();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async runHook(hookName) {
|
|
130
|
+
const hook = this.config.hooks?.[hookName];
|
|
131
|
+
if (!hook)
|
|
132
|
+
return;
|
|
133
|
+
const ctx = {
|
|
134
|
+
config: this.config,
|
|
135
|
+
env: 'production',
|
|
136
|
+
exec: async (cmd) => {
|
|
137
|
+
return this.executor.exec(cmd);
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
try {
|
|
141
|
+
await hook(ctx);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
145
|
+
throw new DeployError(`${hookName} hook failed: ${message}`, hookName);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../../src/domain/deploy/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { RemoteExecutor } from '../remote/executor.js';
|
|
2
|
+
/**
|
|
3
|
+
* Context passed to every deployment strategy method.
|
|
4
|
+
*/
|
|
5
|
+
export interface StrategyContext {
|
|
6
|
+
config: import('../../shared/types.js').ShipnodeConfig;
|
|
7
|
+
executor: RemoteExecutor;
|
|
8
|
+
workDir: string;
|
|
9
|
+
cwd: string;
|
|
10
|
+
skipBuild: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A deployment strategy knows how to stage, prepare, and start
|
|
14
|
+
* a specific kind of application (backend, frontend, etc.).
|
|
15
|
+
*
|
|
16
|
+
* Strategies are adapters at the deployment seam. The orchestrator
|
|
17
|
+
* owns the invariant lifecycle; the strategy owns the app-specific
|
|
18
|
+
* details.
|
|
19
|
+
*/
|
|
20
|
+
export interface DeploymentStrategy {
|
|
21
|
+
readonly name: string;
|
|
22
|
+
/**
|
|
23
|
+
* Stage artifacts onto the remote host.
|
|
24
|
+
*
|
|
25
|
+
* For a backend this usually means rsyncing source files.
|
|
26
|
+
* For a frontend this means building locally and rsyncing build output.
|
|
27
|
+
*/
|
|
28
|
+
stage(ctx: StrategyContext): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Prepare the runtime environment on the remote host.
|
|
31
|
+
*
|
|
32
|
+
* Optional. For backends this is typically dependency installation
|
|
33
|
+
* and remote builds. For static frontends this is usually a no-op.
|
|
34
|
+
*/
|
|
35
|
+
setupEnvironment?(ctx: StrategyContext): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Start or reload the application.
|
|
38
|
+
*
|
|
39
|
+
* Optional. For backend apps this means reloading PM2.
|
|
40
|
+
* For static frontends this is usually a no-op (Caddy serves files).
|
|
41
|
+
*/
|
|
42
|
+
startApp?(ctx: StrategyContext): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../../../src/domain/deploy/strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,uBAAuB,EAAE,cAAc,CAAC;IACvD,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;OAKG;IACH,KAAK,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3C;;;;;OAKG;IACH,gBAAgB,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvD;;;;;OAKG;IACH,QAAQ,CAAC,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy.js","sourceRoot":"","sources":["../../../src/domain/deploy/strategy.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FrameworkDetectionResult, PkgManager } from '../../shared/types.js';
|
|
2
|
+
export declare function parsePackageJson(cwd: string): Promise<Record<string, string> | null>;
|
|
3
|
+
export declare function detectPkgManager(cwd: string): Promise<PkgManager | null>;
|
|
4
|
+
export declare function detectFramework(cwd: string): Promise<FrameworkDetectionResult>;
|
|
5
|
+
export declare function getInstallCommand(pkgManager: PkgManager): string;
|
|
6
|
+
export declare function getRunCommand(pkgManager: PkgManager): string;
|
|
7
|
+
//# sourceMappingURL=detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../../src/domain/framework/detector.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,wBAAwB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGlF,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,CAe1F;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAc9E;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAkBpF;AA0DD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAEhE;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAE5D"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { readFile } from 'fs/promises';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
import { pathExists } from 'fs-extra';
|
|
4
|
+
import { FRAMEWORK_PATTERNS, PKG_MANAGER_COMMANDS } from '../../shared/constants.js';
|
|
5
|
+
export async function parsePackageJson(cwd) {
|
|
6
|
+
const pkgPath = resolve(cwd, 'package.json');
|
|
7
|
+
const exists = await pathExists(pkgPath);
|
|
8
|
+
if (!exists)
|
|
9
|
+
return null;
|
|
10
|
+
try {
|
|
11
|
+
const content = await readFile(pkgPath, 'utf-8');
|
|
12
|
+
const pkg = JSON.parse(content);
|
|
13
|
+
return {
|
|
14
|
+
...(pkg.dependencies ?? {}),
|
|
15
|
+
...(pkg.devDependencies ?? {}),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export async function detectPkgManager(cwd) {
|
|
23
|
+
const lockFiles = [
|
|
24
|
+
['bun.lockb', 'bun'],
|
|
25
|
+
['bun.lock', 'bun'],
|
|
26
|
+
['pnpm-lock.yaml', 'pnpm'],
|
|
27
|
+
['yarn.lock', 'yarn'],
|
|
28
|
+
['package-lock.json', 'npm'],
|
|
29
|
+
];
|
|
30
|
+
for (const [file, pm] of lockFiles) {
|
|
31
|
+
if (await pathExists(resolve(cwd, file)))
|
|
32
|
+
return pm;
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
export async function detectFramework(cwd) {
|
|
37
|
+
const deps = await parsePackageJson(cwd);
|
|
38
|
+
if (!deps) {
|
|
39
|
+
return { name: 'unknown', appType: 'unknown' };
|
|
40
|
+
}
|
|
41
|
+
const depKeys = Object.keys(deps);
|
|
42
|
+
for (const [name, pattern] of Object.entries(FRAMEWORK_PATTERNS)) {
|
|
43
|
+
const matched = pattern.deps.some((d) => depKeys.some((k) => k === d || k.startsWith(d)));
|
|
44
|
+
if (matched) {
|
|
45
|
+
const port = await detectPortFromScripts(cwd);
|
|
46
|
+
const orm = await detectOrm(cwd);
|
|
47
|
+
return { name, appType: pattern.appType, port, orm };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return { name: 'unknown', appType: 'unknown' };
|
|
51
|
+
}
|
|
52
|
+
async function detectPortFromScripts(cwd) {
|
|
53
|
+
const pkgPath = resolve(cwd, 'package.json');
|
|
54
|
+
const exists = await pathExists(pkgPath);
|
|
55
|
+
if (!exists)
|
|
56
|
+
return undefined;
|
|
57
|
+
try {
|
|
58
|
+
const content = await readFile(pkgPath, 'utf-8');
|
|
59
|
+
const pkg = JSON.parse(content);
|
|
60
|
+
const scripts = [pkg.scripts?.start, pkg.scripts?.dev].filter(Boolean).join(' ');
|
|
61
|
+
const patterns = [
|
|
62
|
+
/PORT=(\d+)/,
|
|
63
|
+
/--port[= ](\d+)/,
|
|
64
|
+
/(?:localhost|127\.0\.0\.1):(\d+)/,
|
|
65
|
+
/listen\(['"]?:(\d+)/,
|
|
66
|
+
];
|
|
67
|
+
for (const pattern of patterns) {
|
|
68
|
+
const match = scripts.match(pattern);
|
|
69
|
+
if (match) {
|
|
70
|
+
const port = parseInt(match[1], 10);
|
|
71
|
+
if (port >= 1 && port <= 65535)
|
|
72
|
+
return port;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// ignore
|
|
78
|
+
}
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
async function detectOrm(cwd) {
|
|
82
|
+
const deps = await parsePackageJson(cwd);
|
|
83
|
+
if (!deps)
|
|
84
|
+
return undefined;
|
|
85
|
+
const depKeys = Object.keys(deps);
|
|
86
|
+
const ormMap = {
|
|
87
|
+
'prisma': 'Prisma',
|
|
88
|
+
'@prisma/client': 'Prisma',
|
|
89
|
+
'drizzle-orm': 'Drizzle',
|
|
90
|
+
'typeorm': 'TypeORM',
|
|
91
|
+
'sequelize': 'Sequelize',
|
|
92
|
+
'knex': 'Knex',
|
|
93
|
+
'mongoose': 'Mongoose',
|
|
94
|
+
'@adonisjs/lucid': 'AdonisJS Lucid',
|
|
95
|
+
};
|
|
96
|
+
for (const [dep, orm] of Object.entries(ormMap)) {
|
|
97
|
+
if (depKeys.some((k) => k === dep || k.startsWith(dep))) {
|
|
98
|
+
return orm;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
export function getInstallCommand(pkgManager) {
|
|
104
|
+
return PKG_MANAGER_COMMANDS[pkgManager]?.install ?? 'npm ci --production';
|
|
105
|
+
}
|
|
106
|
+
export function getRunCommand(pkgManager) {
|
|
107
|
+
return PKG_MANAGER_COMMANDS[pkgManager]?.run ?? 'npm run';
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.js","sourceRoot":"","sources":["../../../src/domain/framework/detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReleaseRecord } from '../../shared/types.js';
|
|
2
|
+
import type { RemoteExecutor } from '../../domain/remote/executor.js';
|
|
3
|
+
export declare class ReleaseManager {
|
|
4
|
+
private executor;
|
|
5
|
+
private remotePath;
|
|
6
|
+
private keepReleases;
|
|
7
|
+
constructor(executor: RemoteExecutor, remotePath: string, keepReleases: number);
|
|
8
|
+
createReleasePath(timestamp: string): Promise<string>;
|
|
9
|
+
setupReleaseStructure(): Promise<void>;
|
|
10
|
+
switchSymlink(releasePath: string): Promise<void>;
|
|
11
|
+
recordRelease(record: ReleaseRecord): Promise<void>;
|
|
12
|
+
cleanupOldReleases(): Promise<void>;
|
|
13
|
+
listReleases(): Promise<ReleaseRecord[]>;
|
|
14
|
+
}
|
|
15
|
+
export declare class DeployLock {
|
|
16
|
+
private executor;
|
|
17
|
+
private remotePath;
|
|
18
|
+
constructor(executor: RemoteExecutor, remotePath: string);
|
|
19
|
+
acquire(): Promise<void>;
|
|
20
|
+
release(): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/domain/release/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAGtE,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,YAAY;gBAFZ,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM;IAGxB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMrD,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtC,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjD,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBnD,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBnC,YAAY,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;CAS/C;AAED,qBAAa,UAAU;IAEnB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,UAAU;gBADV,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,MAAM;IAGtB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAM/B"}
|