@lumenflow/cli 5.7.12 → 5.7.14

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,230 +0,0 @@
1
- #!/usr/bin/env node
2
- // Copyright (c) 2026 Hellmai Ltd
3
- // SPDX-License-Identifier: LicenseRef-LumenFlow-Proprietary
4
- /**
5
- * distribution:preflight CLI Command (WU-2898)
6
- *
7
- * Audits every consumer repo that installs @lumenflow/* and reports whether
8
- * each one is ready for the npm-access flip from "public" to "restricted".
9
- *
10
- * For each consumer the preflight checks:
11
- * - GitHub: NPM_TOKEN is registered as an Actions secret on the repo
12
- * (`gh api repos/<repo>/actions/secrets`), and the repo has a `.npmrc`
13
- * wired to the token.
14
- * - Azure DevOps: prints a documented manual-check instruction. We cannot
15
- * read pipeline secret variables programmatically without standing up an
16
- * `az` PAT, so the report flags Azure rows as "needs manual check" so
17
- * Tom can verify in the Azure DevOps web UI before the flip.
18
- *
19
- * Exits non-zero if any GitHub consumer is missing wiring, or if any Azure
20
- * DevOps row is unverified. Print a single table and a copy/paste remediation
21
- * footer so an operator can fix the gap and re-run.
22
- *
23
- * Usage:
24
- * pnpm distribution:preflight
25
- * pnpm distribution:preflight --json
26
- */
27
- import { execFileSync } from 'node:child_process';
28
- import { WU_STATUS } from '@lumenflow/core';
29
- import chalk from 'chalk';
30
- import Table from 'cli-table3';
31
- import { Command } from 'commander';
32
- export const DEFAULT_CONSUMERS = [
33
- { kind: 'github', repo: 'hellmai/lumenflow-dev' },
34
- { kind: 'github', repo: 'hellmai/lumenflow-cloud' },
35
- { kind: 'github', repo: 'hellmai/patientpath.co.uk' },
36
- { kind: 'azure-devops', project: 'skynexe', repo: 'skynexe-hub' },
37
- { kind: 'azure-devops', project: 'skynexe', repo: 'skynexe-fund-analyser' },
38
- { kind: 'azure-devops', project: 'skynexe', repo: 'skynexe-risk' },
39
- ];
40
- /**
41
- * Production GitHub probe. Shells out to `gh` (already required by other
42
- * lifecycle commands), expecting the operator to be authenticated.
43
- */
44
- export const defaultRunGh = (args) => {
45
- // sonarjs/no-os-command-from-path: this is a developer-machine CLI tool
46
- // intentionally invoked by name so the operator's `gh` install (homebrew,
47
- // apt, scoop, etc.) is picked up. Hard-coding an absolute path would
48
- // break portability across the Mac/Linux/CI surfaces this script targets.
49
- // eslint-disable-next-line sonarjs/no-os-command-from-path
50
- return execFileSync('gh', args, {
51
- encoding: 'utf8',
52
- stdio: ['ignore', 'pipe', 'pipe'],
53
- });
54
- };
55
- const NPM_TOKEN_NAME = 'NPM_TOKEN';
56
- /**
57
- * Probe a single GitHub consumer. Returns a ConsumerReport row.
58
- *
59
- * Failure semantics: if `gh` is unauthenticated or the repo is unreachable,
60
- * we return `npmTokenPresent: false` with a diagnostic note rather than
61
- * throwing — the preflight should report ALL consumer states in one pass,
62
- * not abort on the first error.
63
- */
64
- export function probeGitHubConsumer(consumer, deps) {
65
- const repo = consumer.repo;
66
- let npmTokenPresent = false;
67
- let npmrcWired = false;
68
- const notes = [];
69
- // Check 1: repo Actions secrets contain NPM_TOKEN
70
- try {
71
- const stdout = deps.runGh(['api', `repos/${repo}/actions/secrets`]);
72
- const parsed = JSON.parse(stdout);
73
- const secrets = parsed.secrets ?? [];
74
- npmTokenPresent = secrets.some((s) => s.name === NPM_TOKEN_NAME);
75
- if (!npmTokenPresent) {
76
- notes.push(`secret ${NPM_TOKEN_NAME} not found on ${repo}`);
77
- }
78
- }
79
- catch (error) {
80
- notes.push(`gh secrets probe failed: ${error instanceof Error ? error.message : String(error)}`);
81
- }
82
- // Check 2: repo root contains a .npmrc with NPM_TOKEN auth
83
- try {
84
- const stdout = deps.runGh(['api', `repos/${repo}/contents/.npmrc`]);
85
- const parsed = JSON.parse(stdout);
86
- if (parsed.content && parsed.encoding === 'base64') {
87
- const decoded = Buffer.from(parsed.content, 'base64').toString('utf8');
88
- npmrcWired = /_authToken=\$\{?NPM_TOKEN\}?/.test(decoded);
89
- if (!npmrcWired) {
90
- notes.push(`.npmrc found on ${repo} but does not reference NPM_TOKEN`);
91
- }
92
- }
93
- else {
94
- notes.push(`.npmrc payload on ${repo} not in expected base64 shape`);
95
- }
96
- }
97
- catch (error) {
98
- notes.push(`.npmrc probe failed (${repo}): ${error instanceof Error ? error.message : String(error)}`);
99
- }
100
- return {
101
- repo,
102
- platform: 'github',
103
- npmTokenPresent,
104
- npmrcWired,
105
- readyToFlip: npmTokenPresent && npmrcWired,
106
- note: notes.join('; ') || 'OK',
107
- };
108
- }
109
- /**
110
- * Build the manual-check report row for an Azure DevOps consumer.
111
- *
112
- * We deliberately do NOT shell out to `az` here. Authenticating the Azure
113
- * DevOps CLI requires per-developer PAT setup that the LumenFlow CI surface
114
- * does not own. Treating the row as "needs manual check" is honest — a false
115
- * green here would directly cause the consumer pipelines to break on the
116
- * privatization flip.
117
- */
118
- export function buildAzureDevOpsRow(consumer) {
119
- const repo = `${consumer.project}/${consumer.repo}`;
120
- return {
121
- repo,
122
- platform: 'azure-devops',
123
- npmTokenPresent: null,
124
- npmrcWired: null,
125
- readyToFlip: null,
126
- note: 'manual check required — verify pipeline variable NPM_TOKEN is set as a secret ' +
127
- 'and that .npmrc is wired in the repo root',
128
- };
129
- }
130
- /**
131
- * Run the full preflight against the supplied consumer list. Returns the
132
- * raw report rows — formatting/exit-code policy is applied by `main`.
133
- */
134
- export function runPreflight(consumers, deps = { runGh: defaultRunGh }) {
135
- return consumers.map((c) => c.kind === 'github' ? probeGitHubConsumer(c, deps) : buildAzureDevOpsRow(c));
136
- }
137
- /**
138
- * Pretty-print the report as an aligned ASCII table.
139
- *
140
- * The status column uses three glyphs:
141
- * ready = both checks passed (GitHub) — safe to flip
142
- * FAIL = GitHub repo missing NPM_TOKEN or .npmrc — fix before flip
143
- * manual = Azure DevOps row — operator must verify out-of-band
144
- */
145
- export function formatReport(rows) {
146
- const table = new Table({
147
- head: ['Consumer', 'Platform', 'NPM_TOKEN', '.npmrc', 'Ready', 'Note'],
148
- style: { head: [] },
149
- });
150
- const triBool = (v) => {
151
- if (v === null)
152
- return chalk.yellow('manual');
153
- return v ? chalk.green('yes') : chalk.red('no');
154
- };
155
- const status = (row) => {
156
- if (row.readyToFlip === null)
157
- return chalk.yellow('manual');
158
- if (row.readyToFlip)
159
- return chalk.green(WU_STATUS.READY);
160
- return chalk.red('FAIL');
161
- };
162
- for (const row of rows) {
163
- table.push([
164
- row.repo,
165
- row.platform,
166
- triBool(row.npmTokenPresent),
167
- triBool(row.npmrcWired),
168
- status(row),
169
- row.note,
170
- ]);
171
- }
172
- return table.toString();
173
- }
174
- /**
175
- * Compute the exit code policy. Non-zero if any GitHub row failed or any
176
- * row needs manual verification (since the operator MUST acknowledge the
177
- * Azure rows before the flip is safe).
178
- */
179
- export function computeExitCode(rows) {
180
- const anyFail = rows.some((r) => r.readyToFlip === false);
181
- const anyManual = rows.some((r) => r.readyToFlip === null);
182
- return anyFail || anyManual ? 1 : 0;
183
- }
184
- /**
185
- * CLI entry point. Returns the resolved exit code so tests can assert it
186
- * without spawning a subprocess.
187
- */
188
- export function main(argv = process.argv, deps = { runGh: defaultRunGh }, log = (m) => console.log(m)) {
189
- const program = new Command()
190
- .name('distribution-preflight')
191
- .description('Audit consumer repos for @lumenflow/* privatization readiness (WU-2898)')
192
- .option('--json', 'Emit raw JSON instead of an ASCII table', false)
193
- .parse(argv);
194
- const opts = program.opts();
195
- const rows = runPreflight(DEFAULT_CONSUMERS, deps);
196
- if (opts.json) {
197
- log(JSON.stringify(rows, null, 2));
198
- }
199
- else {
200
- log(formatReport(rows));
201
- const failed = rows.filter((r) => r.readyToFlip === false);
202
- const manual = rows.filter((r) => r.readyToFlip === null);
203
- if (failed.length > 0) {
204
- log('');
205
- log(chalk.red(`✗ ${failed.length} GitHub consumer(s) not ready:`));
206
- for (const r of failed)
207
- log(` - ${r.repo}: ${r.note}`);
208
- }
209
- if (manual.length > 0) {
210
- log('');
211
- log(chalk.yellow(`⚠ ${manual.length} Azure DevOps consumer(s) need manual verification:`));
212
- for (const r of manual)
213
- log(` - ${r.repo}: ${r.note}`);
214
- }
215
- if (failed.length === 0 && manual.length === 0) {
216
- log('');
217
- log(chalk.green('✓ all consumers ready to flip'));
218
- }
219
- }
220
- return computeExitCode(rows);
221
- }
222
- // Run when invoked directly (not when imported by tests).
223
- const isDirectInvocation = import.meta.url === `file://${process.argv[1]}` ||
224
- // tsup bundles the CLI as ESM with the bin shim — argv[1] still ends with
225
- // distribution-preflight.js so this guard remains correct after build.
226
- process.argv[1]?.endsWith('distribution-preflight.js');
227
- if (isDirectInvocation) {
228
- process.exit(main());
229
- }
230
- //# sourceMappingURL=distribution-preflight.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"distribution-preflight.js","sourceRoot":"","sources":["../src/distribution-preflight.ts"],"names":[],"mappings":"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"}