d3ployer 0.0.10 → 0.0.12
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/README.md +46 -30
- package/dist/bin.js +0 -0
- package/dist/cli.js +9 -4
- package/dist/config.d.ts +0 -1
- package/dist/config.js +27 -35
- package/dist/def.d.ts +26 -20
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/renderer.d.ts +23 -0
- package/dist/renderer.js +153 -0
- package/dist/runner.d.ts +8 -4
- package/dist/runner.js +36 -28
- package/dist/tasks/clearTarget.d.ts +2 -0
- package/dist/tasks/clearTarget.js +15 -0
- package/dist/tasks/download.d.ts +3 -0
- package/dist/tasks/download.js +27 -0
- package/dist/tasks/index.d.ts +6 -0
- package/dist/tasks/index.js +76 -0
- package/dist/tasks/installPackages.d.ts +3 -0
- package/dist/tasks/installPackages.js +38 -0
- package/dist/tasks/printDeployment.d.ts +2 -0
- package/dist/tasks/printDeployment.js +8 -0
- package/dist/tasks/printLogs.d.ts +5 -0
- package/dist/tasks/printLogs.js +69 -0
- package/dist/tasks/setupDocker.d.ts +4 -0
- package/dist/tasks/setupDocker.js +33 -0
- package/dist/tasks/setupPm2.d.ts +3 -0
- package/dist/tasks/setupPm2.js +14 -0
- package/dist/tasks/symlinks.d.ts +3 -0
- package/dist/tasks/symlinks.js +18 -0
- package/dist/tasks/upload.d.ts +7 -0
- package/dist/tasks/upload.js +54 -0
- package/package.json +4 -4
- package/dist/defaultTasks.d.ts +0 -9
- package/dist/defaultTasks.js +0 -303
package/dist/defaultTasks.js
DELETED
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
import confirm from '@inquirer/confirm';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { Exception } from './utils/index.js';
|
|
5
|
-
export function buildRsyncCommand(server, source, dest, files, options = {}) {
|
|
6
|
-
const { delete: useDelete = true, } = options;
|
|
7
|
-
const args = ['rsync', '-avz', '--progress=info2'];
|
|
8
|
-
if (useDelete) {
|
|
9
|
-
args.push('--delete');
|
|
10
|
-
}
|
|
11
|
-
// ssh shell
|
|
12
|
-
const sshParts = ['ssh'];
|
|
13
|
-
if (server.port && server.port !== 22) {
|
|
14
|
-
sshParts.push(`-p ${server.port}`);
|
|
15
|
-
}
|
|
16
|
-
if (server.authMethod === 'key' && server.privateKey) {
|
|
17
|
-
sshParts.push(`-i ${server.privateKey}`);
|
|
18
|
-
}
|
|
19
|
-
sshParts.push('-o StrictHostKeyChecking=no');
|
|
20
|
-
args.push('-e', `"${sshParts.join(' ')}"`);
|
|
21
|
-
// include/exclude
|
|
22
|
-
if (files.exclude) {
|
|
23
|
-
for (const pattern of files.exclude) {
|
|
24
|
-
args.push(`--exclude="${pattern}"`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
if (files.include) {
|
|
28
|
-
for (const pattern of files.include) {
|
|
29
|
-
args.push(`--include="${pattern}"`);
|
|
30
|
-
}
|
|
31
|
-
args.push('--exclude="*"');
|
|
32
|
-
}
|
|
33
|
-
args.push(source, dest);
|
|
34
|
-
return args.join(' ');
|
|
35
|
-
}
|
|
36
|
-
const uploadSkip = (ctx) => {
|
|
37
|
-
const files = ctx.config.files;
|
|
38
|
-
return !files
|
|
39
|
-
? 'No files configuration defined'
|
|
40
|
-
: false;
|
|
41
|
-
};
|
|
42
|
-
const uploadTask = async (ctx, ph) => {
|
|
43
|
-
const files = ctx.config.files;
|
|
44
|
-
const localBase = files.basePath?.startsWith('/')
|
|
45
|
-
? files.basePath
|
|
46
|
-
: path.resolve(ctx.config.rootDir, files.basePath ?? '.');
|
|
47
|
-
const remotePath = ph.deployPath;
|
|
48
|
-
const dest = `${ctx.server.username}@${ctx.server.host}:${remotePath}`;
|
|
49
|
-
const source = localBase.endsWith('/') ? localBase : localBase + '/';
|
|
50
|
-
await ctx.run(`mkdir -p ${remotePath}`);
|
|
51
|
-
const command = buildRsyncCommand(ctx.server, source, dest, files, {
|
|
52
|
-
delete: true,
|
|
53
|
-
});
|
|
54
|
-
console.log(chalk.grey(command));
|
|
55
|
-
await ctx.runLocal(command);
|
|
56
|
-
};
|
|
57
|
-
export const downloadSkip = (ctx) => {
|
|
58
|
-
const files = ctx.taskConfig;
|
|
59
|
-
return !files
|
|
60
|
-
? 'No files configuration provided in task config'
|
|
61
|
-
: false;
|
|
62
|
-
};
|
|
63
|
-
export const downloadTask = async (ctx, ph) => {
|
|
64
|
-
const files = ctx.taskConfig;
|
|
65
|
-
if (!files) {
|
|
66
|
-
throw new Exception('No files configuration provided in task config', 1784523741234);
|
|
67
|
-
}
|
|
68
|
-
const localBase = files.basePath?.startsWith('/')
|
|
69
|
-
? files.basePath
|
|
70
|
-
: path.resolve(ctx.config.rootDir, files.basePath ?? '.');
|
|
71
|
-
const remotePath = ph.deployPath;
|
|
72
|
-
const source = `${ctx.server.username}@${ctx.server.host}:${remotePath}/`;
|
|
73
|
-
const dest = localBase.endsWith('/') ? localBase : localBase + '/';
|
|
74
|
-
const command = buildRsyncCommand(ctx.server, source, dest, files, {
|
|
75
|
-
delete: false,
|
|
76
|
-
});
|
|
77
|
-
console.log(chalk.grey(command));
|
|
78
|
-
await ctx.runLocal(command);
|
|
79
|
-
};
|
|
80
|
-
const symlinksSkip = (ctx) => {
|
|
81
|
-
const symlinks = ctx.config.symlinks;
|
|
82
|
-
return !symlinks || symlinks.length === 0
|
|
83
|
-
? 'No symlinks defined in config'
|
|
84
|
-
: false;
|
|
85
|
-
};
|
|
86
|
-
const symlinksTask = async (ctx, ph) => {
|
|
87
|
-
const symlinks = ctx.config.symlinks;
|
|
88
|
-
for (const link of symlinks) {
|
|
89
|
-
const target = link.target.startsWith('/')
|
|
90
|
-
? link.target
|
|
91
|
-
: `${ph.deployPath}/${link.target}`;
|
|
92
|
-
const path = link.path.startsWith('/')
|
|
93
|
-
? link.path
|
|
94
|
-
: `${ph.deployPath}/${link.path}`;
|
|
95
|
-
await ctx.run(`ln -sfn ${target} ${path}`);
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
const depInstallSkip = (ctx) => {
|
|
99
|
-
if (ctx.server.packageManager !== undefined) {
|
|
100
|
-
return ctx.server.packageManager === false
|
|
101
|
-
? 'Package manager disabled for server'
|
|
102
|
-
: false;
|
|
103
|
-
}
|
|
104
|
-
if (ctx.config.packageManager !== undefined) {
|
|
105
|
-
return ctx.config.packageManager === false
|
|
106
|
-
? 'Package manager disabled in config'
|
|
107
|
-
: false;
|
|
108
|
-
}
|
|
109
|
-
return false;
|
|
110
|
-
};
|
|
111
|
-
const depInstallTask = async (ctx) => {
|
|
112
|
-
const config = {
|
|
113
|
-
manager: 'npm',
|
|
114
|
-
productionOnly: true,
|
|
115
|
-
...ctx.config.packageManager,
|
|
116
|
-
...ctx.server.packageManager,
|
|
117
|
-
};
|
|
118
|
-
let cmd = `${config.manager} install`;
|
|
119
|
-
if (config.productionOnly) {
|
|
120
|
-
if (config.manager === 'npm') {
|
|
121
|
-
cmd += ' --omit=dev';
|
|
122
|
-
}
|
|
123
|
-
else if (config.manager === 'yarn') {
|
|
124
|
-
cmd += ' --production';
|
|
125
|
-
}
|
|
126
|
-
else if (config.manager === 'pnpm') {
|
|
127
|
-
cmd += ' --prod';
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
throw new Exception(`Unsupported package manager "${config.manager}"`, 1774823752134);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
await ctx.run(cmd);
|
|
134
|
-
};
|
|
135
|
-
const pm2SetupSkip = async (ctx) => {
|
|
136
|
-
if (ctx.config.pm2 === false) {
|
|
137
|
-
return 'PM2 disabled';
|
|
138
|
-
}
|
|
139
|
-
const pm2ConfigExists = await ctx.test('test -f pm2.config.*');
|
|
140
|
-
if (!pm2ConfigExists) {
|
|
141
|
-
return 'PM2 config not found';
|
|
142
|
-
}
|
|
143
|
-
return false;
|
|
144
|
-
};
|
|
145
|
-
const pm2SetupTask = async (ctx) => {
|
|
146
|
-
await ctx.run('pm2 start pm2.config.* --update-env');
|
|
147
|
-
await ctx.run('pm2 save');
|
|
148
|
-
};
|
|
149
|
-
function buildDockerComposeTestCmd(dockerComposeConfig) {
|
|
150
|
-
if (dockerComposeConfig === false) {
|
|
151
|
-
return 'false';
|
|
152
|
-
}
|
|
153
|
-
const configFiles = dockerComposeConfig.configFiles ?? [
|
|
154
|
-
'docker-compose.yml',
|
|
155
|
-
'docker-compose.yaml',
|
|
156
|
-
'compose.yml',
|
|
157
|
-
'compose.yaml',
|
|
158
|
-
];
|
|
159
|
-
const testCmdPart = configFiles.map(f => `-f ${f}`);
|
|
160
|
-
return `test ${testCmdPart.join(' -o ')}`;
|
|
161
|
-
}
|
|
162
|
-
const dockerSetupSkip = async (ctx) => {
|
|
163
|
-
if (ctx.config.dockerCompose === false) {
|
|
164
|
-
return 'Docker Compose disabled';
|
|
165
|
-
}
|
|
166
|
-
const testCmd = buildDockerComposeTestCmd(ctx.config.dockerCompose);
|
|
167
|
-
const composeExists = await ctx.test(testCmd);
|
|
168
|
-
if (!composeExists) {
|
|
169
|
-
return 'Docker Compose config not found';
|
|
170
|
-
}
|
|
171
|
-
return false;
|
|
172
|
-
};
|
|
173
|
-
const dockerSetupTask = async (ctx) => {
|
|
174
|
-
if (ctx.config.dockerCompose === false) {
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
const configFiles = ctx.config.dockerCompose?.configFiles ?? [];
|
|
178
|
-
const options = configFiles.map(f => `-f ${f}`).join(' ');
|
|
179
|
-
await ctx.run(`docker compose ${options} down --remove-orphans`);
|
|
180
|
-
await ctx.run(`docker compose ${options} up -d --build`);
|
|
181
|
-
};
|
|
182
|
-
const clearTargetTask = async (ctx, ph) => {
|
|
183
|
-
const confirmed = await confirm({
|
|
184
|
-
message: chalk.red(`Remove entire deploy path ${ph.deployPath} on ${ctx.server.host}?`),
|
|
185
|
-
default: false,
|
|
186
|
-
});
|
|
187
|
-
if (!confirmed) {
|
|
188
|
-
console.log(chalk.yellow('Skipped clearing target'));
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
await ctx.run(`rm -rf ${ph.deployPath}`);
|
|
192
|
-
};
|
|
193
|
-
const printDeploymentTask = async (ctx, ph) => {
|
|
194
|
-
await ctx.run('date');
|
|
195
|
-
console.log(chalk.cyan('Deployment directory'), ph.deployPath);
|
|
196
|
-
await ctx.run('ls -la .');
|
|
197
|
-
console.log(chalk.cyan('Directory size'));
|
|
198
|
-
await ctx.run('du -hd 1 .');
|
|
199
|
-
};
|
|
200
|
-
const logsStreamSkip = async (ctx) => {
|
|
201
|
-
if (ctx.config.logs === false) {
|
|
202
|
-
return 'Logs streaming disabled';
|
|
203
|
-
}
|
|
204
|
-
const hasPm2 = ctx.config.pm2 !== false && await ctx.test('test -f pm2.config.*');
|
|
205
|
-
let hasDocker = false;
|
|
206
|
-
if (ctx.config.dockerCompose) {
|
|
207
|
-
const testCmd = buildDockerComposeTestCmd(ctx.config.dockerCompose);
|
|
208
|
-
hasDocker = await ctx.test(testCmd);
|
|
209
|
-
}
|
|
210
|
-
if (!hasPm2 && !hasDocker) {
|
|
211
|
-
return 'No PM2 or Docker Compose detected';
|
|
212
|
-
}
|
|
213
|
-
return false;
|
|
214
|
-
};
|
|
215
|
-
const logsStreamTask = async (ctx) => {
|
|
216
|
-
const logsConfig = {
|
|
217
|
-
time: 3,
|
|
218
|
-
...ctx.config.logs,
|
|
219
|
-
};
|
|
220
|
-
const time = logsConfig.time;
|
|
221
|
-
const hasPm2 = ctx.config.pm2 !== false
|
|
222
|
-
&& await ctx.test('test -f pm2.config.*');
|
|
223
|
-
let hasDocker = false;
|
|
224
|
-
if (ctx.config.dockerCompose !== false) {
|
|
225
|
-
const testCmd = buildDockerComposeTestCmd(ctx.config.dockerCompose);
|
|
226
|
-
hasDocker = await ctx.test(testCmd);
|
|
227
|
-
}
|
|
228
|
-
if (hasPm2) {
|
|
229
|
-
const pm2ConfigRaw = await ctx.run('cat pm2.config.*', { printOutput: false });
|
|
230
|
-
const nameMatch = pm2ConfigRaw.stdout.match(/name: ['"](?<name>.+?)['"]/);
|
|
231
|
-
const name = nameMatch.groups?.name ?? 'all';
|
|
232
|
-
console.log(chalk.cyan(`Streaming PM2 logs for ${time}s...`));
|
|
233
|
-
await ctx.run(`timeout ${time} pm2 logs "${name}" || true`, { printOutput: true, ignoreError: true });
|
|
234
|
-
}
|
|
235
|
-
else if (hasDocker && ctx.config.dockerCompose) {
|
|
236
|
-
const configFiles = ctx.config.dockerCompose.configFiles ?? [];
|
|
237
|
-
const options = configFiles.map(f => `-f ${f}`).join(' ');
|
|
238
|
-
console.log(chalk.cyan(`Streaming Docker Compose logs for ${time}s...`));
|
|
239
|
-
await ctx.run(`timeout ${time} docker compose ${options} logs --tail=10 -f || true`, {
|
|
240
|
-
printOutput: true,
|
|
241
|
-
ignoreError: true,
|
|
242
|
-
});
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
export const defaultTasks = {
|
|
246
|
-
clearTarget: {
|
|
247
|
-
name: 'Clear target',
|
|
248
|
-
task: clearTargetTask,
|
|
249
|
-
},
|
|
250
|
-
upload: {
|
|
251
|
-
name: 'Upload files',
|
|
252
|
-
skip: uploadSkip,
|
|
253
|
-
task: uploadTask,
|
|
254
|
-
},
|
|
255
|
-
download: {
|
|
256
|
-
name: 'Download files',
|
|
257
|
-
skip: downloadSkip,
|
|
258
|
-
task: downloadTask,
|
|
259
|
-
},
|
|
260
|
-
symlinks: {
|
|
261
|
-
name: 'Create symlinks',
|
|
262
|
-
skip: symlinksSkip,
|
|
263
|
-
task: symlinksTask,
|
|
264
|
-
},
|
|
265
|
-
depInstall: {
|
|
266
|
-
name: 'Install dependencies',
|
|
267
|
-
skip: depInstallSkip,
|
|
268
|
-
task: depInstallTask,
|
|
269
|
-
},
|
|
270
|
-
pm2Setup: {
|
|
271
|
-
name: 'PM2 setup',
|
|
272
|
-
skip: pm2SetupSkip,
|
|
273
|
-
task: pm2SetupTask,
|
|
274
|
-
},
|
|
275
|
-
dockerSetup: {
|
|
276
|
-
name: 'Docker Compose setup',
|
|
277
|
-
skip: dockerSetupSkip,
|
|
278
|
-
task: dockerSetupTask,
|
|
279
|
-
},
|
|
280
|
-
printDeployment: {
|
|
281
|
-
name: 'Print deployment info',
|
|
282
|
-
task: printDeploymentTask,
|
|
283
|
-
},
|
|
284
|
-
logsStream: {
|
|
285
|
-
name: 'Logs stream',
|
|
286
|
-
skip: logsStreamSkip,
|
|
287
|
-
task: logsStreamTask,
|
|
288
|
-
},
|
|
289
|
-
};
|
|
290
|
-
export const defaultScenarios = {
|
|
291
|
-
deploy: {
|
|
292
|
-
name: 'Deploy',
|
|
293
|
-
tasks: [
|
|
294
|
-
'upload',
|
|
295
|
-
'symlinks',
|
|
296
|
-
'dep:install',
|
|
297
|
-
'pm2:setup',
|
|
298
|
-
'docker:setup',
|
|
299
|
-
'print:deployment',
|
|
300
|
-
'logs:stream',
|
|
301
|
-
],
|
|
302
|
-
},
|
|
303
|
-
};
|