@catapultjs/deploy 0.10.0 → 0.11.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.
@@ -1,15 +1,11 @@
1
- import { task, desc, local, upload, get, set, before } from "../index.js";
2
- import { resolveHostStringValue } from "../src/utils.js";
3
- set('astro_mode', 'production');
4
- desc('Builds the Astro application locally');
5
- task('deploy:build', async ({ host }) => {
6
- const mode = resolveHostStringValue(get('astro_mode'), host, 'astro_mode');
7
- await local(`astro build --mode ${mode}`);
1
+ import { task, desc, cd, run, get, set, after, pmExec } from "../index.js";
2
+ set('astro_path', get('source_path', ''));
3
+ desc('Builds the Astro application on the remote server');
4
+ task('deploy:build', () => {
5
+ const astroPath = get('astro_path');
6
+ cd(`{{release_path}}/${astroPath}`);
7
+ run(`${pmExec('astro')} build`);
8
8
  });
9
- desc('Uploads local artifacts to the release directory');
10
- task('deploy:update_code', async ({ paths }) => {
11
- const source = get('source_path', './dist/.');
12
- await upload(source, paths.release);
13
- });
14
- before('deploy:lock', 'deploy:build');
9
+ after('deploy:update_code', 'deploy:install');
10
+ after('deploy:shared', 'deploy:build');
15
11
  //# sourceMappingURL=astro.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"astro.js","sourceRoot":"","sources":["../../recipes/astro.ts"],"names":[],"mappings":"AAKA,OAAO,EAAoB,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAC3F,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAExD,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;AAE/B,IAAI,CAAC,sCAAsC,CAAC,CAAA;AAC5C,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,EAAE,IAAI,EAAe,EAAE,EAAE;IACnD,MAAM,IAAI,GAAG,sBAAsB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAA;IAC1E,MAAM,KAAK,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAA;AAC3C,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,kDAAkD,CAAC,CAAA;AACxD,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,EAAE,KAAK,EAAe,EAAE,EAAE;IAC1D,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,EAAE,UAAU,CAAC,CAAA;IAC7C,MAAM,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;AACrC,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,aAAa,EAAE,cAAc,CAAC,CAAA"}
1
+ {"version":3,"file":"astro.js","sourceRoot":"","sources":["../../recipes/astro.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAE1E,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAA;AAEzC,IAAI,CAAC,mDAAmD,CAAC,CAAA;AACzD,IAAI,CAAC,cAAc,EAAE,GAAG,EAAE;IACxB,MAAM,SAAS,GAAG,GAAG,CAAS,YAAY,CAAC,CAAA;IAC3C,EAAE,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAA;IACnC,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;AACjC,CAAC,CAAC,CAAA;AAEF,KAAK,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,CAAA;AAC7C,KAAK,CAAC,eAAe,EAAE,cAAc,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import { task, desc, local, get, set, before } from "../index.js";
2
+ import { resolveHostStringValue } from "../src/utils.js";
3
+ set('astro_mode', 'production');
4
+ set('source_path', './dist/.');
5
+ desc('Builds the Astro application locally');
6
+ task('deploy:build', async ({ host }) => {
7
+ const mode = resolveHostStringValue(get('astro_mode'), host, 'astro_mode');
8
+ await local(`astro build --mode ${mode}`);
9
+ });
10
+ before('deploy:lock', 'deploy:build');
11
+ //# sourceMappingURL=astro_static.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"astro_static.js","sourceRoot":"","sources":["../../recipes/astro_static.ts"],"names":[],"mappings":"AAKA,OAAO,EAAoB,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAExD,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAA;AAC/B,GAAG,CAAC,aAAa,EAAE,UAAU,CAAC,CAAA;AAE9B,IAAI,CAAC,sCAAsC,CAAC,CAAA;AAC5C,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,EAAE,IAAI,EAAe,EAAE,EAAE;IACnD,MAAM,IAAI,GAAG,sBAAsB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAA;IAC1E,MAAM,KAAK,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAA;AAC3C,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,aAAa,EAAE,cAAc,CAAC,CAAA"}
@@ -1,6 +1,7 @@
1
- import { task, desc } from "../../index.js";
2
- desc('Method for updating code');
3
- task('deploy:update_code', () => {
4
- throw new Error('Please implement this task');
1
+ import { task, desc, get, upload } from "../../index.js";
2
+ desc('Uploads local artifacts to the release directory');
3
+ task('deploy:update_code', async ({ paths }) => {
4
+ const source = get('source_path', './.');
5
+ await upload(source, paths.release);
5
6
  });
6
7
  //# sourceMappingURL=update_code.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"update_code.js","sourceRoot":"","sources":["../../../recipes/deploy/update_code.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAQ3C,IAAI,CAAC,0BAA0B,CAAC,CAAA;AAChC,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAC9B,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;AAC/C,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"update_code.js","sourceRoot":"","sources":["../../../recipes/deploy/update_code.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAQ1E,IAAI,CAAC,kDAAkD,CAAC,CAAA;AACxD,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,EAAE,KAAK,EAAe,EAAE,EAAE;IAC1D,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;IACxC,MAAM,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;AACrC,CAAC,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import { set, after } from "../index.js";
2
+ set('shared_files', ['.env']);
3
+ after('deploy:update_code', 'deploy:install');
4
+ after('deploy:install', 'deploy:build');
5
+ //# sourceMappingURL=nestjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nestjs.js","sourceRoot":"","sources":["../../recipes/nestjs.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAExC,GAAG,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;AAE7B,KAAK,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,CAAA;AAC7C,KAAK,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ import { task, desc, run, get, set, cd, after, pmExec } from "../index.js";
2
+ set('shared_files', ['.env']);
3
+ set('nextjs_path', get('source_path', ''));
4
+ set('nextjs_out_path', '.next/standalone/');
5
+ desc('Builds the Next.js app');
6
+ task('deploy:build', () => {
7
+ const nextjsPath = get('nextjs_path');
8
+ cd(`{{release_path}}/${nextjsPath}`);
9
+ run(`${pmExec('next')} build`);
10
+ const nextjsOutPath = get('nextjs_out_path');
11
+ run(`
12
+ if [ -d {{release_path}}/${nextjsOutPath} ]; then
13
+ ln -sfn {{release_path}}/public {{release_path}}/${nextjsOutPath}
14
+ ln -sfn {{release_path}}/.next/static {{release_path}}/${nextjsOutPath}.next/
15
+ fi
16
+ `);
17
+ });
18
+ after('deploy:update_code', 'deploy:install');
19
+ after('deploy:shared', 'deploy:build');
20
+ //# sourceMappingURL=nextjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextjs.js","sourceRoot":"","sources":["../../recipes/nextjs.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAE1E,GAAG,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;AAC7B,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAA;AAC1C,GAAG,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,CAAA;AAE3C,IAAI,CAAC,wBAAwB,CAAC,CAAA;AAC9B,IAAI,CAAC,cAAc,EAAE,GAAG,EAAE;IACxB,MAAM,UAAU,GAAG,GAAG,CAAS,aAAa,CAAC,CAAA;IAC7C,EAAE,CAAC,oBAAoB,UAAU,EAAE,CAAC,CAAA;IACpC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAE9B,MAAM,aAAa,GAAG,GAAG,CAAS,iBAAiB,CAAC,CAAA;IACpD,GAAG,CAAC;+BACyB,aAAa;yDACa,aAAa;+DACP,aAAa;;GAEzE,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,KAAK,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,CAAA;AAC7C,KAAK,CAAC,eAAe,EAAE,cAAc,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import { task, desc, set, before, local } from "../index.js";
2
+ set('source_path', './out/.');
3
+ desc('Builds the Next.js application locally');
4
+ task('deploy:build', async () => {
5
+ await local('next build');
6
+ });
7
+ before('deploy:lock', 'deploy:build');
8
+ //# sourceMappingURL=nextjs_static.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextjs_static.js","sourceRoot":"","sources":["../../recipes/nextjs_static.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAE5D,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC,CAAA;AAE7B,IAAI,CAAC,wCAAwC,CAAC,CAAA;AAC9C,IAAI,CAAC,cAAc,EAAE,KAAK,IAAI,EAAE;IAC9B,MAAM,KAAK,CAAC,YAAY,CAAC,CAAA;AAC3B,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,aAAa,EAAE,cAAc,CAAC,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import { task, desc, set, before, local } from "../index.js";
2
+ set('source_path', './.output/public/.');
3
+ desc('Builds the Nuxt application locally');
4
+ task('deploy:build', async () => {
5
+ await local(`nuxt generate`);
6
+ });
7
+ before('deploy:lock', 'deploy:build');
8
+ //# sourceMappingURL=nuxt_static.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nuxt_static.js","sourceRoot":"","sources":["../../recipes/nuxt_static.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAE5D,GAAG,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAA;AAExC,IAAI,CAAC,qCAAqC,CAAC,CAAA;AAC3C,IAAI,CAAC,cAAc,EAAE,KAAK,IAAI,EAAE;IAC9B,MAAM,KAAK,CAAC,eAAe,CAAC,CAAA;AAC9B,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,aAAa,EAAE,cAAc,CAAC,CAAA"}
@@ -1,4 +1,3 @@
1
- import { createRequire } from 'node:module';
2
1
  import { task, desc, cd, run, after, onStatus, bin } from "../index.js";
3
2
  import { ssh, q } from "../src/utils.js";
4
3
  onStatus(async (_ctx, host) => {
@@ -42,10 +41,12 @@ task('pm2:delete', async () => {
42
41
  });
43
42
  desc('Displays the last 50 lines of logs for all apps');
44
43
  task('pm2:logs', async ({ host, paths, logger }) => {
45
- const require = createRequire(import.meta.url);
46
- const ecosystem = require(process.cwd() + '/ecosystem.config.cjs');
47
- const names = (ecosystem?.apps ?? []).map((a) => a.name).join(' ');
48
- const { stdout } = await ssh(host, `set -e\ncd ${q(paths.current)}\n${bin('pm2')} logs ${names} --nostream --lines 50`, { color: true });
44
+ const { stdout } = await ssh(host, `
45
+ set -e
46
+ cd ${q(paths.current)}
47
+ names=$(${bin('node')} -e "const e=require('./ecosystem.config.cjs'); console.log((e.apps||[]).map((a)=>a.name).join(' '))")
48
+ ${bin('pm2')} logs $names --nostream --lines 50
49
+ `, { color: true });
49
50
  logger.log(stdout.trim());
50
51
  });
51
52
  desc('Lists all PM2 processes');
@@ -57,15 +58,15 @@ task('pm2:list', async ({ host, paths, logger }) => {
57
58
  });
58
59
  desc('Shows detailed info for each app in ecosystem.config.cjs');
59
60
  task('pm2:show', async ({ host, paths, logger }) => {
60
- const require = createRequire(import.meta.url);
61
- const ecosystem = require(process.cwd() + '/ecosystem.config.cjs');
62
- const names = (ecosystem?.apps ?? []).map((a) => a.name);
63
- for (const name of names) {
64
- const { stdout } = await ssh(host, `set -e\ncd ${q(paths.current)}\n${bin('pm2')} show ${q(name)}`, {
65
- color: true,
66
- });
67
- logger.log(stdout.trim());
68
- }
61
+ const { stdout } = await ssh(host, `
62
+ set -e
63
+ cd ${q(paths.current)}
64
+ names=$(${bin('node')} -e "const e=require('./ecosystem.config.cjs'); console.log((e.apps||[]).map((a)=>a.name).join(' '))")
65
+ for name in $names; do
66
+ ${bin('pm2')} show "$name"
67
+ done
68
+ `, { color: true });
69
+ logger.log(stdout.trim());
69
70
  });
70
71
  after('deploy:publish', 'pm2:startOrReload');
71
72
  after('pm2:startOrReload', 'pm2:save');
@@ -1 +1 @@
1
- {"version":3,"file":"pm2.js","sourceRoot":"","sources":["../../recipes/pm2.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pm2.js","sourceRoot":"","sources":["../../recipes/pm2.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import { set, after } from "../index.js";
2
+ set('shared_files', ['.env']);
3
+ after('deploy:update_code', 'deploy:install');
4
+ after('deploy:install', 'deploy:build');
5
+ //# sourceMappingURL=tanstack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tanstack.js","sourceRoot":"","sources":["../../recipes/tanstack.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAExC,GAAG,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;AAE7B,KAAK,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,CAAA;AAC7C,KAAK,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@catapultjs/deploy",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "type": "module",
5
5
  "main": "build/index.js",
6
6
  "bin": {
@@ -42,6 +42,10 @@
42
42
  "deployment",
43
43
  "ssh",
44
44
  "nodejs",
45
+ "capistrano",
46
+ "deployer",
47
+ "release",
48
+ "rollback",
45
49
  "adonisjs",
46
50
  "pm2",
47
51
  "rsync",
@@ -9,7 +9,7 @@ Capistrano-style SSH deployment for Node.js: versioned releases under `releases/
9
9
 
10
10
  ## Critical rule
11
11
 
12
- `defineConfig()` does not impose a deployment mode: exactly one recipe (or a custom task) must provide the `deploy:update_code` pipeline task. Providers: `recipes/git`, `recipes/rsync`, `recipes/adonisjs_local`, `recipes/astro`, `recipes/vitepress`, or your own `task('deploy:update_code', …)`. A config without one fails at deploy time.
12
+ `deploy:update_code` uploads `source_path` by SCP by default. Import `recipes/git` or `recipes/rsync` only when you want to replace that delivery behavior. Do not combine delivery providers such as `git` and `rsync` unless the user explicitly defines the pipeline.
13
13
 
14
14
  ## References
15
15
 
@@ -19,9 +19,23 @@ Read the file matching the task before writing code:
19
19
  | --- | --- |
20
20
  | Create or update `deploy.ts`: hosts, recipe selection, healthchecks, lifecycle hooks, pipeline tuning, `setPipeline()` | [references/config.md](references/config.md) |
21
21
  | Write or modify a recipe or deployment task: task DSL, `onSetup`/`onStatus` hooks, store options, `TaskRegistry` | [references/recipe.md](references/recipe.md) |
22
- | Use an official recipe (git, rsync, astro, vitepress, adonisjs, nuxt, directus, pm2, redis): tasks added, store keys, monorepo patterns | [references/recipes.md](references/recipes.md) |
22
+ | Use an official recipe (git, rsync, nextjs, nuxt, astro, tanstack, nestjs, adonisjs, vitepress, directus, pm2, redis): tasks added, store keys, monorepo patterns | [references/recipes.md](references/recipes.md) |
23
23
  | Script deployments from Node.js (scripts, CI, bots, dashboards) with the `Catapult` class | [references/api.md](references/api.md) |
24
24
  | Set up a GitHub Actions workflow with `catapultjs/deploy-action`: inputs, SSH secrets, env vars | [references/github-actions.md](references/github-actions.md) |
25
25
  | Use the `cata` CLI: deploy, rollback, task, status, run, ssh, list commands and their options | [references/cli.md](references/cli.md) |
26
26
 
27
27
  When a change spans several areas (e.g. a config plus a custom recipe), read every matching reference.
28
+
29
+ ## Interactive config workflow
30
+
31
+ When the user asks to create, initialize, or configure a Catapult deployment and the required facts are not already present in the repo or prompt, ask focused questions before writing `deploy.ts`.
32
+
33
+ Do not invent production values. At minimum, determine:
34
+
35
+ - app stack/recipe (`nextjs`, `nextjs_static`, `nuxt`, `astro`, `nestjs`, `tanstack`, `adonisjs`, etc.)
36
+ - code delivery mode (default SCP via `source_path`, `git`, `rsync`, local-build/static recipe, or custom)
37
+ - host name, SSH target, deploy path, and branch if using `git`
38
+ - process manager (`pm2` or none) and whether an `ecosystem.config.cjs` should be created
39
+ - `.env`/shared paths and optional healthcheck URL
40
+
41
+ Prefer one compact question group over a long interview. If the project files already answer some items, state the inferred values and ask only for the missing or ambiguous ones. After the user answers, generate the config and include the setup/deploy commands.
@@ -2,6 +2,27 @@
2
2
 
3
3
  The config file is auto-detected as `deploy.ts`, `deploy.js`, `deploy.config.ts` or `deploy.config.js` at the project root (override with `cata --config <path>`). It must default-export `defineConfig()`. Full reference: https://catapultjs.com/guide/api
4
4
 
5
+ ## Before creating a config
6
+
7
+ If the user asks to create or configure a deployment and the repo/prompt does not provide enough information, ask for the missing deployment facts before writing files. Do not guess real production values such as SSH hostnames, deploy paths, domains, branches, or healthcheck URLs.
8
+
9
+ Use project inspection first:
10
+
11
+ - `package.json` scripts and dependencies identify the stack and package manager.
12
+ - Framework config files identify variants: `next.config.*` (`standalone` vs `export`), `nuxt.config.*`, `astro.config.*`, `vite.config.*`, `adonisrc.ts`, `nest-cli.json`.
13
+ - Existing `ecosystem.config.cjs` means `recipes/pm2` is likely wanted.
14
+ - Existing `.env.example`, `storage/`, `uploads/`, `public/`, or app-specific folders can suggest shared paths, but confirm anything destructive or production-specific.
15
+
16
+ Ask a compact set of questions for missing values:
17
+
18
+ 1. Which environment and server? Need host name, SSH target (`user@host`), and absolute `deployPath`.
19
+ 2. How should code reach the server? Use default SCP when uploading `source_path` is enough; choose `git` when the server can access the repository; choose `rsync` when rsync-based sync/delete behavior is preferred.
20
+ 3. Which branch or source path should deploy?
21
+ 4. Should PM2 be configured? If yes, confirm app name, start entry, port, and whether to create `ecosystem.config.cjs`.
22
+ 5. Is there a healthcheck URL and any extra shared files or directories?
23
+
24
+ When the user answers, generate `deploy.ts` with the selected recipes and put `set(...)` calls before the recipe imports they configure.
25
+
5
26
  ```typescript
6
27
  import { defineConfig } from '@catapultjs/deploy'
7
28
  import '@catapultjs/deploy/recipes/git'
@@ -19,25 +40,32 @@ export default defineConfig({
19
40
  })
20
41
  ```
21
42
 
22
- ## Critical rule: code delivery
43
+ ## Code delivery
23
44
 
24
- `defineConfig()` does not impose a deployment mode. The pipeline task `deploy:update_code` MUST be provided by exactly one recipe (or a custom task), otherwise the deploy fails. Pick one:
45
+ Catapult registers a default `deploy:update_code` task that uploads `source_path` via SCP. Recipes can override that task when a different delivery mechanism is needed. Pick one delivery mode:
25
46
 
26
47
  | Recipe | Delivery | Use for |
27
48
  | --- | --- | --- |
49
+ | default `deploy:update_code` | Uploads `source_path` via SCP | Simple local upload, static recipes that set `source_path` |
28
50
  | `recipes/git` | Clones the repo on the server (bare mirror in `.catapult/repo`) | Server can reach the repo, build on server |
29
51
  | `recipes/rsync` | Pushes a local directory into the release | Local builds, no repo access from server |
30
52
  | `recipes/adonisjs_local` | Builds AdonisJS locally, uploads the artifact | AdonisJS without building on the server |
31
- | `recipes/astro` / `recipes/vitepress` | Builds locally, uploads the static output | Static sites |
53
+ | `recipes/vitepress` | Builds locally, uploads the static output | VitePress static sites |
32
54
  | custom `task('deploy:update_code', …)` | Whatever you implement | Anything else |
33
55
 
56
+ Avoid combining providers that override `deploy:update_code` (`git`, `rsync`, `adonisjs_local`, `vitepress`, custom) unless intentionally replacing task behavior.
57
+
34
58
  ## Picking recipes by stack
35
59
 
36
60
  Inspect the project (`package.json`, lock file, config files) before choosing:
37
61
 
38
- - **AdonisJS**: `adonisjs` (installs and builds on the server, exposes `ace:*` migration tasks) or `adonisjs_local` (build locally, upload). Both need a delivery recipe only in the `adonisjs` case (pair it with `git`).
39
- - **Nuxt**: `nuxt` (exposes `deploy:build` and `nuxt:generate`), pair with `git`.
40
- - **Astro / VitePress**: `astro` / `vitepress` alone (they handle delivery).
62
+ - **Next.js**: `nextjs` for standalone server builds on the server (pair with `git` or `rsync`); `nextjs_static` for static export built locally and uploaded from `./out/.` using default SCP unless `rsync` is imported.
63
+ - **Nuxt**: `nuxt` for server builds on the server (pair with `git` or `rsync`); `nuxt_static` for local static generation uploaded from `./.output/public/.` using default SCP unless `rsync` is imported.
64
+ - **Astro**: `astro` for standalone server builds on the server (pair with `git` or `rsync`); `astro_static` for static sites built locally and uploaded from `./dist/.` using default SCP unless `rsync` is imported.
65
+ - **TanStack Start**: `tanstack` for server builds on the server (pair with `git` or `rsync`); configure Vite with Nitro `node-server`.
66
+ - **NestJS**: `nestjs` wires standard install/build on the server (pair with `git` or `rsync`).
67
+ - **AdonisJS**: `adonisjs` (installs and builds on the server, exposes `ace:*` migration tasks; pair with `git` or `rsync`) or `adonisjs_local` (build locally, upload).
68
+ - **VitePress**: `vitepress` builds locally and uploads the static output.
41
69
  - **Process manager**: add `pm2` if the app runs under PM2 (`ecosystem.config.cjs` expected in the project). It wires restart after publish and adds `pm2:*` tasks plus a status report.
42
70
  - **Extras**: `directus` (DB migrations and schema snapshots), `redis` (`redis:db:flush*` tasks, configure with `set('redis_db', n)`).
43
71
 
@@ -159,7 +187,7 @@ Rules:
159
187
  ## Checklist
160
188
 
161
189
  1. `defineConfig()` is the default export.
162
- 2. Exactly one provider for `deploy:update_code` is imported (or defined).
190
+ 2. Delivery mode is intentional: default SCP, or one overriding provider such as `git`, `rsync`, `adonisjs_local`, `vitepress`, or a custom `deploy:update_code`.
163
191
  3. Recipe store options (`set(…)`) match the imported recipes.
164
192
  4. Healthcheck URLs point to an endpoint reachable from the server itself.
165
193
  5. Pin the package version in `package.json` (the API is still in beta).
@@ -10,14 +10,20 @@ Full docs: https://catapultjs.com/guide/recipes
10
10
  | --- | --- | --- |
11
11
  | `recipes/git` | Yes | Server can reach the repo; build runs on the server |
12
12
  | `recipes/rsync` | Yes | Local build, push artifacts via rsync |
13
- | `recipes/astro` | Yes | Astro site, build locally, upload dist |
13
+ | `recipes/astro` | No (pair with `git` or `rsync`) | Astro, build on the server |
14
+ | `recipes/astro_static` | Uses default SCP; `rsync` optional | Static Astro site, build locally |
14
15
  | `recipes/vitepress` | Yes | VitePress site, build locally, upload dist |
15
16
  | `recipes/adonisjs_local` | Yes | AdonisJS, build locally, upload artifact |
16
17
  | `recipes/adonisjs` | No (pair with `git` or `rsync`) | AdonisJS, build on the server |
18
+ | `recipes/nestjs` | No (pair with `git` or `rsync`) | NestJS, build on the server |
19
+ | `recipes/nextjs` | No (pair with `git` or `rsync`) | Next.js, build on the server |
20
+ | `recipes/nextjs_static` | Uses default SCP; `rsync` optional | Static Next.js export, build locally |
17
21
  | `recipes/nuxt` | No (pair with `git` or `rsync`) | Nuxt, build on the server |
22
+ | `recipes/nuxt_static` | Uses default SCP; `rsync` optional | Static Nuxt site, generate locally |
18
23
  | `recipes/directus` | No (pair with `git` or `rsync`) | Directus, migrations and schema snapshots |
19
24
  | `recipes/pm2` | No | Process management (add to any stack) |
20
25
  | `recipes/redis` | No | Redis cache flush (add to any stack) |
26
+ | `recipes/tanstack` | No (pair with `git` or `rsync`) | TanStack Start, build on the server |
21
27
 
22
28
  ---
23
29
 
@@ -71,25 +77,70 @@ import '@catapultjs/deploy/recipes/rsync'
71
77
  import '@catapultjs/deploy/recipes/astro'
72
78
  ```
73
79
 
74
- Builds locally before the lock step, then uploads the output via SCP. Does not run `astro build` on the server.
80
+ Remote build. Does not override `deploy:update_code` — pair with `git` or `rsync`.
81
+
82
+ | Task | Inserted | Description |
83
+ | --- | --- | --- |
84
+ | `deploy:install` | after `deploy:update_code` | Installs dependencies in the release |
85
+ | `deploy:build` | after `deploy:shared` | Runs `astro build` on the server |
86
+
87
+ | Key | Type | Default | Description |
88
+ | --- | --- | --- | --- |
89
+ | `astro_path` | `string` | `''` | Sub-path to the Astro app (monorepo) |
90
+ | `source_path` | `string` | `''` | Used as default for `astro_path` |
91
+
92
+ ```typescript
93
+ set('astro_path', 'apps/web')
94
+ import '@catapultjs/deploy/recipes/astro'
95
+ ```
96
+
97
+ Enable standalone server output in `astro.config.mjs`:
98
+
99
+ ```typescript
100
+ import { defineConfig } from 'astro/config'
101
+ import node from '@astrojs/node'
102
+
103
+ export default defineConfig({
104
+ output: 'server',
105
+ adapter: node({
106
+ mode: 'standalone',
107
+ }),
108
+ })
109
+ ```
110
+
111
+ ---
112
+
113
+ ## `recipes/astro_static`
114
+
115
+ ```typescript
116
+ import '@catapultjs/deploy/recipes/astro_static'
117
+ ```
118
+
119
+ Local build for static Astro sites. Sets `source_path` to `./dist/.` and runs `astro build --mode <astro_mode>` before the remote lock step.
120
+
121
+ Uses the built-in `deploy:update_code` task by default, which transfers `source_path` via SCP. Import `rsync` only if rsync-based transfers are preferred. Do not combine with `git`.
75
122
 
76
123
  | Task | Inserted | Description |
77
124
  | --- | --- | --- |
78
125
  | `deploy:build` | before `deploy:lock` | Runs `astro build --mode <astro_mode>` locally |
79
- | `deploy:update_code` | — | Uploads the generated directory to `releases/<release>` via SCP |
80
126
 
81
127
  | Key | Type | Default | Description |
82
128
  | --- | --- | --- | --- |
83
129
  | `astro_mode` | `string \| Record<string, string>` | `'production'` | Build mode. String = same for all hosts; object = per host name |
84
- | `source_path` | `string` | `'./dist/.'` | Local directory uploaded after the build |
130
+ | `source_path` | `string` | `'./dist/.'` | Local static output directory to transfer |
85
131
 
86
132
  ```typescript
87
133
  // Per-host modes
88
134
  set('astro_mode', { production: 'production', staging: 'staging' })
89
- import '@catapultjs/deploy/recipes/astro'
135
+ import '@catapultjs/deploy/recipes/astro_static'
90
136
  ```
91
137
 
92
- To use rsync instead of SCP for the upload, import both `astro` and `rsync` — `astro` provides `deploy:build`, `rsync` overrides `deploy:update_code`. Do not combine with `git`.
138
+ Optional rsync transfer:
139
+
140
+ ```typescript
141
+ import '@catapultjs/deploy/recipes/astro_static'
142
+ import '@catapultjs/deploy/recipes/rsync'
143
+ ```
93
144
 
94
145
  ---
95
146
 
@@ -176,6 +227,103 @@ Local build + artifact upload. Same `ace:*` tasks as `adonisjs`. Copies `package
176
227
 
177
228
  ---
178
229
 
230
+ ## `recipes/nestjs`
231
+
232
+ ```typescript
233
+ import '@catapultjs/deploy/recipes/nestjs'
234
+ ```
235
+
236
+ Remote build for NestJS applications. Does not override `deploy:update_code` — pair with `git` or `rsync`.
237
+
238
+ Uses the default Node.js install/build tasks: install dependencies in `{{release_path}}`, then run the package manager build script.
239
+
240
+ | Task | Inserted | Description |
241
+ | --- | --- | --- |
242
+ | `deploy:install` | after `deploy:update_code` | Installs dependencies in the release |
243
+ | `deploy:build` | after `deploy:install` | Runs the default `deploy:build` task (`<pm> run build`) |
244
+
245
+ | Key | Type | Default | Description |
246
+ | --- | --- | --- | --- |
247
+ | `shared_files` | `string[]` | `['.env']` | Symlinked into each release |
248
+
249
+ ```typescript
250
+ import '@catapultjs/deploy/recipes/git'
251
+ import '@catapultjs/deploy/recipes/nestjs'
252
+ import '@catapultjs/deploy/recipes/pm2'
253
+ ```
254
+
255
+ PM2 entry:
256
+
257
+ ```javascript
258
+ {
259
+ name: 'nest',
260
+ cwd: path.join(deployPath, 'current'),
261
+ script: 'node',
262
+ args: 'dist/main.js',
263
+ }
264
+ ```
265
+
266
+ ---
267
+
268
+ ## `recipes/tanstack`
269
+
270
+ ```typescript
271
+ import '@catapultjs/deploy/recipes/tanstack'
272
+ ```
273
+
274
+ Remote build for TanStack Start applications. Does not override `deploy:update_code` — pair with `git` or `rsync`.
275
+
276
+ Uses the default Node.js install/build tasks: install dependencies in `{{release_path}}`, then run the package manager build script. `.env` is shared by default.
277
+
278
+ For Vite-based TanStack Start deployments on Node.js, use Nitro with the `node-server` preset and start the generated `.output/server/index.mjs` file.
279
+
280
+ | Task | Inserted | Description |
281
+ | --- | --- | --- |
282
+ | `deploy:install` | after `deploy:update_code` | Installs dependencies in the release |
283
+ | `deploy:build` | after `deploy:install` | Runs the default `deploy:build` task (`<pm> run build`) |
284
+
285
+ | Key | Type | Default | Description |
286
+ | --- | --- | --- | --- |
287
+ | `shared_files` | `string[]` | `['.env']` | Symlinked into each release |
288
+
289
+ ```typescript
290
+ // vite.config.ts
291
+ import { defineConfig } from 'vite'
292
+ import { tanstackStart } from '@tanstack/react-start/plugin/vite'
293
+ import { nitro } from 'nitro/vite'
294
+ import viteReact from '@vitejs/plugin-react'
295
+
296
+ export default defineConfig({
297
+ plugins: [tanstackStart(), nitro({ preset: 'node-server' }), viteReact()],
298
+ })
299
+ ```
300
+
301
+ ```json
302
+ {
303
+ "scripts": {
304
+ "build": "vite build",
305
+ "start": "node .output/server/index.mjs"
306
+ }
307
+ }
308
+ ```
309
+
310
+ PM2 environment should pass host/port explicitly:
311
+
312
+ ```javascript
313
+ env: {
314
+ NODE_ENV: 'production',
315
+ HOST: '0.0.0.0',
316
+ HOSTNAME: '0.0.0.0',
317
+ NITRO_HOST: '0.0.0.0',
318
+ PORT: 3000,
319
+ NITRO_PORT: 3000,
320
+ }
321
+ ```
322
+
323
+ Upstream hosting docs: https://tanstack.com/start/latest/docs/framework/react/guide/hosting#nodejs--docker
324
+
325
+ ---
326
+
179
327
  ## `recipes/nuxt`
180
328
 
181
329
  ```typescript
@@ -200,6 +348,138 @@ set('nuxt_path', 'apps/web')
200
348
  import '@catapultjs/deploy/recipes/nuxt'
201
349
  ```
202
350
 
351
+ PM2 entry:
352
+
353
+ ```javascript
354
+ {
355
+ name: 'nuxt',
356
+ cwd: path.join(deployPath, 'current'),
357
+ script: '.output/server/index.mjs',
358
+ }
359
+ ```
360
+
361
+ For static Nuxt sites generated locally, use `recipes/nuxt_static`.
362
+
363
+ ---
364
+
365
+ ## `recipes/nuxt_static`
366
+
367
+ ```typescript
368
+ import '@catapultjs/deploy/recipes/nuxt_static'
369
+ ```
370
+
371
+ Local generation for static Nuxt sites. Sets `source_path` to `./.output/public/.` and runs `nuxt generate` before the remote lock step.
372
+
373
+ Uses the built-in `deploy:update_code` task by default, which transfers `source_path` via SCP. Import `rsync` only if rsync-based transfers are preferred. Do not combine with `git`.
374
+
375
+ | Task | Inserted | Description |
376
+ | --- | --- | --- |
377
+ | `deploy:build` | before `deploy:lock` | Runs `nuxt generate` locally |
378
+
379
+ | Key | Type | Default | Description |
380
+ | --- | --- | --- | --- |
381
+ | `source_path` | `string` | `'./.output/public/.'` | Local generated output directory to transfer |
382
+
383
+ ```typescript
384
+ import '@catapultjs/deploy/recipes/nuxt_static'
385
+ ```
386
+
387
+ Optional rsync transfer:
388
+
389
+ ```typescript
390
+ import '@catapultjs/deploy/recipes/nuxt_static'
391
+ import '@catapultjs/deploy/recipes/rsync'
392
+ ```
393
+
394
+ ---
395
+
396
+ ## `recipes/nextjs`
397
+
398
+ ```typescript
399
+ import '@catapultjs/deploy/recipes/nextjs'
400
+ ```
401
+
402
+ Remote build. Does not override `deploy:update_code` — pair with `git` or `rsync`.
403
+
404
+ After `next build`, the recipe symlinks `public` and `.next/static` into `.next/standalone/` when the standalone output directory exists.
405
+
406
+ | Task | Inserted | Description |
407
+ | --- | --- | --- |
408
+ | `deploy:build` | after `deploy:shared` | Runs `next build` and prepares standalone output symlinks |
409
+
410
+ | Key | Type | Default | Description |
411
+ | --- | --- | --- | --- |
412
+ | `shared_files` | `string[]` | `['.env']` | Symlinked into each release |
413
+ | `nextjs_path` | `string` | `''` | Sub-path to the Next.js app (monorepo) |
414
+ | `nextjs_out_path` | `string` | `'.next/standalone/'` | Standalone output path receiving `public` and `.next/static` symlinks |
415
+ | `source_path` | `string` | `''` | Used as default for `nextjs_path` |
416
+
417
+ ```typescript
418
+ set('nextjs_path', 'apps/web')
419
+ import '@catapultjs/deploy/recipes/nextjs'
420
+ ```
421
+
422
+ Enable standalone output in `next.config.*`:
423
+
424
+ ```typescript
425
+ export default {
426
+ output: 'standalone',
427
+ }
428
+ ```
429
+
430
+ Next.js creates `.next/standalone/server.js` for standalone deployments. It does not copy `public` or `.next/static` into the standalone directory by default; this recipe links them into the standalone output after the build.
431
+
432
+ PM2 entry:
433
+
434
+ ```javascript
435
+ {
436
+ name: 'next',
437
+ cwd: path.join(deployPath, 'current'),
438
+ script: '.next/standalone/server.js',
439
+ }
440
+ ```
441
+
442
+ Upstream output docs: https://nextjs.org/docs/pages/api-reference/config/next-config-js/output
443
+
444
+ ---
445
+
446
+ ## `recipes/nextjs_static`
447
+
448
+ ```typescript
449
+ import '@catapultjs/deploy/recipes/nextjs_static'
450
+ ```
451
+
452
+ Local build for static Next.js export. Sets `source_path` to `./out/.` and runs `next build` before the remote lock step.
453
+
454
+ Uses the built-in `deploy:update_code` task by default, which transfers `source_path` via SCP. Import `rsync` only if rsync-based transfers are preferred.
455
+
456
+ | Task | Inserted | Description |
457
+ | --- | --- | --- |
458
+ | `deploy:build` | before `deploy:lock` | Runs `next build` locally |
459
+
460
+ | Key | Type | Default | Description |
461
+ | --- | --- | --- | --- |
462
+ | `source_path` | `string` | `'./out/.'` | Local static export directory to transfer |
463
+
464
+ ```typescript
465
+ import '@catapultjs/deploy/recipes/nextjs_static'
466
+ ```
467
+
468
+ Optional rsync transfer:
469
+
470
+ ```typescript
471
+ import '@catapultjs/deploy/recipes/nextjs_static'
472
+ import '@catapultjs/deploy/recipes/rsync'
473
+ ```
474
+
475
+ Enable static export in `next.config.*`:
476
+
477
+ ```typescript
478
+ export default {
479
+ output: 'export',
480
+ }
481
+ ```
482
+
203
483
  ---
204
484
 
205
485
  ## `recipes/directus`