@catapultjs/deploy 0.0.1-alpha.19
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 +24 -0
- package/build/bin/run.d.ts +2 -0
- package/build/bin/run.js +60 -0
- package/build/bin/run.js.map +1 -0
- package/build/commands/deploy.d.ts +7 -0
- package/build/commands/deploy.js +55 -0
- package/build/commands/deploy.js.map +1 -0
- package/build/commands/init.d.ts +6 -0
- package/build/commands/init.js +41 -0
- package/build/commands/init.js.map +1 -0
- package/build/commands/list_pipeline.d.ts +6 -0
- package/build/commands/list_pipeline.js +14 -0
- package/build/commands/list_pipeline.js.map +1 -0
- package/build/commands/list_releases.d.ts +6 -0
- package/build/commands/list_releases.js +40 -0
- package/build/commands/list_releases.js.map +1 -0
- package/build/commands/list_tasks.d.ts +6 -0
- package/build/commands/list_tasks.js +23 -0
- package/build/commands/list_tasks.js.map +1 -0
- package/build/commands/rollback.d.ts +6 -0
- package/build/commands/rollback.js +25 -0
- package/build/commands/rollback.js.map +1 -0
- package/build/commands/run_task.d.ts +7 -0
- package/build/commands/run_task.js +36 -0
- package/build/commands/run_task.js.map +1 -0
- package/build/commands/setup.d.ts +6 -0
- package/build/commands/setup.js +22 -0
- package/build/commands/setup.js.map +1 -0
- package/build/commands/status.d.ts +6 -0
- package/build/commands/status.js +46 -0
- package/build/commands/status.js.map +1 -0
- package/build/commands/version.d.ts +6 -0
- package/build/commands/version.js +14 -0
- package/build/commands/version.js.map +1 -0
- package/build/index.d.ts +5 -0
- package/build/index.js +6 -0
- package/build/index.js.map +1 -0
- package/build/recipes/adonisjs.d.ts +7 -0
- package/build/recipes/adonisjs.js +19 -0
- package/build/recipes/adonisjs.js.map +1 -0
- package/build/recipes/pm2.d.ts +11 -0
- package/build/recipes/pm2.js +52 -0
- package/build/recipes/pm2.js.map +1 -0
- package/build/recipes/rsync.d.ts +6 -0
- package/build/recipes/rsync.js +14 -0
- package/build/recipes/rsync.js.map +1 -0
- package/build/src/base_command.d.ts +6 -0
- package/build/src/base_command.js +41 -0
- package/build/src/base_command.js.map +1 -0
- package/build/src/ctx.d.ts +3 -0
- package/build/src/ctx.js +10 -0
- package/build/src/ctx.js.map +1 -0
- package/build/src/define_config.d.ts +2 -0
- package/build/src/define_config.js +6 -0
- package/build/src/define_config.js.map +1 -0
- package/build/src/host.d.ts +21 -0
- package/build/src/host.js +237 -0
- package/build/src/host.js.map +1 -0
- package/build/src/task.d.ts +28 -0
- package/build/src/task.js +122 -0
- package/build/src/task.js.map +1 -0
- package/build/src/types.d.ts +52 -0
- package/build/src/types.js +2 -0
- package/build/src/types.js.map +1 -0
- package/build/src/utils.d.ts +10 -0
- package/build/src/utils.js +43 -0
- package/build/src/utils.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
import { task, after, onStatus, bin, getContext, getPaths, ssh, q } from "../index.js";
|
|
3
|
+
onStatus(async (_ctx, host) => {
|
|
4
|
+
const { stdout } = await ssh(host, `set +e\n${bin('pm2')} --version || true`);
|
|
5
|
+
console.log(stdout.trim() ? `pm2 ${stdout.trim()}` : 'pm2 unavailable');
|
|
6
|
+
});
|
|
7
|
+
task('pm2:start', async () => {
|
|
8
|
+
const { host, deployCtx } = getContext();
|
|
9
|
+
const paths = getPaths(host.deployPath, deployCtx.release);
|
|
10
|
+
await ssh(host, `
|
|
11
|
+
set -e
|
|
12
|
+
cd ${q(paths.current)}
|
|
13
|
+
${bin('pm2')} startOrReload ecosystem.config.cjs --update-env
|
|
14
|
+
${bin('pm2')} save
|
|
15
|
+
`);
|
|
16
|
+
console.log(`✅ [${host.name}] pm2 started`);
|
|
17
|
+
});
|
|
18
|
+
after('deploy:publish', 'pm2:start');
|
|
19
|
+
task('pm2:logs', async () => {
|
|
20
|
+
const { host, deployCtx } = getContext();
|
|
21
|
+
const paths = getPaths(host.deployPath, deployCtx.release);
|
|
22
|
+
const require = createRequire(import.meta.url);
|
|
23
|
+
const ecosystem = require(process.cwd() + '/ecosystem.config.cjs');
|
|
24
|
+
const names = (ecosystem?.apps ?? []).map((a) => a.name).join(' ');
|
|
25
|
+
const { stdout } = await ssh(host, `set -e\ncd ${q(paths.current)}\n${bin('pm2')} logs ${names} --nostream --lines 50`);
|
|
26
|
+
console.log(stdout.trim());
|
|
27
|
+
});
|
|
28
|
+
task('pm2:list', async () => {
|
|
29
|
+
const { host, deployCtx } = getContext();
|
|
30
|
+
const paths = getPaths(host.deployPath, deployCtx.release);
|
|
31
|
+
const { stdout } = await ssh(host, `set -e\ncd ${q(paths.current)}\n${bin('pm2')} list`);
|
|
32
|
+
console.log(stdout.trim());
|
|
33
|
+
});
|
|
34
|
+
task('pm2:stop', async () => {
|
|
35
|
+
const { host, deployCtx } = getContext();
|
|
36
|
+
const paths = getPaths(host.deployPath, deployCtx.release);
|
|
37
|
+
await ssh(host, `set -e\ncd ${q(paths.current)}\n${bin('pm2')} stop ecosystem.config.cjs`);
|
|
38
|
+
console.log(`✅ [${host.name}] pm2 stopped`);
|
|
39
|
+
});
|
|
40
|
+
task('pm2:reload', async () => {
|
|
41
|
+
const { host, deployCtx } = getContext();
|
|
42
|
+
const paths = getPaths(host.deployPath, deployCtx.release);
|
|
43
|
+
await ssh(host, `set -e\ncd ${q(paths.current)}\n${bin('pm2')} reload ecosystem.config.cjs --update-env`);
|
|
44
|
+
console.log(`✅ [${host.name}] pm2 reloaded`);
|
|
45
|
+
});
|
|
46
|
+
task('pm2:restart', async () => {
|
|
47
|
+
const { host, deployCtx } = getContext();
|
|
48
|
+
const paths = getPaths(host.deployPath, deployCtx.release);
|
|
49
|
+
await ssh(host, `set -e\ncd ${q(paths.current)}\n${bin('pm2')} restart ecosystem.config.cjs --update-env`);
|
|
50
|
+
console.log(`✅ [${host.name}] pm2 restarted`);
|
|
51
|
+
});
|
|
52
|
+
//# sourceMappingURL=pm2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pm2.js","sourceRoot":"","sources":["../../recipes/pm2.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { $ } from 'execa';
|
|
2
|
+
import { task, get, getContext, remove } from "../index.js";
|
|
3
|
+
import { rsyncSshFlag, resolveSshArgs } from "../src/utils.js";
|
|
4
|
+
remove('deploy:check_branch');
|
|
5
|
+
task('deploy:update_code', async () => {
|
|
6
|
+
const { host, paths } = getContext();
|
|
7
|
+
const [target] = resolveSshArgs(host);
|
|
8
|
+
const args = ['-az', '-e', rsyncSshFlag(host)];
|
|
9
|
+
for (const pattern of get('rsync_excludes', [])) {
|
|
10
|
+
args.push(`--exclude=${pattern}`);
|
|
11
|
+
}
|
|
12
|
+
await $ `rsync ${args} ./ ${target}:${paths.release}/`;
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=rsync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rsync.js","sourceRoot":"","sources":["../../recipes/rsync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAE9D,MAAM,CAAC,qBAAqB,CAAC,CAAA;AAQ7B,IAAI,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;IACpC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,UAAU,EAAE,CAAA;IACpC,MAAM,CAAC,MAAM,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,CAAA;IACrC,MAAM,IAAI,GAAa,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAA;IACxD,KAAK,MAAM,OAAO,IAAI,GAAG,CAAW,gBAAgB,EAAE,EAAE,CAAC,EAAE,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,aAAa,OAAO,EAAE,CAAC,CAAA;IACnC,CAAC;IACD,MAAM,CAAC,CAAA,SAAS,IAAI,OAAO,MAAM,IAAI,KAAK,CAAC,OAAO,GAAG,CAAA;AACvD,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { BaseCommand, flags } from '@adonisjs/ace';
|
|
11
|
+
import { getCtx } from "./ctx.js";
|
|
12
|
+
export class BaseDeployCommand extends BaseCommand {
|
|
13
|
+
async selectHosts() {
|
|
14
|
+
const ctx = getCtx();
|
|
15
|
+
if (this.host) {
|
|
16
|
+
const hosts = ctx.config.hosts.filter((h) => h.name === this.host);
|
|
17
|
+
if (hosts.length === 0) {
|
|
18
|
+
this.logger.error(`Unknown host: ${this.host}`);
|
|
19
|
+
this.exitCode = 1;
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return hosts;
|
|
23
|
+
}
|
|
24
|
+
if (ctx.config.hosts.length > 1) {
|
|
25
|
+
const selected = await this.prompt.multiple('Select hosts', ctx.config.hosts.map((h) => ({ name: h.name, message: h.name })));
|
|
26
|
+
const hosts = ctx.config.hosts.filter((h) => selected.includes(h.name));
|
|
27
|
+
if (hosts.length === 0) {
|
|
28
|
+
this.logger.error('No host selected');
|
|
29
|
+
this.exitCode = 1;
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return hosts;
|
|
33
|
+
}
|
|
34
|
+
return ctx.config.hosts;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
__decorate([
|
|
38
|
+
flags.string({ description: 'Target a specific host' }),
|
|
39
|
+
__metadata("design:type", Object)
|
|
40
|
+
], BaseDeployCommand.prototype, "host", void 0);
|
|
41
|
+
//# sourceMappingURL=base_command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base_command.js","sourceRoot":"","sources":["../../src/base_command.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,MAAM,OAAgB,iBAAkB,SAAQ,WAAW;IAI/C,KAAK,CAAC,WAAW;QACzB,MAAM,GAAG,GAAG,MAAM,EAAE,CAAA;QAEpB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAA;YAClE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;gBAC/C,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAA;gBACjB,OAAO,IAAI,CAAA;YACb,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CACzC,cAAc,EACd,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CACjE,CAAA;YACD,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;YACvE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAA;gBACrC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAA;gBACjB,OAAO,IAAI,CAAA;YACb,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;QAED,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,CAAA;IACzB,CAAC;CACF;AA/BS;IADP,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC;;+CACxB"}
|
package/build/src/ctx.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ctx.js","sourceRoot":"","sources":["../../src/ctx.ts"],"names":[],"mappings":"AAEA,IAAI,IAAI,GAAyB,IAAI,CAAA;AAErC,MAAM,UAAU,MAAM,CAAC,GAAkB;IACvC,IAAI,GAAG,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,MAAM;IACpB,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAA;IAC3E,OAAO,IAAI,CAAA;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../src/define_config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAc;IAC/C,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IAC9D,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,CAAA;AACxD,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Host, DeployContext, Hooks, HookContext } from './types.ts';
|
|
2
|
+
declare module './types.ts' {
|
|
3
|
+
interface TaskRegistry {
|
|
4
|
+
'deploy:lock': true;
|
|
5
|
+
'deploy:check_branch': true;
|
|
6
|
+
'deploy:release': true;
|
|
7
|
+
'deploy:update_code': true;
|
|
8
|
+
'deploy:shared': true;
|
|
9
|
+
'deploy:publish': true;
|
|
10
|
+
'deploy:trace_release': true;
|
|
11
|
+
'deploy:healthcheck': true;
|
|
12
|
+
'deploy:unlock': true;
|
|
13
|
+
'deploy:cleanup': true;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export declare function runHook(ctx: DeployContext, name: keyof Hooks, context?: HookContext): Promise<void>;
|
|
17
|
+
export declare function setupHost(ctx: DeployContext, host: Host): Promise<void>;
|
|
18
|
+
export declare function getCurrentRelease(ctx: DeployContext, host: Host): Promise<string | null>;
|
|
19
|
+
export declare function getPreviousReleaseName(ctx: DeployContext, host: Host): Promise<string | null>;
|
|
20
|
+
export declare function rollbackHost(ctx: DeployContext, host: Host): Promise<void>;
|
|
21
|
+
export declare function deployHost(ctx: DeployContext, host: Host): Promise<void>;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { $ } from 'execa';
|
|
2
|
+
import { q, getPaths, ssh, sleep } from "./utils.js";
|
|
3
|
+
import { task, run, getContext, runTask, getPipeline, get } from "./task.js";
|
|
4
|
+
export async function runHook(ctx, name, context = {}) {
|
|
5
|
+
if (!ctx.hooks[name])
|
|
6
|
+
return;
|
|
7
|
+
console.log(`==> hook: ${name}`);
|
|
8
|
+
await ctx.hooks[name](context);
|
|
9
|
+
}
|
|
10
|
+
task('deploy:lock', async () => {
|
|
11
|
+
const { host, deployCtx, paths } = getContext();
|
|
12
|
+
try {
|
|
13
|
+
await ssh(host, `
|
|
14
|
+
set -e
|
|
15
|
+
if [ -f ${q(paths.lock)} ]; then
|
|
16
|
+
echo "Deploy lock already present: ${paths.lock}" >&2
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
echo ${q(deployCtx.release)} > ${q(paths.lock)}
|
|
20
|
+
`, { quiet: true });
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
throw new Error(error.stderr?.trim() || error.message);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
task('deploy:unlock', async () => {
|
|
27
|
+
const { host, paths } = getContext();
|
|
28
|
+
await ssh(host, `
|
|
29
|
+
set +e
|
|
30
|
+
rm -f ${q(paths.lock)}
|
|
31
|
+
true
|
|
32
|
+
`);
|
|
33
|
+
});
|
|
34
|
+
task('deploy:check_branch', async () => {
|
|
35
|
+
const { host, deployCtx } = getContext();
|
|
36
|
+
if (!host.branch)
|
|
37
|
+
return;
|
|
38
|
+
const branchName = typeof host.branch === 'object' ? host.branch.name : host.branch;
|
|
39
|
+
let repository = deployCtx.config.repository;
|
|
40
|
+
if (!repository) {
|
|
41
|
+
repository = (await $ `git remote get-url origin`).stdout.trim();
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
await $ `git ls-remote --exit-code --heads ${repository} ${branchName}`;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
throw new Error(`[${host.name}] branch "${branchName}" does not exist on remote ${repository}`);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
task('deploy:release', () => {
|
|
51
|
+
run('mkdir -p {{release_path}}');
|
|
52
|
+
});
|
|
53
|
+
task('deploy:update_code', async () => {
|
|
54
|
+
const { host, paths, deployCtx } = getContext();
|
|
55
|
+
if (!host.branch)
|
|
56
|
+
throw new Error(`[${host.name}] git mode requires "branch" on host`);
|
|
57
|
+
const branchName = typeof host.branch === 'object' ? host.branch.name : host.branch;
|
|
58
|
+
let repository = deployCtx.config.repository;
|
|
59
|
+
if (!repository) {
|
|
60
|
+
repository = (await $ `git remote get-url origin`).stdout.trim();
|
|
61
|
+
}
|
|
62
|
+
await ssh(host, `set -e\ngit clone --depth 1 --branch ${q(branchName)} ${q(repository)} ${q(paths.release)}`);
|
|
63
|
+
});
|
|
64
|
+
task('deploy:shared', () => {
|
|
65
|
+
const dirs = get('writable_dirs', []);
|
|
66
|
+
const files = get('shared_files', []);
|
|
67
|
+
for (const dir of dirs) {
|
|
68
|
+
run(`rm -rf {{release_path}}/${dir}`);
|
|
69
|
+
run(`ln -sfn {{shared_path}}/${dir} {{release_path}}/${dir}`);
|
|
70
|
+
}
|
|
71
|
+
for (const file of files) {
|
|
72
|
+
run(`rm -f {{release_path}}/${file}`);
|
|
73
|
+
run(`ln -sfn {{shared_path}}/${file} {{release_path}}/${file}`);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
task('deploy:publish', () => {
|
|
77
|
+
run('ln -sfn {{release_path}} {{current_path}}');
|
|
78
|
+
});
|
|
79
|
+
task('deploy:trace_release', async () => {
|
|
80
|
+
const { host, deployCtx } = getContext();
|
|
81
|
+
const branch = typeof host.branch === 'object' ? host.branch.name : (host.branch ?? 'unknown');
|
|
82
|
+
let commit = 'unknown';
|
|
83
|
+
let user = 'unknown';
|
|
84
|
+
try {
|
|
85
|
+
commit = (await $ `git rev-parse HEAD`).stdout.trim();
|
|
86
|
+
user = (await $ `git config user.name`).stdout.trim();
|
|
87
|
+
}
|
|
88
|
+
catch { }
|
|
89
|
+
const line = `Branch ${branch} (at ${commit}) deployed as release ${deployCtx.release} by ${user}`;
|
|
90
|
+
const logFile = `${host.deployPath}/revisions.log`;
|
|
91
|
+
await ssh(host, `echo ${q(line)} >> ${q(logFile)}`);
|
|
92
|
+
});
|
|
93
|
+
task('deploy:healthcheck', async () => {
|
|
94
|
+
const { deployCtx, host } = getContext();
|
|
95
|
+
await healthcheckOrThrow(deployCtx, host);
|
|
96
|
+
});
|
|
97
|
+
task('deploy:cleanup', async () => {
|
|
98
|
+
const { deployCtx, host } = getContext();
|
|
99
|
+
const paths = getPaths(host.deployPath, deployCtx.release);
|
|
100
|
+
await ssh(host, `
|
|
101
|
+
set -e
|
|
102
|
+
[ -d ${q(paths.releases)} ] || exit 0
|
|
103
|
+
cd ${q(paths.releases)}
|
|
104
|
+
|
|
105
|
+
count=$(ls -1dt */ 2>/dev/null | wc -l | tr -d ' ')
|
|
106
|
+
if [ "$count" -le ${deployCtx.config.keepReleases} ]; then
|
|
107
|
+
exit 0
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
ls -1dt */ | tail -n +$(( ${deployCtx.config.keepReleases} + 1 )) | xargs -r rm -rf
|
|
111
|
+
`);
|
|
112
|
+
});
|
|
113
|
+
export async function setupHost(ctx, host) {
|
|
114
|
+
const paths = getPaths(host.deployPath, ctx.release);
|
|
115
|
+
console.log(`==> [${host.name}] setup directories`);
|
|
116
|
+
const dirs = get('writable_dirs', []);
|
|
117
|
+
const files = get('shared_files', []);
|
|
118
|
+
const mkdirs = dirs.map((dir) => `mkdir -p ${q(paths.shared + '/' + dir)}`).join('\n ');
|
|
119
|
+
const mkfiles = files
|
|
120
|
+
.map((file) => `if [ ! -f ${q(paths.shared + '/' + file)} ]; then touch ${q(paths.shared + '/' + file)}; fi`)
|
|
121
|
+
.join('\n ');
|
|
122
|
+
await ssh(host, `
|
|
123
|
+
set -e
|
|
124
|
+
mkdir -p ${q(paths.base)}
|
|
125
|
+
mkdir -p ${q(paths.releases)}
|
|
126
|
+
mkdir -p ${q(paths.shared)}
|
|
127
|
+
${mkdirs}
|
|
128
|
+
${mkfiles}
|
|
129
|
+
`);
|
|
130
|
+
}
|
|
131
|
+
async function healthcheckOrThrow(ctx, host) {
|
|
132
|
+
console.log(`==> [${host.name}] healthcheck ${host.healthcheckUrl}`);
|
|
133
|
+
if (ctx.config.healthcheckRetries) {
|
|
134
|
+
for (let i = 1; i <= ctx.config.healthcheckRetries; i += 1) {
|
|
135
|
+
try {
|
|
136
|
+
await ssh(host, `
|
|
137
|
+
set -e
|
|
138
|
+
curl --fail --silent --show-error --max-time 5 ${q(host.healthcheckUrl)} >/dev/null
|
|
139
|
+
`);
|
|
140
|
+
console.log(`==> [${host.name}] healthcheck OK (${i}/${ctx.config.healthcheckRetries})`);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
console.log(`==> [${host.name}] healthcheck failed (${i}/${ctx.config.healthcheckRetries})`);
|
|
145
|
+
if (i < ctx.config.healthcheckRetries) {
|
|
146
|
+
await sleep(ctx.config.healthcheckDelayMs || 3_000);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
throw new Error(`[${host.name}] healthcheck failed: ${host.healthcheckUrl}`);
|
|
152
|
+
}
|
|
153
|
+
export async function getCurrentRelease(ctx, host) {
|
|
154
|
+
const paths = getPaths(host.deployPath, ctx.release);
|
|
155
|
+
try {
|
|
156
|
+
const { stdout } = await ssh(host, `
|
|
157
|
+
set -e
|
|
158
|
+
if [ -L ${q(paths.current)} ]; then
|
|
159
|
+
basename "$(readlink ${q(paths.current)})"
|
|
160
|
+
fi
|
|
161
|
+
`);
|
|
162
|
+
return stdout.trim() || null;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
export async function getPreviousReleaseName(ctx, host) {
|
|
169
|
+
const paths = getPaths(host.deployPath, ctx.release);
|
|
170
|
+
const currentRelease = await getCurrentRelease(ctx, host);
|
|
171
|
+
let stdout = '';
|
|
172
|
+
try {
|
|
173
|
+
;
|
|
174
|
+
({ stdout } = await ssh(host, `
|
|
175
|
+
set -e
|
|
176
|
+
cd ${q(paths.releases)}
|
|
177
|
+
ls -1dt */ 2>/dev/null
|
|
178
|
+
`));
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
const releases = stdout
|
|
184
|
+
.split('\n')
|
|
185
|
+
.map((line) => line.trim().replace(/\/$/, ''))
|
|
186
|
+
.filter(Boolean);
|
|
187
|
+
if (!currentRelease) {
|
|
188
|
+
return releases[1] || releases[0] || null;
|
|
189
|
+
}
|
|
190
|
+
return releases.find((name) => name !== currentRelease) ?? null;
|
|
191
|
+
}
|
|
192
|
+
export async function rollbackHost(ctx, host) {
|
|
193
|
+
const paths = getPaths(host.deployPath, ctx.release);
|
|
194
|
+
const previous = await getPreviousReleaseName(ctx, host);
|
|
195
|
+
if (!previous) {
|
|
196
|
+
throw new Error(`[${host.name}] no previous release available`);
|
|
197
|
+
}
|
|
198
|
+
console.log(`==> [${host.name}] rollback to ${previous}`);
|
|
199
|
+
await ssh(host, `set -e\nln -sfn ${q(paths.releases + '/' + previous)} ${q(paths.current)}`);
|
|
200
|
+
if (getPipeline().includes('pm2:start')) {
|
|
201
|
+
await runTask('pm2:start', ctx, host);
|
|
202
|
+
}
|
|
203
|
+
if (getPipeline().includes('deploy:healthcheck')) {
|
|
204
|
+
await healthcheckOrThrow(ctx, host);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
export async function deployHost(ctx, host) {
|
|
208
|
+
let published = false;
|
|
209
|
+
await runHook(ctx, 'beforeHostDeploy', { host });
|
|
210
|
+
try {
|
|
211
|
+
for (const taskName of getPipeline()) {
|
|
212
|
+
console.log(`==> [${host.name}] ${taskName}`);
|
|
213
|
+
await runTask(taskName, ctx, host);
|
|
214
|
+
if (taskName === 'deploy:publish')
|
|
215
|
+
published = true;
|
|
216
|
+
}
|
|
217
|
+
console.log(`✅ [${host.name}] deploy OK -> ${ctx.release}`);
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
console.error(`❌ [${host.name}] deploy failed: ${error.message}`);
|
|
221
|
+
if (published) {
|
|
222
|
+
try {
|
|
223
|
+
await rollbackHost(ctx, host);
|
|
224
|
+
console.log(`↩️ [${host.name}] auto rollback OK`);
|
|
225
|
+
}
|
|
226
|
+
catch (rollbackError) {
|
|
227
|
+
console.error(`💥 [${host.name}] auto rollback failed: ${rollbackError.message}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
await runTask('deploy:unlock', ctx, host);
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
finally {
|
|
234
|
+
await runHook(ctx, 'afterHostDeploy', { host });
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/host.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Host, DeployContext, Paths, TaskName } from './types.ts';
|
|
2
|
+
export type TaskFn = () => void | Promise<void>;
|
|
3
|
+
export interface TaskContext {
|
|
4
|
+
host: Host;
|
|
5
|
+
paths: Paths;
|
|
6
|
+
deployCtx: DeployContext;
|
|
7
|
+
}
|
|
8
|
+
export declare function getContext(): TaskContext;
|
|
9
|
+
export declare function task(name: TaskName, fn: TaskFn): void;
|
|
10
|
+
export declare function cd(path: string): void;
|
|
11
|
+
export declare function run(command: string): void;
|
|
12
|
+
export declare function runTask(name: TaskName, deployCtx: DeployContext, host: Host): Promise<void>;
|
|
13
|
+
export declare function before(existing: TaskName, newTask: TaskName): void;
|
|
14
|
+
export declare function after(existing: TaskName, newTask: TaskName): void;
|
|
15
|
+
export declare function getPipeline(): string[];
|
|
16
|
+
export declare function hasTask(name: TaskName): boolean;
|
|
17
|
+
export declare function getTasks(): string[];
|
|
18
|
+
export declare function set(key: string, value: unknown): void;
|
|
19
|
+
export declare function get<T>(key: string, defaultValue?: T): T;
|
|
20
|
+
export declare function bin(name: string): string;
|
|
21
|
+
export declare function remove(name: TaskName): void;
|
|
22
|
+
export declare function setPipeline(tasks: string[]): void;
|
|
23
|
+
type LifecycleHook = (ctx: DeployContext, host: Host) => Promise<void> | void;
|
|
24
|
+
export declare function onSetup(fn: LifecycleHook): void;
|
|
25
|
+
export declare function getSetupHooks(): LifecycleHook[];
|
|
26
|
+
export declare function onStatus(fn: LifecycleHook): void;
|
|
27
|
+
export declare function getStatusHooks(): LifecycleHook[];
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { q, getPaths, ssh } from "./utils.js";
|
|
2
|
+
const _registry = new Map();
|
|
3
|
+
let _pipeline = [
|
|
4
|
+
'deploy:lock',
|
|
5
|
+
'deploy:check_branch',
|
|
6
|
+
'deploy:release',
|
|
7
|
+
'deploy:update_code',
|
|
8
|
+
'deploy:shared',
|
|
9
|
+
'deploy:publish',
|
|
10
|
+
'deploy:trace_release',
|
|
11
|
+
'deploy:healthcheck',
|
|
12
|
+
'deploy:unlock',
|
|
13
|
+
'deploy:cleanup',
|
|
14
|
+
];
|
|
15
|
+
let _execCtx = null;
|
|
16
|
+
export function getContext() {
|
|
17
|
+
if (!_execCtx)
|
|
18
|
+
throw new Error('getContext() must be called inside a task');
|
|
19
|
+
return _execCtx;
|
|
20
|
+
}
|
|
21
|
+
export function task(name, fn) {
|
|
22
|
+
_registry.set(name, fn);
|
|
23
|
+
}
|
|
24
|
+
export function cd(path) {
|
|
25
|
+
if (!_execCtx)
|
|
26
|
+
throw new Error('cd() must be called inside a task');
|
|
27
|
+
_execCtx.commands.push(`cd ${q(_resolve(path))}`);
|
|
28
|
+
}
|
|
29
|
+
export function run(command) {
|
|
30
|
+
if (!_execCtx)
|
|
31
|
+
throw new Error('run() must be called inside a task');
|
|
32
|
+
_execCtx.commands.push(_resolve(command));
|
|
33
|
+
}
|
|
34
|
+
export async function runTask(name, deployCtx, host) {
|
|
35
|
+
const fn = _registry.get(name);
|
|
36
|
+
if (!fn)
|
|
37
|
+
throw new Error(`Task not found: "${name}"`);
|
|
38
|
+
const paths = getPaths(host.deployPath, deployCtx.release);
|
|
39
|
+
_execCtx = { host, paths, deployCtx, commands: [] };
|
|
40
|
+
try {
|
|
41
|
+
const result = fn();
|
|
42
|
+
if (result instanceof Promise)
|
|
43
|
+
await result;
|
|
44
|
+
await _flush();
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
_execCtx = null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function before(existing, newTask) {
|
|
51
|
+
const idx = _pipeline.indexOf(existing);
|
|
52
|
+
if (idx === -1)
|
|
53
|
+
throw new Error(`Task "${existing}" not found in pipeline`);
|
|
54
|
+
_pipeline.splice(idx, 0, newTask);
|
|
55
|
+
}
|
|
56
|
+
export function after(existing, newTask) {
|
|
57
|
+
const idx = _pipeline.indexOf(existing);
|
|
58
|
+
if (idx === -1)
|
|
59
|
+
throw new Error(`Task "${existing}" not found in pipeline`);
|
|
60
|
+
_pipeline.splice(idx + 1, 0, newTask);
|
|
61
|
+
}
|
|
62
|
+
export function getPipeline() {
|
|
63
|
+
return [..._pipeline];
|
|
64
|
+
}
|
|
65
|
+
export function hasTask(name) {
|
|
66
|
+
return _registry.has(name);
|
|
67
|
+
}
|
|
68
|
+
export function getTasks() {
|
|
69
|
+
return [..._registry.keys()];
|
|
70
|
+
}
|
|
71
|
+
const _vars = new Map();
|
|
72
|
+
export function set(key, value) {
|
|
73
|
+
_vars.set(key, value);
|
|
74
|
+
}
|
|
75
|
+
export function get(key, defaultValue) {
|
|
76
|
+
return (_vars.has(key) ? _vars.get(key) : defaultValue);
|
|
77
|
+
}
|
|
78
|
+
export function bin(name) {
|
|
79
|
+
return get(`bin/${name}`, name);
|
|
80
|
+
}
|
|
81
|
+
export function remove(name) {
|
|
82
|
+
const idx = _pipeline.indexOf(name);
|
|
83
|
+
if (idx === -1)
|
|
84
|
+
throw new Error(`Task "${name}" not found in pipeline`);
|
|
85
|
+
_pipeline.splice(idx, 1);
|
|
86
|
+
}
|
|
87
|
+
export function setPipeline(tasks) {
|
|
88
|
+
_pipeline = [...tasks];
|
|
89
|
+
}
|
|
90
|
+
const _setupHooks = [];
|
|
91
|
+
export function onSetup(fn) {
|
|
92
|
+
_setupHooks.push(fn);
|
|
93
|
+
}
|
|
94
|
+
export function getSetupHooks() {
|
|
95
|
+
return [..._setupHooks];
|
|
96
|
+
}
|
|
97
|
+
const _statusHooks = [];
|
|
98
|
+
export function onStatus(fn) {
|
|
99
|
+
_statusHooks.push(fn);
|
|
100
|
+
}
|
|
101
|
+
export function getStatusHooks() {
|
|
102
|
+
return [..._statusHooks];
|
|
103
|
+
}
|
|
104
|
+
function _resolve(str) {
|
|
105
|
+
if (!_execCtx)
|
|
106
|
+
return str;
|
|
107
|
+
const p = _execCtx.paths;
|
|
108
|
+
return str
|
|
109
|
+
.replace(/\{\{release_path\}\}/g, p.release)
|
|
110
|
+
.replace(/\{\{current_path\}\}/g, p.current)
|
|
111
|
+
.replace(/\{\{shared_path\}\}/g, p.shared)
|
|
112
|
+
.replace(/\{\{releases_path\}\}/g, p.releases)
|
|
113
|
+
.replace(/\{\{base_path\}\}/g, p.base)
|
|
114
|
+
.replace(/\{\{release\}\}/g, _execCtx.deployCtx.release);
|
|
115
|
+
}
|
|
116
|
+
async function _flush() {
|
|
117
|
+
if (!_execCtx || _execCtx.commands.length === 0)
|
|
118
|
+
return;
|
|
119
|
+
const cmds = _execCtx.commands.splice(0);
|
|
120
|
+
await ssh(_execCtx.host, ['set -e', ...cmds].join('\n'));
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/task.ts"],"names":[],"mappings":"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"}
|