@celilo/cli 0.9.1 → 0.10.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/CELILO_CORE_MODULES.md +1 -1
- package/CELILO_SUBSYSTEMS.md +1 -0
- package/package.json +9 -3
- package/src/cli/commands/publish/helpers.ts +18 -0
- package/src/cli/commands/publish/types.ts +6 -8
- package/src/cli/commands/publish/workspace.test.ts +44 -7
- package/src/cli/commands/publish/workspace.ts +40 -164
package/CELILO_CORE_MODULES.md
CHANGED
|
@@ -44,7 +44,7 @@ Each entry: `module id` — what it is — **provides** / **requires** capabilit
|
|
|
44
44
|
- **forgejo** — self-hosted Forgejo git forge (git-over-SSH, OIDC, public ingress). **provides:** `source_forge`. **requires:** `public_web`, `idp`, `firewall`, `dns_registrar`. See `v2/CI_PIPELINE.md`.
|
|
45
45
|
- **forgejo-runner** — host-mode (LXC) Forgejo Actions runner for unit/lint jobs; outbound-only, lives in dmz. **requires:** `source_forge`. See `v2/FORGEJO_RUNNER.md`.
|
|
46
46
|
- **forgejo-builder** — VM-based, Docker-capable Forgejo Actions runner (`requires.system.type: vm`) for hermetic release builds + the cele2e suite. **requires:** `source_forge`.
|
|
47
|
-
- **npm-cache-node** — self-hosted npm registry
|
|
47
|
+
- **npm-cache-node** — self-hosted npm registry: a pass-through disk cache (proxies upstream) plus a `PUT /<pkg>` publish endpoint that stores locally published `@celilo/*` tarballs as authoritative local-origin (never overwritten by upstream). PUT is gated on a static operator-set publish token (`publish_tokens` secret, SHA-256 model; fail-closed — absent/bad token → 401); reads stay open (it's a mirror). **requires:** `public_web`, `dns_registrar`. See `v2/NPM_CACHE_NODE.md`.
|
|
48
48
|
|
|
49
49
|
## Applications
|
|
50
50
|
|
package/CELILO_SUBSYSTEMS.md
CHANGED
|
@@ -81,3 +81,4 @@ see `design/README.md`. Companion doc: [CELILO_CORE_MODULES.md](./CELILO_CORE_MO
|
|
|
81
81
|
|
|
82
82
|
- **cele2e harness** — `packages/e2e/src/` — `runner.ts`, `container-manager.ts` (`startNetwork`, `reconnectNetwork`), `network-builder.ts` (`NetworkBuilder`).
|
|
83
83
|
- **Run wrapper** — `infra/scripts/cele2e-run.sh` lives in the separate `infra/` clone, **not** in this repo. See the cele2e section of the repo-root `CLAUDE.md` for the operator workflow.
|
|
84
|
+
- **MCP server (agent-driven e2e)** — `packages/mcp-server/src/index.ts` — stdio MCP server exposing `start_run`/`run_status`/`run_result`/`stop_run` (detached cele2e runs read off the event bus, no ANSI scraping) + `env_check` (docker VM, run-lock, shared-infra, mgmt image CLI version, netapps). Dev/ops tool, `private`, not shipped to consumers.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@celilo/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Celilo — home lab orchestration CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -16,7 +16,13 @@
|
|
|
16
16
|
"CELILO_SUBSYSTEMS.md",
|
|
17
17
|
"CELILO_CORE_MODULES.md"
|
|
18
18
|
],
|
|
19
|
-
"keywords": [
|
|
19
|
+
"keywords": [
|
|
20
|
+
"celilo",
|
|
21
|
+
"homelab",
|
|
22
|
+
"orchestration",
|
|
23
|
+
"ansible",
|
|
24
|
+
"terraform"
|
|
25
|
+
],
|
|
20
26
|
"license": "MIT",
|
|
21
27
|
"repository": {
|
|
22
28
|
"type": "git",
|
|
@@ -51,7 +57,7 @@
|
|
|
51
57
|
"@aws-sdk/client-s3": "^3.1024.0",
|
|
52
58
|
"@celilo/capabilities": "^0.6.0",
|
|
53
59
|
"@celilo/cli-display": "^0.1.9",
|
|
54
|
-
"@celilo/event-bus": "^0.1.
|
|
60
|
+
"@celilo/event-bus": "^0.1.8",
|
|
55
61
|
"@clack/prompts": "^1.1.0",
|
|
56
62
|
"ajv": "^8.18.0",
|
|
57
63
|
"drizzle-orm": "^0.36.4",
|
|
@@ -125,6 +125,24 @@ export function readExternalProjectPaths(): string[] {
|
|
|
125
125
|
return [];
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Read `NPM_PUBLISH_TARGET` from .env — the registry URL `celilo publish`
|
|
130
|
+
* points `bun publish --registry` at for @celilo/* packages (a deployed
|
|
131
|
+
* npm-cache-node). Unset → publish to npmjs (current behavior). See
|
|
132
|
+
* v2/NPM_CACHE_NODE.md Phase 3.1 / v2/PUBLILO_CLI.md decision 10.
|
|
133
|
+
*/
|
|
134
|
+
export function readNpmPublishTarget(): string | null {
|
|
135
|
+
if (!existsSync(ENV_FILE)) return null;
|
|
136
|
+
const content = readFileSync(ENV_FILE, 'utf-8');
|
|
137
|
+
for (const line of content.split('\n')) {
|
|
138
|
+
const m = line.match(/^\s*NPM_PUBLISH_TARGET\s*=\s*(.+?)\s*$/);
|
|
139
|
+
if (!m) continue;
|
|
140
|
+
const raw = m[1].replace(/^["']|["']$/g, '').trim();
|
|
141
|
+
return raw || null;
|
|
142
|
+
}
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
|
|
128
146
|
/**
|
|
129
147
|
* Recursively find every package.json under a root, skipping
|
|
130
148
|
* node_modules and common build-output dirs (so we don't try to rewrite
|
|
@@ -139,15 +139,13 @@ export interface RewriteOptions {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
/**
|
|
142
|
-
* Per-package pre-publish work. Currently only `@celilo/e2e` triggers
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
142
|
+
* Per-package pre-publish work. Currently only `@celilo/e2e` triggers this
|
|
143
|
+
* (it bundles the npm-compat registry server source inside its tarball).
|
|
144
|
+
* Sim-content caches (website/npm) and standard-module netapps are NOT
|
|
145
|
+
* bundled at publish — they're fetched from the public celilo sources at
|
|
146
|
+
* `cele2e build-infra` time instead (ce-qwz Decisions 2B + 3, ce-i2i).
|
|
146
147
|
*/
|
|
147
|
-
export type PrePublishHookKind =
|
|
148
|
-
| 'registryServerBundle'
|
|
149
|
-
| 'rebuildE2eNetapps'
|
|
150
|
-
| 'stageE2ePublishCaches';
|
|
148
|
+
export type PrePublishHookKind = 'registryServerBundle';
|
|
151
149
|
|
|
152
150
|
/**
|
|
153
151
|
* Single workspace package planned to publish (or explicitly skip) in
|
|
@@ -57,6 +57,7 @@ mock.module('./helpers', () => ({
|
|
|
57
57
|
},
|
|
58
58
|
listModuleDirs: () => [],
|
|
59
59
|
readExternalProjectPaths: () => [],
|
|
60
|
+
readNpmPublishTarget: () => null,
|
|
60
61
|
findPackageJsons: () => [],
|
|
61
62
|
bareVersion: (s: string) => s.replace(/^[\s^~=><]+/, '').trim(),
|
|
62
63
|
withOperator: (oldSpec: string, newVersion: string) => {
|
|
@@ -74,6 +75,10 @@ mock.module('./alpha', () => ({
|
|
|
74
75
|
return { name: spec.slice(0, i), version: spec.slice(i + 1) };
|
|
75
76
|
},
|
|
76
77
|
stripAlphaSuffix: (v: string) => v.replace(/-alpha\.\d+$/, ''),
|
|
78
|
+
prereleaseDistTag: (v: string) => {
|
|
79
|
+
const dash = v.indexOf('-');
|
|
80
|
+
return dash === -1 ? undefined : v.slice(dash + 1).split('.')[0] || undefined;
|
|
81
|
+
},
|
|
77
82
|
isAlphaVersion: (v: string) => /-alpha\.\d+$/.test(v),
|
|
78
83
|
nextAlphaNumber: (name: string, semverCore: string) =>
|
|
79
84
|
nextAlphaResponses[`${name}@${semverCore}`] ?? 0,
|
|
@@ -84,7 +89,7 @@ mock.module('./alpha', () => ({
|
|
|
84
89
|
decideAlphaSkip: () => ({ skip: false }),
|
|
85
90
|
}));
|
|
86
91
|
|
|
87
|
-
const { planWorkspace } = await import('./workspace');
|
|
92
|
+
const { planWorkspace, buildPublishArgs } = await import('./workspace');
|
|
88
93
|
|
|
89
94
|
function buildBaseMap(): Map<string, string> {
|
|
90
95
|
const m = new Map<string, string>();
|
|
@@ -131,7 +136,7 @@ describe('planWorkspace', () => {
|
|
|
131
136
|
expect(cli?.skipReason).toBeUndefined();
|
|
132
137
|
});
|
|
133
138
|
|
|
134
|
-
test('e2e gets the registry-bundle
|
|
139
|
+
test('e2e gets only the registry-bundle hook (caches/netapps fetched at build-infra, not bundled)', () => {
|
|
135
140
|
publishedSet = new Set();
|
|
136
141
|
const result = planWorkspace({
|
|
137
142
|
mode: { kind: 'normal' },
|
|
@@ -141,11 +146,7 @@ describe('planWorkspace', () => {
|
|
|
141
146
|
});
|
|
142
147
|
|
|
143
148
|
const e2e = result.items.find((i) => i.pkg === 'packages/e2e');
|
|
144
|
-
expect(e2e?.hooks).toEqual([
|
|
145
|
-
'registryServerBundle',
|
|
146
|
-
'rebuildE2eNetapps',
|
|
147
|
-
'stageE2ePublishCaches',
|
|
148
|
-
]);
|
|
149
|
+
expect(e2e?.hooks).toEqual(['registryServerBundle']);
|
|
149
150
|
const cli = result.items.find((i) => i.pkg === 'apps/celilo');
|
|
150
151
|
expect(cli?.hooks).toEqual([]);
|
|
151
152
|
});
|
|
@@ -302,6 +303,42 @@ describe('planWorkspace', () => {
|
|
|
302
303
|
});
|
|
303
304
|
});
|
|
304
305
|
|
|
306
|
+
describe('buildPublishArgs registry target', () => {
|
|
307
|
+
test('no target → default registry (unchanged behavior)', () => {
|
|
308
|
+
expect(buildPublishArgs({ name: '@celilo/cli', tag: undefined }, null)).toEqual([
|
|
309
|
+
'publish',
|
|
310
|
+
'--access',
|
|
311
|
+
'public',
|
|
312
|
+
]);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
test('target set → --registry appended for @celilo/* package', () => {
|
|
316
|
+
expect(
|
|
317
|
+
buildPublishArgs({ name: '@celilo/cli', tag: undefined }, 'https://npm.example.test/'),
|
|
318
|
+
).toEqual(['publish', '--access', 'public', '--registry', 'https://npm.example.test/']);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
test('tag and registry both present', () => {
|
|
322
|
+
expect(
|
|
323
|
+
buildPublishArgs({ name: '@celilo/cli', tag: 'alpha' }, 'https://npm.example.test/'),
|
|
324
|
+
).toEqual([
|
|
325
|
+
'publish',
|
|
326
|
+
'--access',
|
|
327
|
+
'public',
|
|
328
|
+
'--tag',
|
|
329
|
+
'alpha',
|
|
330
|
+
'--registry',
|
|
331
|
+
'https://npm.example.test/',
|
|
332
|
+
]);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
test('non-@celilo package never gets the private registry', () => {
|
|
336
|
+
expect(
|
|
337
|
+
buildPublishArgs({ name: 'some-other-pkg', tag: undefined }, 'https://npm.example.test/'),
|
|
338
|
+
).toEqual(['publish', '--access', 'public']);
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
|
|
305
342
|
describe('dependency order', () => {
|
|
306
343
|
test('preserves PACKAGES order in planned items', () => {
|
|
307
344
|
publishedSet = new Set();
|
|
@@ -17,18 +17,8 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { spawnSync } from 'node:child_process';
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
existsSync,
|
|
23
|
-
mkdirSync,
|
|
24
|
-
readFileSync,
|
|
25
|
-
readdirSync,
|
|
26
|
-
rmSync,
|
|
27
|
-
statSync,
|
|
28
|
-
unlinkSync,
|
|
29
|
-
writeFileSync,
|
|
30
|
-
} from 'node:fs';
|
|
31
|
-
import { join, relative } from 'node:path';
|
|
20
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
21
|
+
import { join } from 'node:path';
|
|
32
22
|
import {
|
|
33
23
|
ALPHA_TAG,
|
|
34
24
|
alphaSkipDecision,
|
|
@@ -36,7 +26,7 @@ import {
|
|
|
36
26
|
prereleaseDistTag,
|
|
37
27
|
stripAlphaSuffix,
|
|
38
28
|
} from './alpha';
|
|
39
|
-
import { REPO_ROOT, isPublished, readPkg } from './helpers';
|
|
29
|
+
import { REPO_ROOT, isPublished, readNpmPublishTarget, readPkg } from './helpers';
|
|
40
30
|
import type {
|
|
41
31
|
PackageJson,
|
|
42
32
|
PublishMode,
|
|
@@ -74,13 +64,15 @@ export interface PlanWorkspaceOutput {
|
|
|
74
64
|
|
|
75
65
|
/**
|
|
76
66
|
* Pre-publish hooks that fire for @celilo/e2e (the only package that
|
|
77
|
-
* needs
|
|
78
|
-
*
|
|
79
|
-
*
|
|
67
|
+
* needs one today): refresh the bundled npm-compat registry-server source.
|
|
68
|
+
* Sim-content caches and standard-module netapps are no longer staged into
|
|
69
|
+
* the tarball at publish — a monorepo-free consumer fetches them from the
|
|
70
|
+
* public celilo sources at `cele2e build-infra` time (ce-qwz Decisions
|
|
71
|
+
* 2B + 3, ce-i2i).
|
|
80
72
|
*/
|
|
81
73
|
function workspaceHooksFor(pkg: string): WorkspaceItem['hooks'] {
|
|
82
74
|
if (pkg !== 'packages/e2e') return [];
|
|
83
|
-
return ['registryServerBundle'
|
|
75
|
+
return ['registryServerBundle'];
|
|
84
76
|
}
|
|
85
77
|
|
|
86
78
|
/**
|
|
@@ -328,147 +320,23 @@ export async function verifyPublishedDeps(
|
|
|
328
320
|
}
|
|
329
321
|
}
|
|
330
322
|
|
|
331
|
-
// ─── Per-package pre-publish hooks ─────────────────────────────────
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Modules excluded from the @celilo/e2e netapps shipment:
|
|
335
|
-
* - celilo-registry: bundles the bun-compiled registry server
|
|
336
|
-
* binaries (~76 MB packed). Not used by typical consumer e2e
|
|
337
|
-
* tests; including it would bloat the npm tarball past the SSL
|
|
338
|
-
* transport's reliable window.
|
|
339
|
-
* - archive: not a real module dir.
|
|
340
|
-
*/
|
|
341
|
-
const E2E_NETAPP_EXCLUDES = new Set(['archive', 'celilo-registry']);
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* Pre-publish step for @celilo/e2e: package each (non-excluded)
|
|
345
|
-
* module under `<root>/modules/` into `packages/e2e/netapps/`. Replaces
|
|
346
|
-
* whatever was last left there by a local `cele2e build-infra` so the
|
|
347
|
-
* shipped tarball is always built from the current branch, not the
|
|
348
|
-
* publisher's last local development build.
|
|
349
|
-
*/
|
|
350
|
-
export function rebuildE2eNetapps(repoRoot: string): void {
|
|
351
|
-
const modulesDir = join(repoRoot, 'modules');
|
|
352
|
-
const netappsDir = join(repoRoot, 'packages/e2e/netapps');
|
|
353
|
-
const celiloWrapper = join(repoRoot, 'celilo');
|
|
354
|
-
|
|
355
|
-
if (!existsSync(modulesDir)) {
|
|
356
|
-
console.warn(
|
|
357
|
-
`⚠ ${modulesDir} not found — skipping netapp rebuild. The published tarball will reuse whatever's currently in packages/e2e/netapps/.`,
|
|
358
|
-
);
|
|
359
|
-
return;
|
|
360
|
-
}
|
|
361
|
-
if (!existsSync(celiloWrapper)) {
|
|
362
|
-
console.warn(
|
|
363
|
-
`⚠ ${celiloWrapper} not found — skipping netapp rebuild. Same staleness risk as above.`,
|
|
364
|
-
);
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
console.log('Rebuilding packages/e2e/netapps/ from infra/modules/...');
|
|
369
|
-
|
|
370
|
-
for (const existing of readdirSync(netappsDir).filter((f) => f.endsWith('.netapp'))) {
|
|
371
|
-
try {
|
|
372
|
-
unlinkSync(join(netappsDir, existing));
|
|
373
|
-
} catch {
|
|
374
|
-
// Best effort
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
const moduleDirs = readdirSync(modulesDir).filter((name) => {
|
|
379
|
-
if (E2E_NETAPP_EXCLUDES.has(name)) return false;
|
|
380
|
-
const dir = join(modulesDir, name);
|
|
381
|
-
try {
|
|
382
|
-
return statSync(dir).isDirectory() && existsSync(join(dir, 'manifest.yml'));
|
|
383
|
-
} catch {
|
|
384
|
-
return false;
|
|
385
|
-
}
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
let okCount = 0;
|
|
389
|
-
const failures: Array<{ name: string; stderr: string }> = [];
|
|
390
|
-
for (const name of moduleDirs) {
|
|
391
|
-
const moduleDir = join(modulesDir, name);
|
|
392
|
-
const out = join(netappsDir, `${name}.netapp`);
|
|
393
|
-
const r = spawnSync(celiloWrapper, ['package', moduleDir, '--output', out], {
|
|
394
|
-
cwd: repoRoot,
|
|
395
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
396
|
-
encoding: 'utf-8',
|
|
397
|
-
});
|
|
398
|
-
if (r.status === 0) {
|
|
399
|
-
okCount++;
|
|
400
|
-
} else {
|
|
401
|
-
failures.push({ name, stderr: (r.stderr ?? '').trim() || `exit ${r.status}` });
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
if (failures.length > 0) {
|
|
406
|
-
console.error(`✗ Failed to package ${failures.length} module(s):`);
|
|
407
|
-
for (const f of failures) {
|
|
408
|
-
console.error(` ${f.name}: ${f.stderr}`);
|
|
409
|
-
}
|
|
410
|
-
console.error(
|
|
411
|
-
'Aborting publish — shipping with missing netapps would silently break consumer e2e tests.',
|
|
412
|
-
);
|
|
413
|
-
process.exit(1);
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
console.log(
|
|
417
|
-
`Refreshed ${okCount} netapp(s) in packages/e2e/netapps/ (excluded: ${[...E2E_NETAPP_EXCLUDES].join(', ')}).\n`,
|
|
418
|
-
);
|
|
419
|
-
}
|
|
420
|
-
|
|
421
323
|
/**
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
*
|
|
324
|
+
* Build the `bun publish` argv for a workspace item. When a private
|
|
325
|
+
* registry target is configured (a deployed npm-cache-node) AND the
|
|
326
|
+
* package is @celilo/*-scoped, point bun at it via --registry; otherwise
|
|
327
|
+
* publish to the default registry (npmjs — current behavior).
|
|
328
|
+
* v2/NPM_CACHE_NODE.md Phase 3.1 / v2/PUBLILO_CLI.md decision 10.
|
|
426
329
|
*/
|
|
427
|
-
export function
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
const
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
console.error(`✗ ${websiteSrc} not found — cannot stage .celilo-website-cache.`);
|
|
436
|
-
process.exit(1);
|
|
330
|
+
export function buildPublishArgs(
|
|
331
|
+
item: Pick<WorkspaceItem, 'name' | 'tag'>,
|
|
332
|
+
registryTarget: string | null,
|
|
333
|
+
): string[] {
|
|
334
|
+
const args = ['publish', '--access', 'public'];
|
|
335
|
+
if (item.tag) args.push('--tag', item.tag);
|
|
336
|
+
if (registryTarget && item.name.startsWith('@celilo/')) {
|
|
337
|
+
args.push('--registry', registryTarget);
|
|
437
338
|
}
|
|
438
|
-
|
|
439
|
-
console.error(`✗ ${packScript} not found — cannot stage .npm-registry-cache.`);
|
|
440
|
-
process.exit(1);
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
console.log('Staging .celilo-website-cache/ from modules/celilo-website/site/...');
|
|
444
|
-
const installResult = spawnSync('bun', ['install'], { cwd: websiteSrc, stdio: 'pipe' });
|
|
445
|
-
if (installResult.status !== 0) {
|
|
446
|
-
console.error('✗ bun install for celilo-website failed:');
|
|
447
|
-
console.error(installResult.stderr?.toString());
|
|
448
|
-
process.exit(1);
|
|
449
|
-
}
|
|
450
|
-
const buildResult = spawnSync('bun', ['run', 'build'], { cwd: websiteSrc, stdio: 'pipe' });
|
|
451
|
-
if (buildResult.status !== 0) {
|
|
452
|
-
console.error('✗ bun run build for celilo-website failed:');
|
|
453
|
-
console.error(buildResult.stderr?.toString());
|
|
454
|
-
process.exit(1);
|
|
455
|
-
}
|
|
456
|
-
rmSync(websiteCache, { recursive: true, force: true });
|
|
457
|
-
mkdirSync(websiteCache, { recursive: true });
|
|
458
|
-
cpSync(join(websiteSrc, 'dist'), websiteCache, { recursive: true });
|
|
459
|
-
console.log(`✓ Staged .celilo-website-cache/ (from ${relative(repoRoot, websiteSrc)}/dist/)\n`);
|
|
460
|
-
|
|
461
|
-
console.log('Staging .npm-registry-cache/ from @celilo/* workspace tarballs...');
|
|
462
|
-
const packResult = spawnSync('bun', ['run', packScript], { cwd: repoRoot, stdio: 'pipe' });
|
|
463
|
-
if (packResult.status !== 0) {
|
|
464
|
-
console.error('✗ pack-celilo-packages.ts failed:');
|
|
465
|
-
console.error(packResult.stderr?.toString());
|
|
466
|
-
process.exit(1);
|
|
467
|
-
}
|
|
468
|
-
const packed = existsSync(npmCache)
|
|
469
|
-
? readdirSync(npmCache).filter((f) => f.endsWith('.tgz'))
|
|
470
|
-
: [];
|
|
471
|
-
console.log(`✓ Staged .npm-registry-cache/ with ${packed.length} workspace tarball(s)\n`);
|
|
339
|
+
return args;
|
|
472
340
|
}
|
|
473
341
|
|
|
474
342
|
// ─── Executor ──────────────────────────────────────────────────────
|
|
@@ -486,6 +354,13 @@ export async function executeWorkspace(input: ExecuteWorkspaceInput): Promise<Pu
|
|
|
486
354
|
const published: PublishResult['published'] = [];
|
|
487
355
|
const skipped: string[] = [];
|
|
488
356
|
|
|
357
|
+
// When an npm-cache-node is configured, @celilo/* tarballs go there
|
|
358
|
+
// (the cache forwards upstream under policy); unset → npmjs.
|
|
359
|
+
const registryTarget = readNpmPublishTarget();
|
|
360
|
+
if (registryTarget) {
|
|
361
|
+
console.log(`\nPublishing @celilo/* to configured registry: ${registryTarget}`);
|
|
362
|
+
}
|
|
363
|
+
|
|
489
364
|
for (const item of items) {
|
|
490
365
|
const { pkg, name, baseVersion, versionToPublish } = item;
|
|
491
366
|
|
|
@@ -511,12 +386,6 @@ export async function executeWorkspace(input: ExecuteWorkspaceInput): Promise<Pu
|
|
|
511
386
|
'Refreshed packages/e2e/registry-server/ bundle from packages/registry-server.\n',
|
|
512
387
|
);
|
|
513
388
|
}
|
|
514
|
-
if (item.hooks.includes('rebuildE2eNetapps')) {
|
|
515
|
-
rebuildE2eNetapps(REPO_ROOT);
|
|
516
|
-
}
|
|
517
|
-
if (item.hooks.includes('stageE2ePublishCaches')) {
|
|
518
|
-
stageE2ePublishCaches(REPO_ROOT);
|
|
519
|
-
}
|
|
520
389
|
|
|
521
390
|
const { original: pkgJsonOriginal, rewrites: workspaceRewrites } = rewriteWorkspaceDeps(
|
|
522
391
|
pkg,
|
|
@@ -548,8 +417,7 @@ export async function executeWorkspace(input: ExecuteWorkspaceInput): Promise<Pu
|
|
|
548
417
|
process.exit(1);
|
|
549
418
|
}
|
|
550
419
|
|
|
551
|
-
const publishArgs =
|
|
552
|
-
if (item.tag) publishArgs.push('--tag', item.tag);
|
|
420
|
+
const publishArgs = buildPublishArgs(item, registryTarget);
|
|
553
421
|
|
|
554
422
|
let publishStatus: number | null = null;
|
|
555
423
|
let publishError: unknown = null;
|
|
@@ -591,7 +459,15 @@ export async function executeWorkspace(input: ExecuteWorkspaceInput): Promise<Pu
|
|
|
591
459
|
}
|
|
592
460
|
|
|
593
461
|
if (workspaceRewrites.length > 0) {
|
|
594
|
-
|
|
462
|
+
// Verify against the same registry we published to — a cache node
|
|
463
|
+
// forwards upstream under policy, so the version may not be on
|
|
464
|
+
// npmjs yet.
|
|
465
|
+
await verifyPublishedDeps(
|
|
466
|
+
name,
|
|
467
|
+
versionToPublish,
|
|
468
|
+
workspaceRewrites,
|
|
469
|
+
registryTarget ?? undefined,
|
|
470
|
+
);
|
|
595
471
|
}
|
|
596
472
|
|
|
597
473
|
// Silence the unused-var warning on baseVersion — we keep the value
|