@catapultjs/deploy 0.12.0 → 0.13.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/README.md +34 -13
- package/build/bin/run.js +18 -42
- package/build/bin/run.js.map +1 -1
- package/build/commands/config_validate.d.ts +7 -0
- package/build/commands/config_validate.js +45 -0
- package/build/commands/config_validate.js.map +1 -0
- package/build/commands/init.js +18 -2
- package/build/commands/init.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/src/config/json/loader.d.ts +4 -0
- package/build/src/config/json/loader.js +206 -0
- package/build/src/config/json/loader.js.map +1 -0
- package/build/src/config/json/recipe_registry.d.ts +3 -0
- package/build/src/config/json/recipe_registry.js +44 -0
- package/build/src/config/json/recipe_registry.js.map +1 -0
- package/build/src/config/json/schema.d.ts +45 -0
- package/build/src/config/json/schema.js +198 -0
- package/build/src/config/json/schema.js.map +1 -0
- package/build/src/config/loader.d.ts +2 -0
- package/build/src/config/loader.js +21 -0
- package/build/src/config/loader.js.map +1 -0
- package/build/src/config/resolve.d.ts +2 -0
- package/build/src/config/resolve.js +30 -0
- package/build/src/config/resolve.js.map +1 -0
- package/build/src/utils.js +8 -1
- package/build/src/utils.js.map +1 -1
- package/package.json +11 -6
- package/schema/deploy.schema.json +287 -0
- package/skills/catapultjs/SKILL.md +14 -11
- package/skills/catapultjs/references/cli.md +11 -2
- package/skills/catapultjs/references/config.md +133 -34
- package/skills/catapultjs/references/recipe.md +1 -1
- package/skills/catapultjs/references/recipes.md +4 -2
package/README.md
CHANGED
|
@@ -19,13 +19,13 @@ Full documentation at **https://catapultjs.com/**
|
|
|
19
19
|
|
|
20
20
|
## Quick start
|
|
21
21
|
|
|
22
|
-
Run `init` at the root of your project
|
|
22
|
+
Run `init` at the root of your project. It lets you choose TypeScript, JavaScript or JSON, creates the matching `deploy.config.*` file, and installs `@catapultjs/deploy` as a dev dependency:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
npx @catapultjs/deploy init
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
Edit
|
|
28
|
+
Edit the generated config to describe your hosts and pick your recipes. With TypeScript:
|
|
29
29
|
|
|
30
30
|
```typescript
|
|
31
31
|
import { defineConfig } from '@catapultjs/deploy'
|
|
@@ -43,6 +43,27 @@ export default defineConfig({
|
|
|
43
43
|
})
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
For a fully declarative config, choose JSON. Catapult validates it against the schema shipped with the package and supports built-in recipes, store values, custom task steps and declarative pipeline controls:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"$schema": "https://catapultjs.com/schema/deploy.schema.json",
|
|
51
|
+
"version": 1,
|
|
52
|
+
"recipes": ["git", "pm2"],
|
|
53
|
+
"config": {
|
|
54
|
+
"hosts": [
|
|
55
|
+
{
|
|
56
|
+
"name": "production",
|
|
57
|
+
"ssh": "deploy@example.com",
|
|
58
|
+
"deployPath": "/home/deploy/myapp"
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
See the [JSON configuration guide](https://catapultjs.com/guide/json-configuration) for tasks, pipeline customization, supported recipes and the cases that still require TypeScript or JavaScript.
|
|
66
|
+
|
|
46
67
|
Prepare the server (once per host), then deploy:
|
|
47
68
|
|
|
48
69
|
```bash
|
|
@@ -69,18 +90,18 @@ npx cata deploy
|
|
|
69
90
|
|
|
70
91
|
## Recipes
|
|
71
92
|
|
|
72
|
-
| Recipe | Description
|
|
73
|
-
| ---------------- |
|
|
93
|
+
| Recipe | Description |
|
|
94
|
+
| ---------------- | -------------------------------------------------------------------------- |
|
|
74
95
|
| `git` | Clones the repository into each release, keeps a bare mirror on the server |
|
|
75
|
-
| `rsync` | Pushes a local directory into the release with rsync
|
|
76
|
-
| `pm2` | Start, reload and manage PM2 processes
|
|
77
|
-
| `adonisjs` | Install, build and migration tasks for AdonisJS apps
|
|
78
|
-
| `adonisjs_local` | Builds the AdonisJS app locally, uploads the artifact
|
|
79
|
-
| `astro` | Builds locally with `astro build`, uploads the output
|
|
80
|
-
| `nuxt` | Build tasks for Nuxt apps
|
|
81
|
-
| `vitepress` | Builds locally with `vitepress build`, uploads the static files
|
|
82
|
-
| `directus` | Directus database migration and schema snapshot tasks
|
|
83
|
-
| `redis` | Flush one, many or all Redis databases
|
|
96
|
+
| `rsync` | Pushes a local directory into the release with rsync |
|
|
97
|
+
| `pm2` | Start, reload and manage PM2 processes |
|
|
98
|
+
| `adonisjs` | Install, build and migration tasks for AdonisJS apps |
|
|
99
|
+
| `adonisjs_local` | Builds the AdonisJS app locally, uploads the artifact |
|
|
100
|
+
| `astro` | Builds locally with `astro build`, uploads the output |
|
|
101
|
+
| `nuxt` | Build tasks for Nuxt apps |
|
|
102
|
+
| `vitepress` | Builds locally with `vitepress build`, uploads the static files |
|
|
103
|
+
| `directus` | Directus database migration and schema snapshot tasks |
|
|
104
|
+
| `redis` | Flush one, many or all Redis databases |
|
|
84
105
|
|
|
85
106
|
## Requirements
|
|
86
107
|
|
package/build/bin/run.js
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
4
|
-
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
5
|
-
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
6
|
-
});
|
|
7
|
-
}
|
|
8
|
-
return path;
|
|
9
|
-
};
|
|
10
|
-
import { pathToFileURL } from 'node:url';
|
|
11
|
-
import { resolve } from 'node:path';
|
|
12
|
-
import { access } from 'node:fs/promises';
|
|
13
|
-
import { findDeployFile } from "../src/utils.js";
|
|
2
|
+
import { loadDeployConfig } from "../src/config/loader.js";
|
|
14
3
|
import { Context } from "../src/context.js";
|
|
15
4
|
import { logger } from "../src/logger.js";
|
|
16
5
|
import { Verbose } from "../src/enums.js";
|
|
@@ -28,6 +17,9 @@ import Pipeline from "../commands/pipeline.js";
|
|
|
28
17
|
import RunTask from "../commands/run_task.js";
|
|
29
18
|
import Ssh from "../commands/ssh.js";
|
|
30
19
|
import Run from "../commands/run.js";
|
|
20
|
+
import ConfigValidate from "../commands/config_validate.js";
|
|
21
|
+
import { resolveDeployConfigFile } from "../src/config/resolve.js";
|
|
22
|
+
const cliArgs = process.argv.slice(2);
|
|
31
23
|
function parseVerboseLevel(argv) {
|
|
32
24
|
let count = 0;
|
|
33
25
|
for (const arg of argv) {
|
|
@@ -38,39 +30,18 @@ function parseVerboseLevel(argv) {
|
|
|
38
30
|
}
|
|
39
31
|
return Math.min(count, Verbose.DEBUG);
|
|
40
32
|
}
|
|
41
|
-
|
|
42
|
-
for (let i = 0; i < argv.length; i++) {
|
|
43
|
-
if ((argv[i] === '--config' || argv[i] === '-c') && argv[i + 1]) {
|
|
44
|
-
return argv[i + 1];
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
const skipDeployFile = ['init', 'version'].includes(process.argv[2]);
|
|
33
|
+
const skipDeployFile = ['init', 'version', 'config:validate'].includes(cliArgs[0]);
|
|
50
34
|
if (!skipDeployFile) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
await access(resolved);
|
|
57
|
-
deployFile = resolved;
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
logger.error(`Config file not found: ${configFlag}`);
|
|
61
|
-
process.exit(1);
|
|
62
|
-
}
|
|
35
|
+
try {
|
|
36
|
+
const deployFile = await resolveDeployConfigFile(cliArgs);
|
|
37
|
+
const initialize = await loadDeployConfig(deployFile);
|
|
38
|
+
await initialize();
|
|
63
39
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
if (!deployFile) {
|
|
68
|
-
logger.error('No supported deploy config file found in current directory. Run `npx cata init` to create one.');
|
|
40
|
+
catch (error) {
|
|
41
|
+
logger.error(error instanceof Error ? error.message : String(error));
|
|
69
42
|
process.exit(1);
|
|
70
43
|
}
|
|
71
|
-
const
|
|
72
|
-
await mod.default();
|
|
73
|
-
const verboseLevel = parseVerboseLevel(process.argv.slice(2));
|
|
44
|
+
const verboseLevel = parseVerboseLevel(cliArgs);
|
|
74
45
|
if (verboseLevel > Verbose.SILENT)
|
|
75
46
|
Context.get().config.verbose = verboseLevel;
|
|
76
47
|
}
|
|
@@ -84,6 +55,10 @@ kernel.defineFlag('config', {
|
|
|
84
55
|
alias: 'c',
|
|
85
56
|
description: 'Path to the deploy config file (default: auto-detected)',
|
|
86
57
|
});
|
|
58
|
+
kernel.defineFlag('json', {
|
|
59
|
+
type: 'boolean',
|
|
60
|
+
description: 'Output result as JSON when supported by the command',
|
|
61
|
+
});
|
|
87
62
|
kernel.on('help', async (command, $kernel, parsed) => {
|
|
88
63
|
parsed.args.unshift(command.commandName);
|
|
89
64
|
const help = new HelpCommand($kernel, parsed, kernel.ui, kernel.prompt);
|
|
@@ -101,10 +76,11 @@ kernel.addLoader(new ListLoader([
|
|
|
101
76
|
ListRevisions,
|
|
102
77
|
ListTasks,
|
|
103
78
|
Pipeline,
|
|
79
|
+
ConfigValidate,
|
|
104
80
|
RunTask,
|
|
105
81
|
Ssh,
|
|
106
82
|
Run,
|
|
107
83
|
]));
|
|
108
|
-
await kernel.handle(
|
|
84
|
+
await kernel.handle(cliArgs);
|
|
109
85
|
process.exitCode = kernel.exitCode ?? 0;
|
|
110
86
|
//# sourceMappingURL=run.js.map
|
package/build/bin/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../bin/run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../bin/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
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 { loadDeployConfig } from "../src/config/loader.js";
|
|
12
|
+
import { resolveDeployConfigFile } from "../src/config/resolve.js";
|
|
13
|
+
export default class ConfigValidate extends BaseCommand {
|
|
14
|
+
static commandName = 'config:validate';
|
|
15
|
+
static description = 'Validate the deploy configuration file';
|
|
16
|
+
async run() {
|
|
17
|
+
let file = null;
|
|
18
|
+
try {
|
|
19
|
+
file = await resolveDeployConfigFile(process.argv.slice(2));
|
|
20
|
+
const initialize = await loadDeployConfig(file);
|
|
21
|
+
await initialize();
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
25
|
+
if (this.json || process.argv.includes('--json')) {
|
|
26
|
+
console.log(JSON.stringify({ valid: false, file, error: message }, null, 2));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
this.logger.error(message);
|
|
30
|
+
}
|
|
31
|
+
this.exitCode = 1;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (this.json || process.argv.includes('--json')) {
|
|
35
|
+
console.log(JSON.stringify({ valid: true, file }, null, 2));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.logger.info(`Deploy config is valid: ${file}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
__decorate([
|
|
42
|
+
flags.boolean({ description: 'Output result as JSON' }),
|
|
43
|
+
__metadata("design:type", Boolean)
|
|
44
|
+
], ConfigValidate.prototype, "json", void 0);
|
|
45
|
+
//# sourceMappingURL=config_validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config_validate.js","sourceRoot":"","sources":["../../commands/config_validate.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAElE,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,WAAW;IACrD,MAAM,CAAC,WAAW,GAAG,iBAAiB,CAAA;IACtC,MAAM,CAAC,WAAW,GAAG,wCAAwC,CAAA;IAK7D,KAAK,CAAC,GAAG;QACP,IAAI,IAAI,GAAkB,IAAI,CAAA;QAE9B,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;YAC3D,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAA;YAC/C,MAAM,UAAU,EAAE,CAAA;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACtE,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YAC9E,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YAC5B,CAAC;YACD,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAA;YACjB,OAAM;QACR,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;YAC3D,OAAM;QACR,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAA;IACrD,CAAC;;AA1BO;IADP,KAAK,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,uBAAuB,EAAE,CAAC;;4CACnC"}
|
package/build/commands/init.js
CHANGED
|
@@ -25,6 +25,21 @@ export default defineConfig({
|
|
|
25
25
|
],
|
|
26
26
|
})
|
|
27
27
|
`;
|
|
28
|
+
const JSON_TEMPLATE = `{
|
|
29
|
+
"$schema": "https://catapultjs.com/schema/deploy.schema.json",
|
|
30
|
+
"version": 1,
|
|
31
|
+
"config": {
|
|
32
|
+
"hosts": [
|
|
33
|
+
{
|
|
34
|
+
"name": "production",
|
|
35
|
+
"ssh": "deploy@example.com",
|
|
36
|
+
"deployPath": "/home/deploy/myapp",
|
|
37
|
+
"branch": "main"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
28
43
|
export default class Init extends BaseCommand {
|
|
29
44
|
static commandName = 'init';
|
|
30
45
|
static description = 'Create a deploy configuration file';
|
|
@@ -37,10 +52,11 @@ export default class Init extends BaseCommand {
|
|
|
37
52
|
const lang = await this.prompt.choice('Which language do you want to use?', [
|
|
38
53
|
{ name: 'ts', message: 'TypeScript (deploy.config.ts)' },
|
|
39
54
|
{ name: 'js', message: 'JavaScript (deploy.config.js)' },
|
|
55
|
+
{ name: 'json', message: 'JSON (deploy.config.json)' },
|
|
40
56
|
]);
|
|
41
|
-
const filename =
|
|
57
|
+
const filename = `deploy.config.${lang}`;
|
|
42
58
|
const dest = resolve(process.cwd(), filename);
|
|
43
|
-
await writeFile(dest, TEMPLATE);
|
|
59
|
+
await writeFile(dest, lang === 'json' ? JSON_TEMPLATE : TEMPLATE);
|
|
44
60
|
this.logger.action(`create ${filename}`).succeeded();
|
|
45
61
|
if (this.skipInstall) {
|
|
46
62
|
this.logger.info('Skipping @catapultjs/deploy installation');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../commands/init.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAC7B,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtE,MAAM,QAAQ,GAAG;;;;;;;;;;;;CAYhB,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,WAAW;IAC3C,MAAM,CAAC,WAAW,GAAG,MAAM,CAAA;IAC3B,MAAM,CAAC,WAAW,GAAG,oCAAoC,CAAA;IAKzD,KAAK,CAAC,GAAG;QACP,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAA;QACvC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,QAAQ,iBAAiB,CAAC,CAAA;YACjD,OAAM;QACR,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,oCAAoC,EAAE;YAC1E,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,+BAA+B,EAAE;YACxD,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,+BAA+B,EAAE;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../commands/init.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAC7B,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAEtE,MAAM,QAAQ,GAAG;;;;;;;;;;;;CAYhB,CAAA;AAED,MAAM,aAAa,GAAG;;;;;;;;;;;;;;CAcrB,CAAA;AAED,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,WAAW;IAC3C,MAAM,CAAC,WAAW,GAAG,MAAM,CAAA;IAC3B,MAAM,CAAC,WAAW,GAAG,oCAAoC,CAAA;IAKzD,KAAK,CAAC,GAAG;QACP,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAA;QACvC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,QAAQ,iBAAiB,CAAC,CAAA;YACjD,OAAM;QACR,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,oCAAoC,EAAE;YAC1E,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,+BAA+B,EAAE;YACxD,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,+BAA+B,EAAE;YACxD,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,2BAA2B,EAAE;SACvD,CAAC,CAAA;QAEF,MAAM,QAAQ,GAAG,iBAAiB,IAAI,EAAE,CAAA;QACxC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAA;QAE7C,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;QACjE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,QAAQ,EAAE,CAAC,CAAC,SAAS,EAAE,CAAA;QAEpD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAA;YAC5D,OAAM;QACR,CAAC;QAED,MAAM,EAAE,GAAG,MAAM,oBAAoB,EAAE,CAAA;QACvC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAA;QACpD,MAAM,KAAK,CAAC,EAAE,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,oBAAoB,CAAC,EAAE;YACvD,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;YAClB,KAAK,EAAE,SAAS;SACjB,CAAC,CAAA;QACF,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,SAAS,EAAE,CAAA;IAC9D,CAAC;;AAjCO;IADP,KAAK,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,8DAA8D,EAAE,CAAC;;yCACnE"}
|
package/build/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from './src/task.ts';
|
|
|
5
5
|
export * from './src/pipeline.ts';
|
|
6
6
|
export * from './src/package_manager.ts';
|
|
7
7
|
export * from './src/define_config.ts';
|
|
8
|
+
export * from './src/config/json/schema.ts';
|
|
8
9
|
export * from './src/deployer.ts';
|
|
9
10
|
export * from './src/status.ts';
|
|
10
11
|
export { Catapult } from './src/api.ts';
|
package/build/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export * from "./src/task.js";
|
|
|
5
5
|
export * from "./src/pipeline.js";
|
|
6
6
|
export * from "./src/package_manager.js";
|
|
7
7
|
export * from "./src/define_config.js";
|
|
8
|
+
export * from "./src/config/json/schema.js";
|
|
8
9
|
export * from "./src/deployer.js";
|
|
9
10
|
export * from "./src/status.js";
|
|
10
11
|
export { Catapult } from "./src/api.js";
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,mBAAmB,CAAA;AACjC,cAAc,0BAA0B,CAAA;AACxC,cAAc,wBAAwB,CAAA;AACtC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,mBAAmB,CAAA;AACjC,cAAc,0BAA0B,CAAA;AACxC,cAAc,wBAAwB,CAAA;AACtC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type JsonDeployConfig } from './schema.ts';
|
|
2
|
+
export declare function validateJsonConfig(value: unknown): JsonDeployConfig;
|
|
3
|
+
export declare function parseJsonConfig(contents: string, source: string): JsonDeployConfig;
|
|
4
|
+
export declare function loadJsonConfig(filePath: string): Promise<() => Promise<void>>;
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { Ajv } from 'ajv';
|
|
3
|
+
import { before, after, remove, setPipeline, getPipeline } from "../../pipeline.js";
|
|
4
|
+
import { cd, desc, download, hasTask, local, run, task, upload } from "../../task.js";
|
|
5
|
+
import { set } from "../../store.js";
|
|
6
|
+
import { defineConfig } from "../../define_config.js";
|
|
7
|
+
import { deployJsonSchema, } from "./schema.js";
|
|
8
|
+
import { loadBuiltInRecipe } from "./recipe_registry.js";
|
|
9
|
+
const ajv = new Ajv({ allErrors: true, strict: true });
|
|
10
|
+
const validateSchema = ajv.compile(deployJsonSchema);
|
|
11
|
+
function pointerSegment(value) {
|
|
12
|
+
return String(value).replace(/~/g, '~0').replace(/\//g, '~1');
|
|
13
|
+
}
|
|
14
|
+
function errorPath(error) {
|
|
15
|
+
let path = error.instancePath;
|
|
16
|
+
if (error.keyword === 'required') {
|
|
17
|
+
path += `/${pointerSegment(error.params.missingProperty)}`;
|
|
18
|
+
}
|
|
19
|
+
else if (error.keyword === 'additionalProperties') {
|
|
20
|
+
path += `/${pointerSegment(error.params.additionalProperty)}`;
|
|
21
|
+
}
|
|
22
|
+
else if (error.keyword === 'propertyNames') {
|
|
23
|
+
path += `/${pointerSegment(error.params.propertyName)}`;
|
|
24
|
+
}
|
|
25
|
+
return path || '/';
|
|
26
|
+
}
|
|
27
|
+
function formatValidationError(error) {
|
|
28
|
+
return `${errorPath(error)} ${error.message ?? 'is invalid'}`;
|
|
29
|
+
}
|
|
30
|
+
function validateHostNames(config) {
|
|
31
|
+
const names = new Set();
|
|
32
|
+
for (const host of config.config.hosts) {
|
|
33
|
+
if (names.has(host.name)) {
|
|
34
|
+
throw new Error(`Invalid JSON deploy config: duplicate host name "${host.name}"`);
|
|
35
|
+
}
|
|
36
|
+
names.add(host.name);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function validateJsonConfig(value) {
|
|
40
|
+
if (!validateSchema(value)) {
|
|
41
|
+
const details = (validateSchema.errors ?? []).map(formatValidationError).join('\n');
|
|
42
|
+
throw new Error(`Invalid JSON deploy config:\n${details}`);
|
|
43
|
+
}
|
|
44
|
+
const config = value;
|
|
45
|
+
validateHostNames(config);
|
|
46
|
+
return config;
|
|
47
|
+
}
|
|
48
|
+
export function parseJsonConfig(contents, source) {
|
|
49
|
+
let value;
|
|
50
|
+
try {
|
|
51
|
+
value = JSON.parse(contents.replace(/^\uFEFF/, ''));
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
throw new Error(`Unable to parse JSON deploy config "${source}": ${error.message}`);
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
return validateJsonConfig(value);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
throw new Error(`${error.message}\nConfig file: ${source}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function stepsFor(definition) {
|
|
64
|
+
return Array.isArray(definition) ? definition : definition.steps;
|
|
65
|
+
}
|
|
66
|
+
async function executeStep(step) {
|
|
67
|
+
if ('cd' in step) {
|
|
68
|
+
cd(step.cd);
|
|
69
|
+
}
|
|
70
|
+
else if ('run' in step) {
|
|
71
|
+
run(step.run);
|
|
72
|
+
}
|
|
73
|
+
else if ('local' in step) {
|
|
74
|
+
await local(step.local.command, { cwd: step.local.cwd });
|
|
75
|
+
}
|
|
76
|
+
else if ('upload' in step) {
|
|
77
|
+
await upload(step.upload.local, step.upload.remote);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
await download(step.download.remote, step.download.local);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function registerTasks(tasks = {}) {
|
|
84
|
+
for (const [name, definition] of Object.entries(tasks)) {
|
|
85
|
+
if (!Array.isArray(definition) && definition.description) {
|
|
86
|
+
desc(definition.description);
|
|
87
|
+
}
|
|
88
|
+
task(name, async () => {
|
|
89
|
+
for (const step of stepsFor(definition)) {
|
|
90
|
+
await executeStep(step);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function assertRegistered(name, path) {
|
|
96
|
+
if (!hasTask(name)) {
|
|
97
|
+
throw new Error(`Invalid JSON deploy config at ${path}: task "${name}" is not registered`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function applyPipelineMutation(path, operation) {
|
|
101
|
+
try {
|
|
102
|
+
operation();
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
throw new Error(`Invalid JSON deploy config at ${path}: ${error.message}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function placementTasks(value) {
|
|
109
|
+
return typeof value === 'string' ? [value] : value;
|
|
110
|
+
}
|
|
111
|
+
function placementTaskPath(position, target, value, index) {
|
|
112
|
+
const path = `/${position}/${pointerSegment(target)}`;
|
|
113
|
+
return Array.isArray(value) ? `${path}/${index}` : path;
|
|
114
|
+
}
|
|
115
|
+
function validatePlacements(config) {
|
|
116
|
+
const targets = new Set([...Object.keys(config.before ?? {}), ...Object.keys(config.after ?? {})]);
|
|
117
|
+
const removed = new Set(config.remove ?? []);
|
|
118
|
+
const placed = new Map();
|
|
119
|
+
for (const position of ['before', 'after']) {
|
|
120
|
+
for (const [target, value] of Object.entries(config[position] ?? {})) {
|
|
121
|
+
for (const [index, name] of placementTasks(value).entries()) {
|
|
122
|
+
const path = placementTaskPath(position, target, value, index);
|
|
123
|
+
const previousPath = placed.get(name);
|
|
124
|
+
if (previousPath) {
|
|
125
|
+
throw new Error(`Invalid JSON deploy config at ${path}: task "${name}" is already placed at ${previousPath}`);
|
|
126
|
+
}
|
|
127
|
+
if (targets.has(name)) {
|
|
128
|
+
throw new Error(`Invalid JSON deploy config at ${path}: task "${name}" cannot also be a before/after target`);
|
|
129
|
+
}
|
|
130
|
+
if (removed.has(name)) {
|
|
131
|
+
throw new Error(`Invalid JSON deploy config at ${path}: task "${name}" cannot be both placed and removed`);
|
|
132
|
+
}
|
|
133
|
+
placed.set(name, path);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function applyPlacements(position, placements = {}) {
|
|
139
|
+
for (const [target, value] of Object.entries(placements)) {
|
|
140
|
+
const tasks = placementTasks(value);
|
|
141
|
+
const path = `/${position}/${pointerSegment(target)}`;
|
|
142
|
+
for (const [index, name] of tasks.entries()) {
|
|
143
|
+
const taskPath = placementTaskPath(position, target, value, index);
|
|
144
|
+
assertRegistered(name, taskPath);
|
|
145
|
+
}
|
|
146
|
+
const orderedTasks = position === 'after' ? [...tasks].reverse() : tasks;
|
|
147
|
+
applyPipelineMutation(path, () => {
|
|
148
|
+
for (const name of orderedTasks) {
|
|
149
|
+
if (position === 'before')
|
|
150
|
+
before(target, name);
|
|
151
|
+
else
|
|
152
|
+
after(target, name);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function applyPipelineConfig(config) {
|
|
158
|
+
validatePlacements(config);
|
|
159
|
+
if (config.pipeline !== undefined) {
|
|
160
|
+
for (const [index, name] of config.pipeline.entries()) {
|
|
161
|
+
assertRegistered(name, `/pipeline/${index}`);
|
|
162
|
+
}
|
|
163
|
+
setPipeline(config.pipeline);
|
|
164
|
+
}
|
|
165
|
+
for (const [index, name] of (config.remove ?? []).entries()) {
|
|
166
|
+
applyPipelineMutation(`/remove/${index}`, () => remove(name));
|
|
167
|
+
}
|
|
168
|
+
applyPlacements('before', config.before);
|
|
169
|
+
applyPlacements('after', config.after);
|
|
170
|
+
}
|
|
171
|
+
function validateFinalPipeline() {
|
|
172
|
+
const pipeline = getPipeline();
|
|
173
|
+
if (pipeline.length === 0) {
|
|
174
|
+
throw new Error('Invalid JSON deploy config at /pipeline: final pipeline must contain at least one task');
|
|
175
|
+
}
|
|
176
|
+
for (const [index, name] of pipeline.entries()) {
|
|
177
|
+
assertRegistered(name, `/pipeline/${index}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function applyStore(values) {
|
|
181
|
+
for (const [key, value] of Object.entries(values ?? {}))
|
|
182
|
+
set(key, value);
|
|
183
|
+
}
|
|
184
|
+
export async function loadJsonConfig(filePath) {
|
|
185
|
+
const contents = await readFile(filePath, 'utf8');
|
|
186
|
+
const json = parseJsonConfig(contents, filePath);
|
|
187
|
+
applyStore(json.store);
|
|
188
|
+
for (const recipe of json.recipes ?? []) {
|
|
189
|
+
try {
|
|
190
|
+
await loadBuiltInRecipe(recipe);
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
throw new Error(`Unable to load recipe "${recipe}": ${error.message}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
applyStore(json.store);
|
|
197
|
+
registerTasks(json.tasks);
|
|
198
|
+
applyPipelineConfig(json);
|
|
199
|
+
validateFinalPipeline();
|
|
200
|
+
const initialize = defineConfig(json.config);
|
|
201
|
+
return async () => {
|
|
202
|
+
await initialize();
|
|
203
|
+
validateFinalPipeline();
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../../src/config/json/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const BUILT_IN_RECIPE_NAMES: readonly ["adonisjs", "adonisjs_local", "astro", "astro_static", "caddy", "directus", "git", "nestjs", "nextjs", "nextjs_static", "nuxt", "nuxt_static", "pm2", "redis", "rsync", "systemd", "tanstack", "vitepress"];
|
|
2
|
+
export type BuiltInRecipeName = (typeof BUILT_IN_RECIPE_NAMES)[number];
|
|
3
|
+
export declare function loadBuiltInRecipe(name: BuiltInRecipeName): Promise<void>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export const BUILT_IN_RECIPE_NAMES = [
|
|
2
|
+
'adonisjs',
|
|
3
|
+
'adonisjs_local',
|
|
4
|
+
'astro',
|
|
5
|
+
'astro_static',
|
|
6
|
+
'caddy',
|
|
7
|
+
'directus',
|
|
8
|
+
'git',
|
|
9
|
+
'nestjs',
|
|
10
|
+
'nextjs',
|
|
11
|
+
'nextjs_static',
|
|
12
|
+
'nuxt',
|
|
13
|
+
'nuxt_static',
|
|
14
|
+
'pm2',
|
|
15
|
+
'redis',
|
|
16
|
+
'rsync',
|
|
17
|
+
'systemd',
|
|
18
|
+
'tanstack',
|
|
19
|
+
'vitepress',
|
|
20
|
+
];
|
|
21
|
+
const recipeLoaders = {
|
|
22
|
+
adonisjs: () => import("../../../recipes/adonisjs.js"),
|
|
23
|
+
adonisjs_local: () => import("../../../recipes/adonisjs_local.js"),
|
|
24
|
+
astro: () => import("../../../recipes/astro.js"),
|
|
25
|
+
astro_static: () => import("../../../recipes/astro_static.js"),
|
|
26
|
+
caddy: () => import("../../../recipes/caddy.js"),
|
|
27
|
+
directus: () => import("../../../recipes/directus.js"),
|
|
28
|
+
git: () => import("../../../recipes/git.js"),
|
|
29
|
+
nestjs: () => import("../../../recipes/nestjs.js"),
|
|
30
|
+
nextjs: () => import("../../../recipes/nextjs.js"),
|
|
31
|
+
nextjs_static: () => import("../../../recipes/nextjs_static.js"),
|
|
32
|
+
nuxt: () => import("../../../recipes/nuxt.js"),
|
|
33
|
+
nuxt_static: () => import("../../../recipes/nuxt_static.js"),
|
|
34
|
+
pm2: () => import("../../../recipes/pm2.js"),
|
|
35
|
+
redis: () => import("../../../recipes/redis.js"),
|
|
36
|
+
rsync: () => import("../../../recipes/rsync.js"),
|
|
37
|
+
systemd: () => import("../../../recipes/systemd.js"),
|
|
38
|
+
tanstack: () => import("../../../recipes/tanstack.js"),
|
|
39
|
+
vitepress: () => import("../../../recipes/vitepress.js"),
|
|
40
|
+
};
|
|
41
|
+
export async function loadBuiltInRecipe(name) {
|
|
42
|
+
await recipeLoaders[name]();
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=recipe_registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipe_registry.js","sourceRoot":"","sources":["../../../../src/config/json/recipe_registry.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,UAAU;IACV,gBAAgB;IAChB,OAAO;IACP,cAAc;IACd,OAAO;IACP,UAAU;IACV,KAAK;IACL,QAAQ;IACR,QAAQ;IACR,eAAe;IACf,MAAM;IACN,aAAa;IACb,KAAK;IACL,OAAO;IACP,OAAO;IACP,SAAS;IACT,UAAU;IACV,WAAW;CACH,CAAA;AAIV,MAAM,aAAa,GAAsD;IACvE,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,8BAA8B,CAAC;IACtD,cAAc,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,oCAAoC,CAAC;IAClE,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,2BAA2B,CAAC;IAChD,YAAY,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,kCAAkC,CAAC;IAC9D,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,2BAA2B,CAAC;IAChD,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,8BAA8B,CAAC;IACtD,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAAC;IAC5C,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,4BAA4B,CAAC;IAClD,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,4BAA4B,CAAC;IAClD,aAAa,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,mCAAmC,CAAC;IAChE,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,0BAA0B,CAAC;IAC9C,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,iCAAiC,CAAC;IAC5D,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,yBAAyB,CAAC;IAC5C,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,2BAA2B,CAAC;IAChD,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,2BAA2B,CAAC;IAChD,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,6BAA6B,CAAC;IACpD,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,8BAA8B,CAAC;IACtD,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,+BAA+B,CAAC;CACzD,CAAA;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAuB;IAC7D,MAAM,aAAa,CAAC,IAAI,CAAC,EAAE,CAAA;AAC7B,CAAC"}
|