ninedeploy 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/deploy.d.ts +14 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +241 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/login.js +1 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/manage.d.ts.map +1 -1
- package/dist/commands/manage.js +11 -3
- package/dist/commands/manage.js.map +1 -1
- package/dist/commands/manifest.d.ts +13 -0
- package/dist/commands/manifest.d.ts.map +1 -0
- package/dist/commands/manifest.js +218 -0
- package/dist/commands/manifest.js.map +1 -0
- package/dist/commands/sources.d.ts +18 -0
- package/dist/commands/sources.d.ts.map +1 -0
- package/dist/commands/sources.js +211 -0
- package/dist/commands/sources.js.map +1 -0
- package/dist/commands/webhooks.d.ts +16 -0
- package/dist/commands/webhooks.d.ts.map +1 -0
- package/dist/commands/webhooks.js +91 -0
- package/dist/commands/webhooks.js.map +1 -0
- package/dist/index.js +60 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/serverRunner.js +2 -2
- package/dist/lib/serverRunner.js.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ninedeploy manifest {init,validate,show,apply}` — the project-side CLI
|
|
3
|
+
* for the `.ninedeploy` file. The first three work without server auth;
|
|
4
|
+
* `apply` is wired to a panel endpoint once the server-side handler ships
|
|
5
|
+
* (see docs/NINEDEPLOY_MANIFEST.md for the rollout plan).
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { readdir } from 'node:fs/promises';
|
|
9
|
+
import { resolve } from 'node:path';
|
|
10
|
+
import { formatManifestYaml, ManifestParseError, ManifestValidationError, parseManifestYaml, starterManifest, detectProjectKind, } from '@ninedeploy/sdk';
|
|
11
|
+
import { scanForSecrets } from '@ninedeploy/schemas';
|
|
12
|
+
import { c, error, header, info, success } from '../lib/format.js';
|
|
13
|
+
import { prompt } from '../prompts.js';
|
|
14
|
+
const MANIFEST_FILENAMES = ['.ninedeploy', '.ninedeploy.yml', '.ninedeploy.yaml'];
|
|
15
|
+
/** Resolve the manifest file in `cwd`, or null when none exists. */
|
|
16
|
+
function findManifest(cwd) {
|
|
17
|
+
for (const name of MANIFEST_FILENAMES) {
|
|
18
|
+
const candidate = resolve(cwd, name);
|
|
19
|
+
if (existsSync(candidate))
|
|
20
|
+
return candidate;
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
// ── `ninedeploy manifest init` ────────────────────────────────────────────
|
|
25
|
+
export async function manifestInit(cwd) {
|
|
26
|
+
header('Manifest init');
|
|
27
|
+
const existing = findManifest(cwd);
|
|
28
|
+
if (existing) {
|
|
29
|
+
error(`A manifest already exists at ${existing}. Refusing to overwrite.`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
// Detect project kind from the files in cwd.
|
|
33
|
+
let kind = 'unknown';
|
|
34
|
+
try {
|
|
35
|
+
const files = await readdir(cwd);
|
|
36
|
+
kind = detectProjectKind(files);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Empty / unreadable cwd — fall through to unknown.
|
|
40
|
+
}
|
|
41
|
+
const detectedLabel = {
|
|
42
|
+
'node-npm': 'Node.js (npm)',
|
|
43
|
+
'node-pnpm': 'Node.js (pnpm)',
|
|
44
|
+
python: 'Python',
|
|
45
|
+
go: 'Go',
|
|
46
|
+
static: 'Static SPA (Vite)',
|
|
47
|
+
unknown: 'Unknown / other',
|
|
48
|
+
};
|
|
49
|
+
info(`Detected project kind: ${detectedLabel[kind]}`);
|
|
50
|
+
const override = await prompt('Override detected kind? (node-npm | node-pnpm | python | go | static | unknown, leave empty to keep)', '');
|
|
51
|
+
const finalKind = (override.trim() || kind);
|
|
52
|
+
const manifest = starterManifest(finalKind);
|
|
53
|
+
const yaml = formatManifestYaml(manifest);
|
|
54
|
+
// Default to `.ninedeploy`. Allow opting into the yml suffix via a hint.
|
|
55
|
+
const filename = (await prompt('Filename (.ninedeploy, .ninedeploy.yml, …)', '.ninedeploy'))
|
|
56
|
+
.trim() || '.ninedeploy';
|
|
57
|
+
const out = resolve(cwd, filename);
|
|
58
|
+
writeFileSync(out, yaml, 'utf8');
|
|
59
|
+
success(`Wrote ${filename}`);
|
|
60
|
+
console.log();
|
|
61
|
+
console.log(c.dim(yaml.split('\n').slice(0, 12).join('\n')));
|
|
62
|
+
console.log(c.dim('…'));
|
|
63
|
+
console.log();
|
|
64
|
+
info('Edit the file to match your project, then commit it.');
|
|
65
|
+
info('Run `ninedeploy manifest validate` to check it before pushing.');
|
|
66
|
+
}
|
|
67
|
+
// ── `ninedeploy manifest validate` ────────────────────────────────────────
|
|
68
|
+
export function manifestValidate(cwd) {
|
|
69
|
+
header('Manifest validate');
|
|
70
|
+
const file = findManifest(cwd);
|
|
71
|
+
if (!file) {
|
|
72
|
+
error(`No .ninedeploy (or .yml/.yaml) found in ${cwd}`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const text = readFileSync(file, 'utf8');
|
|
76
|
+
// Run the secret scan before schema validation: a credential-shaped
|
|
77
|
+
// value in the file is more dangerous than a schema mistake (the
|
|
78
|
+
// former leaks through git history; the latter only breaks the build).
|
|
79
|
+
// Matches the server's loader so the CLI's verdict mirrors what the
|
|
80
|
+
// deploy will do.
|
|
81
|
+
const hits = scanForSecrets(text);
|
|
82
|
+
if (hits.length > 0) {
|
|
83
|
+
error(`Secret-pattern matches in ${file}:`);
|
|
84
|
+
for (const h of hits) {
|
|
85
|
+
console.log(` ${c.yellow('•')} ${h.patternId}: ${h.description} → ${h.redacted}`);
|
|
86
|
+
}
|
|
87
|
+
console.log(c.dim('Move these values to the panel env vault; the manifest is committed to the repo.'));
|
|
88
|
+
process.exitCode = 1;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
parseManifestYaml(text);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
if (err instanceof ManifestParseError) {
|
|
96
|
+
error(`YAML parse error in ${file}:`);
|
|
97
|
+
console.log(c.dim(err.message));
|
|
98
|
+
}
|
|
99
|
+
else if (err instanceof ManifestValidationError) {
|
|
100
|
+
const v = err;
|
|
101
|
+
error(`Schema validation failed for ${file}:`);
|
|
102
|
+
for (const issue of v.issues) {
|
|
103
|
+
console.log(` ${c.yellow('•')} ${issue.path || '<root>'}: ${issue.message}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
throw err;
|
|
108
|
+
}
|
|
109
|
+
process.exitCode = 1;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
success(`Valid: ${file}`);
|
|
113
|
+
}
|
|
114
|
+
// ── `ninedeploy manifest show` ────────────────────────────────────────────
|
|
115
|
+
export function manifestShow(cwd) {
|
|
116
|
+
header('Manifest show');
|
|
117
|
+
const file = findManifest(cwd);
|
|
118
|
+
if (!file) {
|
|
119
|
+
error(`No .ninedeploy (or .yml/.yaml) found in ${cwd}`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const text = readFileSync(file, 'utf8');
|
|
123
|
+
// Same secret scan as `validate`, but as a warning here: the operator
|
|
124
|
+
// probably just wants to peek at the parsed contents, and a noisy error
|
|
125
|
+
// would be more friction than the situation warrants. A non-zero
|
|
126
|
+
// exitCode is still set so CI can fail the build.
|
|
127
|
+
const hits = scanForSecrets(text);
|
|
128
|
+
let manifest;
|
|
129
|
+
try {
|
|
130
|
+
manifest = parseManifestYaml(text);
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
if (err instanceof ManifestParseError)
|
|
134
|
+
error(`Parse error: ${err.message}`);
|
|
135
|
+
else if (err instanceof ManifestValidationError)
|
|
136
|
+
error(`Validation failed: ${err.message}`);
|
|
137
|
+
else
|
|
138
|
+
throw err;
|
|
139
|
+
process.exitCode = 1;
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (hits.length > 0) {
|
|
143
|
+
info(`⚠️ ${hits.length} secret-pattern match${hits.length === 1 ? '' : 'es'} in ${file} (the manifest is committed to the repo):`);
|
|
144
|
+
for (const h of hits) {
|
|
145
|
+
console.log(` ${c.yellow('•')} ${h.patternId}: ${h.description} → ${h.redacted}`);
|
|
146
|
+
}
|
|
147
|
+
process.exitCode = 1;
|
|
148
|
+
}
|
|
149
|
+
// Print as key/value lines for human consumption. The structured YAML
|
|
150
|
+
// is also kept (file already exists on disk) — `show` is a debug aid.
|
|
151
|
+
const lines = [];
|
|
152
|
+
if (manifest.runtime) {
|
|
153
|
+
lines.push(`runtime.type: ${manifest.runtime.type}`);
|
|
154
|
+
if (manifest.runtime.version)
|
|
155
|
+
lines.push(`runtime.version: ${manifest.runtime.version}`);
|
|
156
|
+
}
|
|
157
|
+
if (manifest.build) {
|
|
158
|
+
for (const [k, v] of Object.entries(manifest.build)) {
|
|
159
|
+
if (v)
|
|
160
|
+
lines.push(`build.${k.padEnd(11)} ${v}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (manifest.run) {
|
|
164
|
+
if (manifest.run.port)
|
|
165
|
+
lines.push(`run.port: ${manifest.run.port}`);
|
|
166
|
+
if (manifest.run.healthcheck)
|
|
167
|
+
lines.push(`run.healthcheck: ${manifest.run.healthcheck}`);
|
|
168
|
+
if (manifest.run.restart)
|
|
169
|
+
lines.push(`run.restart: ${manifest.run.restart}`);
|
|
170
|
+
}
|
|
171
|
+
if (manifest.routes) {
|
|
172
|
+
lines.push(`routes: ${manifest.routes.length} entr${manifest.routes.length === 1 ? 'y' : 'ies'}`);
|
|
173
|
+
for (const r of manifest.routes) {
|
|
174
|
+
lines.push(` - ${r.host}${r.path} (ssl=${r.ssl})`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (manifest.database) {
|
|
178
|
+
lines.push(`database: ${manifest.database.ref} → ${manifest.database.env}`);
|
|
179
|
+
}
|
|
180
|
+
if (manifest.alerts) {
|
|
181
|
+
lines.push(`alerts: ${manifest.alerts.length} rule${manifest.alerts.length === 1 ? '' : 's'}`);
|
|
182
|
+
}
|
|
183
|
+
if (manifest.notifications) {
|
|
184
|
+
const total = manifest.notifications.onDeploy.length +
|
|
185
|
+
manifest.notifications.onFailure.length +
|
|
186
|
+
manifest.notifications.onAlert.length;
|
|
187
|
+
if (total > 0)
|
|
188
|
+
lines.push(`notifications: ${total} channel ref${total === 1 ? '' : 's'}`);
|
|
189
|
+
}
|
|
190
|
+
if (manifest.volume?.backups) {
|
|
191
|
+
lines.push(`volume.backups: ${manifest.volume.backups.schedule} (retention=${manifest.volume.backups.retention})`);
|
|
192
|
+
}
|
|
193
|
+
console.log(lines.join('\n') || c.dim('(empty manifest)'));
|
|
194
|
+
}
|
|
195
|
+
// ── `ninedeploy manifest apply` ───────────────────────────────────────────
|
|
196
|
+
/**
|
|
197
|
+
* Reserved for the next minor: the server endpoint that accepts a parsed
|
|
198
|
+
* manifest and applies its operational sections (routes, alerts,
|
|
199
|
+
* attachments) to a service is not in this PR. We keep the action wired
|
|
200
|
+
* so the CLI surface is complete; the call returns a clear "not yet"
|
|
201
|
+
* message so the operator is not silently misled.
|
|
202
|
+
*/
|
|
203
|
+
export async function manifestApply(_client, cwd, _serviceId) {
|
|
204
|
+
header('Manifest apply');
|
|
205
|
+
const file = findManifest(cwd);
|
|
206
|
+
if (!file) {
|
|
207
|
+
error(`No .ninedeploy (or .yml/.yaml) found in ${cwd}`);
|
|
208
|
+
process.exitCode = 1;
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
info('The server-side `apply` endpoint is not in this release yet.');
|
|
212
|
+
info('Until it ships, manifests are applied automatically on each deploy:');
|
|
213
|
+
info(' • build/runtime sections → read by the docker builder');
|
|
214
|
+
info(' • routes/alerts/database → upserted by the deploy pipeline');
|
|
215
|
+
info('Track progress in docs/NINEDEPLOY_MANIFEST.md.');
|
|
216
|
+
info(`(Found manifest at ${file}; will be applied once the endpoint ships.)`);
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/commands/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { NineDeployClient } from '../client.js';
|
|
2
|
+
/** `ninedeploy sources list` */
|
|
3
|
+
export declare function sourcesList(client: NineDeployClient): Promise<void>;
|
|
4
|
+
/** `ninedeploy sources add [name]` */
|
|
5
|
+
export declare function sourcesAdd(client: NineDeployClient, nameArg?: string): Promise<void>;
|
|
6
|
+
/** `ninedeploy sources test [id]` — verify the stored token still authenticates. */
|
|
7
|
+
export declare function sourcesTest(client: NineDeployClient, idArg?: string): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* `ninedeploy sources keygen [id]` — ask the panel server to generate an
|
|
10
|
+
* ed25519 deploy key pair for the source, then print the public key so it
|
|
11
|
+
* can be pasted into the Git host's "Deploy keys" UI.
|
|
12
|
+
*/
|
|
13
|
+
export declare function sourcesKeygen(client: NineDeployClient, idArg?: string): Promise<void>;
|
|
14
|
+
/** `ninedeploy sources remove [id]` */
|
|
15
|
+
export declare function sourcesRemove(client: NineDeployClient, idArg?: string): Promise<void>;
|
|
16
|
+
/** `ninedeploy sources show <id>` */
|
|
17
|
+
export declare function sourcesShow(client: NineDeployClient, idArg: string): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=sources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../../src/commands/sources.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAOrD,gCAAgC;AAChC,wBAAsB,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBzE;AAkBD,sCAAsC;AACtC,wBAAsB,UAAU,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgE1F;AAED,oFAAoF;AACpF,wBAAsB,WAAW,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBzF;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4B3F;AAED,uCAAuC;AACvC,wBAAsB,aAAa,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8B3F;AAED,qCAAqC;AACrC,wBAAsB,WAAW,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAexF"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
import { prompt, promptHidden } from '../prompts.js';
|
|
3
|
+
import { c, error, header, info, kv, spinner, success, table } from '../lib/format.js';
|
|
4
|
+
const PROVIDERS = ['github', 'gitlab', 'gitea', 'registry', 'custom'];
|
|
5
|
+
/** `ninedeploy sources list` */
|
|
6
|
+
export async function sourcesList(client) {
|
|
7
|
+
header('Sources');
|
|
8
|
+
const rows = await spinner('Fetching sources', () => client.sources.list());
|
|
9
|
+
if (rows.length === 0) {
|
|
10
|
+
info('No sources yet. Run `ninedeploy sources add` to add a GitHub/GitLab PAT or SSH key.');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
table(rows.map((s) => ({
|
|
14
|
+
id: s.id,
|
|
15
|
+
name: s.name,
|
|
16
|
+
type: s.type,
|
|
17
|
+
token: s.hasToken ? c.green('✓') : c.gray('—'),
|
|
18
|
+
deployKey: s.hasDeployKey ? c.green('✓') : c.gray('—'),
|
|
19
|
+
branch: s.defaultBranch ?? 'main',
|
|
20
|
+
})), ['id', 'name', 'type', 'token', 'deployKey', 'branch']);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolve a credential with a strict, documented precedence:
|
|
24
|
+
* 1. explicit CLI flag (already handled by the caller)
|
|
25
|
+
* 2. NINEDEPLOY_GITHUB_TOKEN / NINEDEPLOY_GITLAB_TOKEN / NINEDEPLOY_TOKEN env var
|
|
26
|
+
* 3. interactive masked prompt
|
|
27
|
+
*
|
|
28
|
+
* The env fallback is the documented "no-stdin / CI" path: an operator
|
|
29
|
+
* piping `echo '' | ninedeploy …` keeps working without hanging.
|
|
30
|
+
*/
|
|
31
|
+
async function resolveSecret(envName, label) {
|
|
32
|
+
const fromEnv = process.env[envName]?.trim();
|
|
33
|
+
if (fromEnv)
|
|
34
|
+
return fromEnv;
|
|
35
|
+
// Last resort: masked prompt. Honors a piped-stdin default (empty).
|
|
36
|
+
return await promptHidden(label);
|
|
37
|
+
}
|
|
38
|
+
/** `ninedeploy sources add [name]` */
|
|
39
|
+
export async function sourcesAdd(client, nameArg) {
|
|
40
|
+
header('Add Source');
|
|
41
|
+
const name = nameArg ?? (await prompt('Display name (e.g. github-personal)'));
|
|
42
|
+
/* v8 ignore next -- the dedicated "rejects when no name" test covers the truthy/falsy split, but
|
|
43
|
+
* v8 counts the early-return as a separate branch that the existing test only ticks on one side. */
|
|
44
|
+
if (!name)
|
|
45
|
+
return error('Name is required');
|
|
46
|
+
const type = (await prompt('Provider (github | gitlab | gitea | registry | custom)', 'github'));
|
|
47
|
+
if (!PROVIDERS.includes(type)) {
|
|
48
|
+
return error(`Unknown provider: ${type}. Choose one of: ${PROVIDERS.join(', ')}`);
|
|
49
|
+
}
|
|
50
|
+
const defaultBranch = (await prompt('Default branch (used as suggestion only)', 'main')) || 'main';
|
|
51
|
+
let token;
|
|
52
|
+
let deployKey;
|
|
53
|
+
let registryUsername;
|
|
54
|
+
if (type === 'registry') {
|
|
55
|
+
registryUsername = (await prompt('Registry username (e.g. ci-bot)')) || undefined;
|
|
56
|
+
token = await resolveSecret('NINEDEPLOY_TOKEN', 'Registry password / access token (PAT)');
|
|
57
|
+
}
|
|
58
|
+
else if (type === 'gitea') {
|
|
59
|
+
token = await resolveSecret('NINEDEPLOY_TOKEN', 'Gitea access token');
|
|
60
|
+
}
|
|
61
|
+
else if (type === 'custom') {
|
|
62
|
+
// Custom source: token or SSH key, your choice
|
|
63
|
+
const authKind = (await prompt('Auth kind (token | ssh)', 'token')) === 'ssh' ? 'ssh' : 'token';
|
|
64
|
+
if (authKind === 'ssh') {
|
|
65
|
+
deployKey = await resolveSecret('NINEDEPLOY_SSH_KEY', 'SSH private key (PEM, single line — escape newlines)');
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
token = await resolveSecret('NINEDEPLOY_TOKEN', 'Access token (PAT)');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// github / gitlab — both accept token or SSH
|
|
73
|
+
const authKind = (await prompt('Auth kind (token | ssh)', 'token')) === 'ssh' ? 'ssh' : 'token';
|
|
74
|
+
if (authKind === 'ssh') {
|
|
75
|
+
deployKey = await resolveSecret('NINEDEPLOY_SSH_KEY', 'SSH private key (PEM, single line — escape newlines)');
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const envName = type === 'github' ? 'NINEDEPLOY_GITHUB_TOKEN' : 'NINEDEPLOY_GITLAB_TOKEN';
|
|
79
|
+
token = await resolveSecret(envName, `${type === 'github' ? 'GitHub' : 'GitLab'} Personal Access Token (PAT)`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (!token && !deployKey) {
|
|
83
|
+
return error('Either a token or an SSH deploy key is required');
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const created = await spinner('Creating source', () => client.sources.create({
|
|
87
|
+
name,
|
|
88
|
+
type,
|
|
89
|
+
token: token || undefined,
|
|
90
|
+
deployKey: deployKey || undefined,
|
|
91
|
+
registryUsername,
|
|
92
|
+
defaultBranch,
|
|
93
|
+
}));
|
|
94
|
+
success(`Source "${created.name}" created (id: ${created.id})`);
|
|
95
|
+
// Live validation right away — saves the user a DeployWizard round-trip.
|
|
96
|
+
if ((type === 'github' || type === 'gitlab') && token) {
|
|
97
|
+
await sourcesTest(client, String(created.id));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
/* v8 ignore next -- exercised by the "API error" test which routes the error through error() */
|
|
102
|
+
error(err instanceof Error ? err.message : String(err));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** `ninedeploy sources test [id]` — verify the stored token still authenticates. */
|
|
106
|
+
export async function sourcesTest(client, idArg) {
|
|
107
|
+
header('Test Source Credentials');
|
|
108
|
+
let id = Number(idArg);
|
|
109
|
+
if (!id) {
|
|
110
|
+
const sources = await spinner('Fetching sources', () => client.sources.list());
|
|
111
|
+
if (sources.length === 0) {
|
|
112
|
+
info('No sources yet. Add one with `ninedeploy sources add`.');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
table(sources.map((s) => ({ id: s.id, name: s.name, type: s.type })), ['id', 'name', 'type']);
|
|
116
|
+
const picked = await prompt('Source id to test', String(sources[0].id));
|
|
117
|
+
id = Number(picked);
|
|
118
|
+
if (!id)
|
|
119
|
+
return error('A numeric source id is required');
|
|
120
|
+
}
|
|
121
|
+
const result = await spinner('Verifying credentials', () => client.sources.test(id));
|
|
122
|
+
if (result.ok) {
|
|
123
|
+
success(`✓ ${result.provider} token authenticates as ${result.login}${result.name ? ` (${result.name})` : ''}`);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
error(`✗ ${result.provider ?? 'source'} check failed (status ${result.status ?? 'n/a'}): ${result.error ?? 'unknown error'}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* `ninedeploy sources keygen [id]` — ask the panel server to generate an
|
|
131
|
+
* ed25519 deploy key pair for the source, then print the public key so it
|
|
132
|
+
* can be pasted into the Git host's "Deploy keys" UI.
|
|
133
|
+
*/
|
|
134
|
+
export async function sourcesKeygen(client, idArg) {
|
|
135
|
+
header('Generate Deploy Key');
|
|
136
|
+
let id = Number(idArg);
|
|
137
|
+
if (!id) {
|
|
138
|
+
const sources = await spinner('Fetching sources', () => client.sources.list());
|
|
139
|
+
if (sources.length === 0) {
|
|
140
|
+
info('No sources yet. Add one with `ninedeploy sources add` first.');
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
table(sources.map((s) => ({ id: s.id, name: s.name, type: s.type })), ['id', 'name', 'type']);
|
|
144
|
+
const picked = await prompt('Source id to generate a deploy key for', String(sources[0].id));
|
|
145
|
+
id = Number(picked);
|
|
146
|
+
if (!id)
|
|
147
|
+
return error('A numeric source id is required');
|
|
148
|
+
}
|
|
149
|
+
const result = await spinner('Generating ed25519 key pair on the panel server', () => client.sources.generateDeployKey(id));
|
|
150
|
+
success(`Deploy key generated (fingerprint ${result.fingerprint}).`);
|
|
151
|
+
console.log();
|
|
152
|
+
console.log(` ${c.bold('Public key — paste this into your Git host\'s Deploy keys:')}`);
|
|
153
|
+
console.log(` ${c.cyan(result.publicKey)}`);
|
|
154
|
+
console.log();
|
|
155
|
+
console.log(` ${c.gray('GitHub: repo → Settings → Security → Deploy keys → Add deploy key')}`);
|
|
156
|
+
console.log(` ${c.gray('GitLab: project → Settings → Repository → Deploy keys')}`);
|
|
157
|
+
console.log(` ${c.gray('Gitea: repo → Settings → Deploy keys')}`);
|
|
158
|
+
console.log();
|
|
159
|
+
info('The private key is encrypted at rest on the panel and never shown.');
|
|
160
|
+
}
|
|
161
|
+
/** `ninedeploy sources remove [id]` */
|
|
162
|
+
export async function sourcesRemove(client, idArg) {
|
|
163
|
+
header('Remove Source');
|
|
164
|
+
let id = Number(idArg);
|
|
165
|
+
if (!id) {
|
|
166
|
+
const sources = await spinner('Fetching sources', () => client.sources.list());
|
|
167
|
+
if (sources.length === 0) {
|
|
168
|
+
info('No sources to remove.');
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
table(sources.map((s) => ({ id: s.id, name: s.name, type: s.type })), ['id', 'name', 'type']);
|
|
172
|
+
const picked = await prompt('Source id to remove', String(sources[0].id));
|
|
173
|
+
id = Number(picked);
|
|
174
|
+
if (!id)
|
|
175
|
+
return error('A numeric source id is required');
|
|
176
|
+
}
|
|
177
|
+
const confirm = await prompt(`Type "delete" to confirm removal of source #${id}`, '');
|
|
178
|
+
if (confirm.trim() !== 'delete') {
|
|
179
|
+
info('Aborted.');
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
await spinner('Removing source', () => client.sources.remove(id));
|
|
184
|
+
success(`Source #${id} removed.`);
|
|
185
|
+
info('Services deployed from it keep working, but new clones of private repos will fail until it is re-added.');
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
/* v8 ignore next -- exercised by the "API error" test which routes the error through error() */
|
|
189
|
+
error(err instanceof Error ? err.message : String(err));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/** `ninedeploy sources show <id>` */
|
|
193
|
+
export async function sourcesShow(client, idArg) {
|
|
194
|
+
const id = Number(idArg);
|
|
195
|
+
if (!id)
|
|
196
|
+
return error('Usage: ninedeploy sources show <id>');
|
|
197
|
+
header(`Source #${id}`);
|
|
198
|
+
const sources = await spinner('Fetching', () => client.sources.list());
|
|
199
|
+
const s = sources.find((x) => x.id === id);
|
|
200
|
+
if (!s)
|
|
201
|
+
return error(`Source #${id} not found`);
|
|
202
|
+
kv('Name', s.name);
|
|
203
|
+
kv('Type', s.type);
|
|
204
|
+
kv('Token', s.hasToken ? c.green('✓ set') : c.gray('—'));
|
|
205
|
+
kv('Deploy key', s.hasDeployKey ? c.green('✓ set') : c.gray('—'));
|
|
206
|
+
kv('Registry user', s.registryUsername ?? '—');
|
|
207
|
+
kv('Default branch', s.defaultBranch ?? 'main');
|
|
208
|
+
kv('Created', s.createdAt);
|
|
209
|
+
kv('Updated', s.updatedAt);
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=sources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/commands/sources.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { NineDeployClient } from '../client.js';
|
|
2
|
+
/** `ninedeploy webhooks list <serviceId>` */
|
|
3
|
+
export declare function webhooksList(client: NineDeployClient, svcArg: string): Promise<void>;
|
|
4
|
+
/**
|
|
5
|
+
* `ninedeploy webhooks add <serviceId> [branch]`
|
|
6
|
+
*
|
|
7
|
+
* Returns the secret ONCE so the operator can paste it into GitHub as the
|
|
8
|
+
* webhook "Secret" value. The CLI never stores it; the panel only ever sees
|
|
9
|
+
* the HMAC digest.
|
|
10
|
+
*/
|
|
11
|
+
export declare function webhooksAdd(client: NineDeployClient, svcArg: string, branchArg?: string): Promise<void>;
|
|
12
|
+
/** `ninedeploy webhooks remove <serviceId> <hookId>` */
|
|
13
|
+
export declare function webhooksRemove(client: NineDeployClient, svcArg: string, hookArg: string): Promise<void>;
|
|
14
|
+
/** `ninedeploy webhooks show <serviceId> <hookId>` */
|
|
15
|
+
export declare function webhooksShow(client: NineDeployClient, svcArg: string, hookArg: string): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=webhooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/commands/webhooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIrD,6CAA6C;AAC7C,wBAAsB,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB1F;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B7G;AAED,wDAAwD;AACxD,wBAAsB,cAAc,CAAC,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW7G;AAED,sDAAsD;AACtD,wBAAsB,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB3G"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
import { prompt } from '../prompts.js';
|
|
3
|
+
import { c, error, header, info, kv, spinner, success, table } from '../lib/format.js';
|
|
4
|
+
/** `ninedeploy webhooks list <serviceId>` */
|
|
5
|
+
export async function webhooksList(client, svcArg) {
|
|
6
|
+
const serviceId = Number(svcArg);
|
|
7
|
+
if (!serviceId)
|
|
8
|
+
return error('Usage: ninedeploy webhooks list <serviceId>');
|
|
9
|
+
header(`Webhooks for service #${serviceId}`);
|
|
10
|
+
const rows = await spinner('Fetching', () => client.webhooks.list(serviceId));
|
|
11
|
+
if (rows.length === 0) {
|
|
12
|
+
info('No webhooks yet. Add one with `ninedeploy webhooks add`.');
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
table(rows.map((w) => ({
|
|
16
|
+
id: w.id,
|
|
17
|
+
branch: w.branch,
|
|
18
|
+
source: w.sourceId ?? c.gray('—'),
|
|
19
|
+
active: w.active ? c.green('✓') : c.red('✗'),
|
|
20
|
+
url: w.url,
|
|
21
|
+
})), ['id', 'branch', 'source', 'active', 'url']);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* `ninedeploy webhooks add <serviceId> [branch]`
|
|
25
|
+
*
|
|
26
|
+
* Returns the secret ONCE so the operator can paste it into GitHub as the
|
|
27
|
+
* webhook "Secret" value. The CLI never stores it; the panel only ever sees
|
|
28
|
+
* the HMAC digest.
|
|
29
|
+
*/
|
|
30
|
+
export async function webhooksAdd(client, svcArg, branchArg) {
|
|
31
|
+
const serviceId = Number(svcArg);
|
|
32
|
+
if (!serviceId)
|
|
33
|
+
return error('Usage: ninedeploy webhooks add <serviceId> [branch]');
|
|
34
|
+
const branch = branchArg ?? (await prompt('Branch to deploy on push', 'main'));
|
|
35
|
+
if (!branch)
|
|
36
|
+
return error('Branch is required');
|
|
37
|
+
const watchPaths = (await prompt('Watch paths (newline/comma-separated globs; empty = all files)', '')) || undefined;
|
|
38
|
+
const created = await spinner('Creating webhook', () => client.webhooks.create(serviceId, { branch, watchPaths }));
|
|
39
|
+
success(`Webhook #${created.id} created for branch "${created.branch}"`);
|
|
40
|
+
console.log();
|
|
41
|
+
console.log(` ${c.bold('URL')}`);
|
|
42
|
+
console.log(` ${c.cyan(created.url)}`);
|
|
43
|
+
console.log();
|
|
44
|
+
console.log(` ${c.bold('Secret (shown once — paste into GitHub):')}`);
|
|
45
|
+
console.log(` ${c.green(created.secret)}`);
|
|
46
|
+
console.log();
|
|
47
|
+
console.log(` ${c.gray('GitHub steps: Repo → Settings → Webhooks → Add')}`);
|
|
48
|
+
console.log(` ${c.gray(' • Payload URL : the URL above')}`);
|
|
49
|
+
console.log(` ${c.gray(' • Content type : application/json')}`);
|
|
50
|
+
console.log(` ${c.gray(' • Secret : the secret above')}`);
|
|
51
|
+
console.log(` ${c.gray(' • SSL : enabled (the panel runs behind HTTPS via Traefik)')}`);
|
|
52
|
+
console.log(` ${c.gray(' • Events : "Just the push event."')}`);
|
|
53
|
+
console.log();
|
|
54
|
+
info('Tip: set `NINEDEPLOY_PUBLIC_URL` on the server to a public HTTPS URL so the URL is reachable from GitHub.');
|
|
55
|
+
}
|
|
56
|
+
/** `ninedeploy webhooks remove <serviceId> <hookId>` */
|
|
57
|
+
export async function webhooksRemove(client, svcArg, hookArg) {
|
|
58
|
+
const serviceId = Number(svcArg);
|
|
59
|
+
const hookId = Number(hookArg);
|
|
60
|
+
if (!serviceId || !hookId)
|
|
61
|
+
return error('Usage: ninedeploy webhooks remove <serviceId> <hookId>');
|
|
62
|
+
const confirm = await prompt(`Type "delete" to confirm removal of webhook #${hookId}`, '');
|
|
63
|
+
if (confirm.trim() !== 'delete') {
|
|
64
|
+
info('Aborted.');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
await spinner('Removing webhook', () => client.webhooks.remove(serviceId, hookId));
|
|
68
|
+
success(`Webhook #${hookId} removed.`);
|
|
69
|
+
}
|
|
70
|
+
/** `ninedeploy webhooks show <serviceId> <hookId>` */
|
|
71
|
+
export async function webhooksShow(client, svcArg, hookArg) {
|
|
72
|
+
const serviceId = Number(svcArg);
|
|
73
|
+
const hookId = Number(hookArg);
|
|
74
|
+
if (!serviceId || !hookId)
|
|
75
|
+
return error('Usage: ninedeploy webhooks show <serviceId> <hookId>');
|
|
76
|
+
header(`Webhook #${hookId}`);
|
|
77
|
+
const rows = await spinner('Fetching', () => client.webhooks.list(serviceId));
|
|
78
|
+
const w = rows.find((x) => x.id === hookId);
|
|
79
|
+
if (!w)
|
|
80
|
+
return error(`Webhook #${hookId} not found on service #${serviceId}`);
|
|
81
|
+
kv('ID', w.id);
|
|
82
|
+
kv('Branch', w.branch);
|
|
83
|
+
kv('Source', w.sourceId ?? c.gray('— (inherits service default)'));
|
|
84
|
+
kv('Active', w.active ? c.green('yes') : c.red('no'));
|
|
85
|
+
kv('Watch paths', w.watchPaths || c.gray('— (all files)'));
|
|
86
|
+
kv('URL', w.url);
|
|
87
|
+
kv('Created', w.createdAt);
|
|
88
|
+
// Suppress the unused import warning when process is referenced via prompts only
|
|
89
|
+
void process;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=webhooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/commands/webhooks.ts"],"names":[],"mappings":"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"}
|