runnix 0.4.0-rc.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/LICENSE +661 -0
- package/README.md +48 -0
- package/bin/runnix.mjs +9 -0
- package/dist/deploy-logic.js +92 -0
- package/dist/deploy-logic.js.map +1 -0
- package/dist/image-digest.js +142 -0
- package/dist/image-digest.js.map +1 -0
- package/dist/main.js +475 -0
- package/dist/main.js.map +1 -0
- package/package.json +50 -0
package/dist/main.js
ADDED
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { mkdir, readdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { pathToFileURL } from 'node:url';
|
|
6
|
+
import { parseImageReference } from '@runnix/protocol';
|
|
7
|
+
import { executeAssignment } from '@runnix/sdk';
|
|
8
|
+
import { loadConfig, resolveRunset } from '@runnix/sdk/config';
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
import { checkSingleRunset, compareAgainstManifest, partitionByRunset, } from './deploy-logic.js';
|
|
11
|
+
import { ciMetadata, gitMetadata, gitShortSha, resolveDigest, resolveImage } from './image-digest.js';
|
|
12
|
+
// Resolves to apps/cli/package.json from both src/ (tsx) and dist/ (published).
|
|
13
|
+
const { version } = createRequire(import.meta.url)('../package.json');
|
|
14
|
+
const program = new Command();
|
|
15
|
+
program.name('runnix').description('Runnix workflow orchestration CLI').version(version);
|
|
16
|
+
/** Control-plane connection for the remote commands; exits with guidance when unset. */
|
|
17
|
+
function requireApi(url, hint = '') {
|
|
18
|
+
const baseUrl = url ?? process.env.RUNNIX_URL;
|
|
19
|
+
const apiKey = process.env.RUNNIX_API_KEY;
|
|
20
|
+
if (!baseUrl || !apiKey) {
|
|
21
|
+
console.error(`RUNNIX_URL and RUNNIX_API_KEY must be set (or pass --url)${hint}`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
return { baseUrl, apiKey };
|
|
25
|
+
}
|
|
26
|
+
function formatImage(image) {
|
|
27
|
+
if (!image)
|
|
28
|
+
return 'none';
|
|
29
|
+
return image.digest ? `${image.reference}@${image.digest.slice(0, 19)}…` : `${image.reference} (unpinned)`;
|
|
30
|
+
}
|
|
31
|
+
function isRunnixFunction(value) {
|
|
32
|
+
return typeof value === 'object' && value !== null && 'definition' in value && 'definitionHash' in value;
|
|
33
|
+
}
|
|
34
|
+
async function loadFunctions(dir) {
|
|
35
|
+
const functions = [];
|
|
36
|
+
let entries;
|
|
37
|
+
try {
|
|
38
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
for (const entry of entries) {
|
|
44
|
+
if (!entry.isFile() || !/\.(ts|js|mjs)$/.test(entry.name) || entry.name.endsWith('.d.ts'))
|
|
45
|
+
continue;
|
|
46
|
+
const mod = await import(pathToFileURL(path.join(dir, entry.name)).href);
|
|
47
|
+
for (const exported of Object.values(mod)) {
|
|
48
|
+
if (isRunnixFunction(exported))
|
|
49
|
+
functions.push(exported);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return functions;
|
|
53
|
+
}
|
|
54
|
+
/** Recursive discovery that remembers which module exported each function. */
|
|
55
|
+
async function discoverFunctions(dir) {
|
|
56
|
+
const found = [];
|
|
57
|
+
let entries;
|
|
58
|
+
try {
|
|
59
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
for (const entry of entries) {
|
|
65
|
+
const full = path.join(dir, entry.name);
|
|
66
|
+
if (entry.isDirectory()) {
|
|
67
|
+
if (entry.name === 'node_modules' || entry.name.startsWith('.'))
|
|
68
|
+
continue;
|
|
69
|
+
found.push(...(await discoverFunctions(full)));
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (!entry.isFile() || !/\.(ts|js|mjs)$/.test(entry.name) || entry.name.endsWith('.d.ts'))
|
|
73
|
+
continue;
|
|
74
|
+
if (/\.(test|spec)\.(ts|js|mjs)$/.test(entry.name))
|
|
75
|
+
continue;
|
|
76
|
+
const mod = await import(pathToFileURL(full).href);
|
|
77
|
+
for (const exported of Object.values(mod)) {
|
|
78
|
+
if (isRunnixFunction(exported))
|
|
79
|
+
found.push({ modulePath: full, fn: exported });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return found;
|
|
83
|
+
}
|
|
84
|
+
/** Shared discovery + cascade resolution for deploy/verify. Exits on empty. */
|
|
85
|
+
async function discoverResolved(options) {
|
|
86
|
+
const loaded = await loadConfig();
|
|
87
|
+
// Explicit --dir scopes discovery exactly (e.g. verifying one image's
|
|
88
|
+
// directory); otherwise take the config's dirs plus its rule dirs.
|
|
89
|
+
const dirs = new Set((options.dir ?? loaded?.config.dirs ?? ['src/functions']).map((d) => path.resolve(d)));
|
|
90
|
+
if (!options.dir && loaded?.config.runsets) {
|
|
91
|
+
const configDir = path.dirname(loaded.configPath);
|
|
92
|
+
for (const rule of Object.values(loaded.config.runsets)) {
|
|
93
|
+
for (const d of rule.dirs)
|
|
94
|
+
dirs.add(path.resolve(configDir, d));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const discoveredRaw = [];
|
|
98
|
+
const seen = new Set();
|
|
99
|
+
for (const dir of dirs) {
|
|
100
|
+
for (const entry of await discoverFunctions(dir)) {
|
|
101
|
+
// Overlapping dirs (a rule dir inside a discovery dir) walk the same
|
|
102
|
+
// module twice - keep one occurrence per (module, function).
|
|
103
|
+
const key = `${entry.modulePath} ${entry.fn.definition.identifier}`;
|
|
104
|
+
if (seen.has(key))
|
|
105
|
+
continue;
|
|
106
|
+
seen.add(key);
|
|
107
|
+
discoveredRaw.push(entry);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (discoveredRaw.length === 0) {
|
|
111
|
+
console.error(`no functions found in: ${[...dirs].join(', ')}`);
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
const discovered = discoveredRaw.map(({ modulePath, fn }) => {
|
|
115
|
+
const runset = resolveRunset({
|
|
116
|
+
functionRunset: fn.runset,
|
|
117
|
+
modulePath,
|
|
118
|
+
loaded,
|
|
119
|
+
runLevelDefault: options.runset,
|
|
120
|
+
});
|
|
121
|
+
return {
|
|
122
|
+
definition: fn.definition,
|
|
123
|
+
definitionHash: fn.definitionHash,
|
|
124
|
+
runset,
|
|
125
|
+
// Decision #21 cascade at deploy: function-level > the runset rule's
|
|
126
|
+
// region > 'default' (runset = WHAT ships, group = WHERE it runs).
|
|
127
|
+
region: fn.region ?? loaded?.config.runsets?.[runset]?.region ?? 'default',
|
|
128
|
+
requiredEnv: fn.env ?? [],
|
|
129
|
+
modulePath,
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
return { discovered, loaded };
|
|
133
|
+
}
|
|
134
|
+
program
|
|
135
|
+
.command('deploy')
|
|
136
|
+
.description('Deploy runset manifests to the control plane (Decision #19)')
|
|
137
|
+
.option('-d, --dir <dirs...>', 'function directories (default: runnix.config dirs, else src/functions)')
|
|
138
|
+
.option('--runset <name>', 'run-level default runset for functions that declare none')
|
|
139
|
+
.option('--owned <names>', 'comma-separated authoritative runset list (overrides runnix.config owned)')
|
|
140
|
+
.option('--image <ref>', 'worker image for the (single) presented runset; default: runnix.config image (Decision #24)')
|
|
141
|
+
.option('--image-digest <sha256>', 'pin the image digest explicitly (CI: from buildx --metadata-file)')
|
|
142
|
+
.option('--version <label>', 'deployment version label (default: git short sha)')
|
|
143
|
+
.option('--allow-unpinned', 'let a production-type environment accept an image with no resolvable digest')
|
|
144
|
+
.option('--dry-run', 'print the manifest without deploying')
|
|
145
|
+
.option('--url <url>', 'control plane URL (default: RUNNIX_URL)')
|
|
146
|
+
.action(async (options) => {
|
|
147
|
+
const { discovered, loaded } = await discoverResolved(options);
|
|
148
|
+
const owned = options.owned
|
|
149
|
+
? options.owned
|
|
150
|
+
.split(',')
|
|
151
|
+
.map((s) => s.trim())
|
|
152
|
+
.filter(Boolean)
|
|
153
|
+
: loaded?.config.owned;
|
|
154
|
+
const { body, duplicates } = partitionByRunset(discovered, owned);
|
|
155
|
+
if (duplicates.length > 0) {
|
|
156
|
+
for (const dup of duplicates) {
|
|
157
|
+
console.error(`duplicate identifier "${dup.identifier}" with diverging builds in:`);
|
|
158
|
+
for (const mod of dup.modules)
|
|
159
|
+
console.error(` ${mod}`);
|
|
160
|
+
}
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
// Decision #24: the deployment names the image. The digest comes from the
|
|
164
|
+
// developer's own docker (after their push); the control plane only
|
|
165
|
+
// records what it is handed.
|
|
166
|
+
if (options.image && body.runsets.length > 1) {
|
|
167
|
+
console.error(`--image applies to one runset but this deploy presents ${body.runsets.length}; set image per runset in runnix.config.ts`);
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
if (options.imageDigest && !options.image) {
|
|
171
|
+
console.error('--image-digest requires --image');
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
const version = options.version ?? (await gitShortSha());
|
|
175
|
+
for (const entry of body.runsets) {
|
|
176
|
+
const reference = resolveImage({ runset: entry.runset, config: loaded?.config ?? {}, flag: options.image });
|
|
177
|
+
if (!reference)
|
|
178
|
+
continue;
|
|
179
|
+
if (!parseImageReference(reference)) {
|
|
180
|
+
console.error(`invalid image reference for runset ${entry.runset}: ${reference}`);
|
|
181
|
+
process.exit(1);
|
|
182
|
+
}
|
|
183
|
+
const digest = await resolveDigest(reference, options.imageDigest);
|
|
184
|
+
entry.image = digest ? { reference, digest } : { reference };
|
|
185
|
+
if (version)
|
|
186
|
+
entry.version = version;
|
|
187
|
+
console.log(`image ${entry.runset}: ${formatImage(entry.image)}${digest ? '' : ' - no digest resolved; push before deploy'}`);
|
|
188
|
+
}
|
|
189
|
+
if (options.allowUnpinned)
|
|
190
|
+
body.allowUnpinned = true;
|
|
191
|
+
// Decision #25: the deploy record carries where the code came from.
|
|
192
|
+
const git = await gitMetadata();
|
|
193
|
+
const ci = ciMetadata();
|
|
194
|
+
if (git || ci)
|
|
195
|
+
body.metadata = { ...(git ? { git } : {}), ...(ci ? { ci } : {}) };
|
|
196
|
+
if (git) {
|
|
197
|
+
console.log(`source: git ${git.sha.slice(0, 12)}${git.branch ? ` (${git.branch})` : ''}${git.dirty ? ' with uncommitted changes' : ''}${ci ? `, ${ci.provider} run` : ''}`);
|
|
198
|
+
}
|
|
199
|
+
for (const entry of body.runsets) {
|
|
200
|
+
console.log(`runset ${entry.runset}: ${entry.functions.map((f) => f.definition.identifier).join(', ')}`);
|
|
201
|
+
}
|
|
202
|
+
if (body.owned)
|
|
203
|
+
console.log(`owned: ${body.owned.join(', ')}`);
|
|
204
|
+
if (options.dryRun)
|
|
205
|
+
return;
|
|
206
|
+
const { baseUrl, apiKey } = requireApi(options.url);
|
|
207
|
+
const response = await fetch(new URL('/v1/deployments', baseUrl), {
|
|
208
|
+
method: 'POST',
|
|
209
|
+
headers: { authorization: `Bearer ${apiKey}`, 'content-type': 'application/json' },
|
|
210
|
+
body: JSON.stringify(body),
|
|
211
|
+
});
|
|
212
|
+
if (!response.ok) {
|
|
213
|
+
const detail = await response.text();
|
|
214
|
+
console.error(`deploy failed: ${response.status} ${detail}`);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
const result = (await response.json());
|
|
218
|
+
console.log(`deploy ${result.deployId}: ${result.deployments.length} runset(s)`);
|
|
219
|
+
for (const dep of result.deployments) {
|
|
220
|
+
const image = dep.image ? `, image ${formatImage(dep.image)}` : '';
|
|
221
|
+
const label = dep.version ? ` ${dep.version}` : '';
|
|
222
|
+
console.log(`deployed ${dep.runset}${label}: ${dep.registered} function(s) registered, ${dep.deprecated} deprecated${image} (${dep.deploymentId})`);
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
program
|
|
226
|
+
.command('deployments')
|
|
227
|
+
.description('List the current deployment per runset (id, version, image), or recent deploys with --history')
|
|
228
|
+
.option('--history [count]', 'list the most recent deploys, each with every runset it shipped (default 20)')
|
|
229
|
+
.option('--url <url>', 'control plane URL (default: RUNNIX_URL)')
|
|
230
|
+
.action(async (options) => {
|
|
231
|
+
const { baseUrl, apiKey } = requireApi(options.url);
|
|
232
|
+
if (options.history) {
|
|
233
|
+
const limit = typeof options.history === 'string' ? Number(options.history) || 20 : 20;
|
|
234
|
+
const response = await fetch(new URL(`/v1/deploys?limit=${limit}`, baseUrl), {
|
|
235
|
+
headers: { authorization: `Bearer ${apiKey}` },
|
|
236
|
+
});
|
|
237
|
+
if (!response.ok) {
|
|
238
|
+
console.error(`failed: ${response.status} ${await response.text()}`);
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
const { deploys } = (await response.json());
|
|
242
|
+
if (deploys.length === 0) {
|
|
243
|
+
console.log('no deploys recorded in this environment');
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
for (const deploy of deploys) {
|
|
247
|
+
const git = deploy.metadata?.git;
|
|
248
|
+
const source = git
|
|
249
|
+
? ` git ${git.sha.slice(0, 12)}${git.branch ? ` ${git.branch}` : ''}${git.dirty ? ' (dirty)' : ''}`
|
|
250
|
+
: '';
|
|
251
|
+
const ci = deploy.metadata?.ci ? ` ${deploy.metadata.ci.provider}` : '';
|
|
252
|
+
const promoted = deploy.promotedFrom ? ` promoted from ${deploy.promotedFrom}` : '';
|
|
253
|
+
console.log(`deploy ${deploy.id} ${deploy.createdAt} by ${deploy.deployedBy ?? '-'}${source}${ci}${promoted}`);
|
|
254
|
+
for (const row of deploy.runsets) {
|
|
255
|
+
const changes = [
|
|
256
|
+
row.diff.added.length ? `+${row.diff.added.length}` : '',
|
|
257
|
+
row.diff.changed.length ? `~${row.diff.changed.length}` : '',
|
|
258
|
+
row.diff.removed.length ? `-${row.diff.removed.length}` : '',
|
|
259
|
+
row.diff.imageChanged ? 'image' : '',
|
|
260
|
+
]
|
|
261
|
+
.filter(Boolean)
|
|
262
|
+
.join(' ');
|
|
263
|
+
console.log(` ${row.runset}\t${row.version ?? '-'}\t${formatImage(row.image)}\t${row.functionCount} fn\t${changes || 'no changes'}${row.current ? '\tcurrent' : ''}\t${row.id}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const response = await fetch(new URL('/v1/deployments', baseUrl), {
|
|
269
|
+
headers: { authorization: `Bearer ${apiKey}` },
|
|
270
|
+
});
|
|
271
|
+
if (!response.ok) {
|
|
272
|
+
console.error(`failed: ${response.status} ${await response.text()}`);
|
|
273
|
+
process.exit(1);
|
|
274
|
+
}
|
|
275
|
+
const { deployments } = (await response.json());
|
|
276
|
+
if (deployments.length === 0) {
|
|
277
|
+
console.log('no deployments recorded in this environment');
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
for (const d of deployments) {
|
|
281
|
+
console.log(`${d.runset}\t${d.id}\t${d.version ?? '-'}\t${formatImage(d.image)}\t${d.functionCount} fn\t${d.createdAt}`);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
program
|
|
285
|
+
.command('promote')
|
|
286
|
+
.description('Roll a runset back (or forward) to a previous deployment: a new row replayed from its snapshot')
|
|
287
|
+
.requiredOption('--to <deploymentId>', 'the deployment to promote (see `runnix deployments` / the Deployments page)')
|
|
288
|
+
.option('--allow-unpinned', 'promote even if that deployment recorded an image without a digest')
|
|
289
|
+
.option('--url <url>', 'control plane URL (default: RUNNIX_URL)')
|
|
290
|
+
.action(async (options) => {
|
|
291
|
+
const { baseUrl, apiKey } = requireApi(options.url);
|
|
292
|
+
const response = await fetch(new URL(`/v1/deployments/${encodeURIComponent(options.to)}/promote`, baseUrl), {
|
|
293
|
+
method: 'POST',
|
|
294
|
+
headers: { authorization: `Bearer ${apiKey}`, 'content-type': 'application/json' },
|
|
295
|
+
body: JSON.stringify({ allowUnpinned: Boolean(options.allowUnpinned) }),
|
|
296
|
+
});
|
|
297
|
+
if (!response.ok) {
|
|
298
|
+
console.error(`promote failed: ${response.status} ${await response.text()}`);
|
|
299
|
+
process.exit(1);
|
|
300
|
+
}
|
|
301
|
+
const { deployment } = (await response.json());
|
|
302
|
+
console.log(`promoted ${deployment.runset}: ${deployment.registered} function(s), ${deployment.deprecated} deprecated, image ${formatImage(deployment.image)} (${deployment.deploymentId})`);
|
|
303
|
+
});
|
|
304
|
+
program
|
|
305
|
+
.command('verify')
|
|
306
|
+
.description('Verify a worker build against its runset deployment (build/startup guard, Decision #19)')
|
|
307
|
+
.option('-d, --dir <dirs...>', 'function directories (default: runnix.config dirs, else src/functions)')
|
|
308
|
+
.option('--runset <name>', 'the single runset this build is supposed to carry (default: RUNNIX_RUNSET)')
|
|
309
|
+
.option('--offline', 'skip the deployed-manifest comparison (local consistency checks only)')
|
|
310
|
+
.option('--allow-unpinned', 'do not fail when the deployed image has no digest')
|
|
311
|
+
.option('--url <url>', 'control plane URL (default: RUNNIX_URL)')
|
|
312
|
+
.action(async (options) => {
|
|
313
|
+
const imageRunset = options.runset ?? process.env.RUNNIX_RUNSET;
|
|
314
|
+
const { discovered } = await discoverResolved({ dir: options.dir, runset: imageRunset });
|
|
315
|
+
const problems = [];
|
|
316
|
+
// Local: a single-runset build must not mix runsets, and duplicate
|
|
317
|
+
// identifiers with diverging builds are always wrong.
|
|
318
|
+
const { duplicates } = partitionByRunset(discovered);
|
|
319
|
+
for (const dup of duplicates) {
|
|
320
|
+
problems.push({
|
|
321
|
+
kind: 'mixed-runset',
|
|
322
|
+
identifier: dup.identifier,
|
|
323
|
+
detail: `duplicate identifier with diverging builds in: ${dup.modules.join(', ')}`,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
if (imageRunset)
|
|
327
|
+
problems.push(...checkSingleRunset(discovered, imageRunset));
|
|
328
|
+
// Remote: compare against the deployed manifest(s). Skipping this check
|
|
329
|
+
// must be explicit (--offline) - a verify that silently does less is
|
|
330
|
+
// exactly the failure mode this command exists to prevent.
|
|
331
|
+
if (!options.offline) {
|
|
332
|
+
const { baseUrl, apiKey } = requireApi(options.url, ' - or pass --offline for local checks only');
|
|
333
|
+
const runsets = imageRunset ? [imageRunset] : [...new Set(discovered.map((fn) => fn.runset))].sort();
|
|
334
|
+
for (const runset of runsets) {
|
|
335
|
+
const response = await fetch(new URL(`/v1/deployments/${encodeURIComponent(runset)}`, baseUrl), {
|
|
336
|
+
headers: { authorization: `Bearer ${apiKey}` },
|
|
337
|
+
});
|
|
338
|
+
if (response.status === 404) {
|
|
339
|
+
problems.push({
|
|
340
|
+
kind: 'undeployed',
|
|
341
|
+
identifier: `runset:${runset}`,
|
|
342
|
+
detail: `no deployment recorded for runset "${runset}" - run \`runnix deploy\` first`,
|
|
343
|
+
});
|
|
344
|
+
continue;
|
|
345
|
+
}
|
|
346
|
+
if (!response.ok) {
|
|
347
|
+
console.error(`verify: fetching deployment for "${runset}" failed: ${response.status} ${await response.text()}`);
|
|
348
|
+
process.exit(1);
|
|
349
|
+
}
|
|
350
|
+
const deployment = (await response.json());
|
|
351
|
+
console.log(`deployed ${runset}: ${deployment.version ?? 'no version'}, image ${formatImage(deployment.image)}`);
|
|
352
|
+
if (deployment.image && !deployment.image.digest && !options.allowUnpinned) {
|
|
353
|
+
problems.push({
|
|
354
|
+
kind: 'image-unpinned',
|
|
355
|
+
identifier: `runset:${runset}`,
|
|
356
|
+
detail: 'deployed image has no digest (a moving tag can split a generation) - deploy after pushing, or pass --allow-unpinned',
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
const local = discovered
|
|
360
|
+
.filter((fn) => fn.runset === runset)
|
|
361
|
+
.map((fn) => ({ identifier: fn.definition.identifier, definitionHash: fn.definitionHash }));
|
|
362
|
+
problems.push(...compareAgainstManifest(local, deployment.functions));
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
if (problems.length > 0) {
|
|
366
|
+
console.error(`verify FAILED (${problems.length} problem${problems.length === 1 ? '' : 's'}):`);
|
|
367
|
+
for (const p of problems)
|
|
368
|
+
console.error(` [${p.kind}] ${p.identifier}: ${p.detail}`);
|
|
369
|
+
process.exit(1);
|
|
370
|
+
}
|
|
371
|
+
const scope = imageRunset ? `runset "${imageRunset}"` : 'all resolved runsets';
|
|
372
|
+
console.log(`verify OK: ${discovered.length} function(s) consistent with ${scope}${options.offline ? ' (offline - manifest comparison skipped)' : ''}`);
|
|
373
|
+
});
|
|
374
|
+
program
|
|
375
|
+
.command('init')
|
|
376
|
+
.description('Scaffold a Runnix project in the current directory')
|
|
377
|
+
.action(async () => {
|
|
378
|
+
await mkdir('src/functions', { recursive: true });
|
|
379
|
+
await writeFile('src/functions/hello.ts', `import { Runnix } from '@runnix/sdk'
|
|
380
|
+
|
|
381
|
+
const runnix = new Runnix()
|
|
382
|
+
|
|
383
|
+
export const hello = runnix.createFunction(
|
|
384
|
+
{
|
|
385
|
+
id: 'hello',
|
|
386
|
+
triggers: [{ event: 'demo.hello' }],
|
|
387
|
+
},
|
|
388
|
+
async ({ event, step, logger }) => {
|
|
389
|
+
const greeting = await step.run('build-greeting', () => {
|
|
390
|
+
return \`Hello, \${(event.data as { name?: string })?.name ?? 'world'}!\`
|
|
391
|
+
})
|
|
392
|
+
logger.info('greeting built', { greeting })
|
|
393
|
+
return { greeting }
|
|
394
|
+
},
|
|
395
|
+
)
|
|
396
|
+
`);
|
|
397
|
+
await writeFile('worker.ts', `import { Runnix } from '@runnix/sdk'
|
|
398
|
+
import { hello } from './src/functions/hello'
|
|
399
|
+
|
|
400
|
+
const runnix = new Runnix()
|
|
401
|
+
runnix.startRunner({ functions: [hello] })
|
|
402
|
+
console.log('runner started')
|
|
403
|
+
`);
|
|
404
|
+
console.log('created src/functions/hello.ts and worker.ts');
|
|
405
|
+
console.log('next: set RUNNIX_API_KEY and RUNNIX_URL, then run: npx tsx worker.ts');
|
|
406
|
+
});
|
|
407
|
+
program
|
|
408
|
+
.command('functions')
|
|
409
|
+
.command('list')
|
|
410
|
+
.description('List functions found in src/functions (local) ')
|
|
411
|
+
.option('-d, --dir <dir>', 'functions directory', 'src/functions')
|
|
412
|
+
.action(async (options) => {
|
|
413
|
+
const functions = await loadFunctions(path.resolve(options.dir));
|
|
414
|
+
if (functions.length === 0) {
|
|
415
|
+
console.log('no functions found');
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
for (const fn of functions) {
|
|
419
|
+
const triggers = fn.definition.triggers
|
|
420
|
+
.map((t) => ('event' in t ? `event:${t.event}` : `cron:${t.cron}`))
|
|
421
|
+
.join(', ');
|
|
422
|
+
console.log(`${fn.definition.identifier} [${triggers}] hash=${fn.definitionHash}`);
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
program
|
|
426
|
+
.command('test')
|
|
427
|
+
.description('Execute a function locally with a mock event (no control plane needed)')
|
|
428
|
+
.argument('<identifier>', 'function identifier')
|
|
429
|
+
.option('-e, --event <json>', 'event payload JSON', '{}')
|
|
430
|
+
.option('-d, --dir <dir>', 'functions directory', 'src/functions')
|
|
431
|
+
.action(async (identifier, options) => {
|
|
432
|
+
const functions = await loadFunctions(path.resolve(options.dir));
|
|
433
|
+
const fn = functions.find((f) => f.definition.identifier === identifier);
|
|
434
|
+
if (!fn) {
|
|
435
|
+
console.error(`function "${identifier}" not found in ${options.dir}`);
|
|
436
|
+
process.exit(1);
|
|
437
|
+
}
|
|
438
|
+
const result = await executeAssignment(fn, {
|
|
439
|
+
taskId: 'local-test',
|
|
440
|
+
runId: 'local-test',
|
|
441
|
+
functionIdentifier: identifier,
|
|
442
|
+
functionDefinitionHash: fn.definitionHash,
|
|
443
|
+
event: {
|
|
444
|
+
id: 'local-event',
|
|
445
|
+
name: 'event' in fn.definition.triggers[0] ? fn.definition.triggers[0].event : 'manual',
|
|
446
|
+
data: JSON.parse(options.event),
|
|
447
|
+
ts: new Date().toISOString(),
|
|
448
|
+
},
|
|
449
|
+
attempt: 1,
|
|
450
|
+
maxAttempts: 1,
|
|
451
|
+
completedSteps: {},
|
|
452
|
+
}, {
|
|
453
|
+
stepStarted: (id) => console.log(` step ${id}: started`),
|
|
454
|
+
stepCompleted: (id, _output, ms) => console.log(` step ${id}: completed in ${ms}ms`),
|
|
455
|
+
stepFailed: (id, error) => console.log(` step ${id}: FAILED ${error.message}`),
|
|
456
|
+
stepSleeping: (id, until) => console.log(` step ${id}: sleeping until ${until.toISOString()}`),
|
|
457
|
+
stepWaiting: (id, eventName, timeoutAt) => console.log(` step ${id}: waiting for "${eventName}" until ${timeoutAt.toISOString()}`),
|
|
458
|
+
stepSentEvent: (id, eventName) => console.log(` step ${id}: sent event "${eventName}"`),
|
|
459
|
+
stepInvoking: (id, fn) => console.log(` step ${id}: invoking "${fn}"`),
|
|
460
|
+
setCurrentStep: () => { },
|
|
461
|
+
}, (severity, body) => console.log(` [${severity}] ${body}`));
|
|
462
|
+
console.log('');
|
|
463
|
+
console.log(`status: ${result.status}`);
|
|
464
|
+
if (result.status === 'completed')
|
|
465
|
+
console.log(`output: ${JSON.stringify(result.output, null, 2)}`);
|
|
466
|
+
if (result.status === 'failed') {
|
|
467
|
+
console.log(`error: ${result.error.message}`);
|
|
468
|
+
process.exit(1);
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
program.parseAsync().catch((err) => {
|
|
472
|
+
console.error(err);
|
|
473
|
+
process.exit(1);
|
|
474
|
+
});
|
|
475
|
+
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "runnix",
|
|
3
|
+
"version": "0.4.0-rc.0",
|
|
4
|
+
"license": "AGPL-3.0-or-later",
|
|
5
|
+
"description": "Runnix CLI: deploy runsets with their worker images, verify worker builds, inspect deploys, promote rollbacks.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"runnix",
|
|
8
|
+
"hetuh",
|
|
9
|
+
"workflow",
|
|
10
|
+
"orchestration",
|
|
11
|
+
"deploy",
|
|
12
|
+
"cli"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://runnix.run",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"email": "hello@hetuh.dev"
|
|
17
|
+
},
|
|
18
|
+
"type": "module",
|
|
19
|
+
"bin": {
|
|
20
|
+
"runnix": "./bin/runnix.mjs"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"bin",
|
|
24
|
+
"dist",
|
|
25
|
+
"README.md",
|
|
26
|
+
"LICENSE"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=22"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"commander": "15.0.0",
|
|
36
|
+
"tsx": "4.22.4",
|
|
37
|
+
"@runnix/protocol": "0.4.0",
|
|
38
|
+
"@runnix/sdk": "0.4.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/node": "25.9.2",
|
|
42
|
+
"typescript": "6.0.3",
|
|
43
|
+
"vitest": "4.1.8"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"dev": "tsx src/main.ts",
|
|
47
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
48
|
+
"typecheck": "tsc --noEmit"
|
|
49
|
+
}
|
|
50
|
+
}
|