@kungfu-tech/buildchain 3.0.4-alpha.2 → 3.0.4-alpha.3
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/bin/buildchain.mjs +126 -72
- package/bin/internal/trust-release-cli.mjs +15 -537
- package/bin/internal/trust-release-command-handlers.mjs +14 -0
- package/bin/internal/trust-release-inspection-handlers.mjs +175 -0
- package/bin/internal/trust-release-release-handlers.mjs +317 -0
- package/bin/internal/trust-release-verification-handlers.mjs +306 -0
- package/dist/site/buildchain-contract.json +35 -24
- package/dist/site/buildchain-site.json +22 -10
- package/dist/site/controller-registry.json +16 -3
- package/dist/site/kfd-claims.json +9 -7
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +2 -2
- package/dist/site/node-api-registry.json +7 -7
- package/dist/site/page-registry.json +9 -4
- package/dist/site/public-surface-audit.json +56 -8
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-model.json +7 -0
- package/dist/site/site-manifest.json +6 -6
- package/dist/site/workflow-registry.json +13 -5
- package/docs/MAP.md +1 -1
- package/docs/release-propagation.md +166 -8
- package/package.json +1 -1
- package/packages/core/buildchain-kfd-claims.js +1 -1
- package/packages/core/controller-evidence.js +8 -1
- package/packages/core/index.js +1 -13
- package/packages/core/paper-npm-bootstrap.js +492 -0
- package/packages/core/paper.js +271 -669
- package/packages/core/public-surface-cli.js +12 -1
- package/packages/core/release-passport.js +67 -71
- package/packages/core/release-propagation-common.js +64 -0
- package/packages/core/release-propagation-execution-profile.js +59 -0
- package/packages/core/release-propagation-release.js +196 -0
- package/packages/core/release-propagation-stage-evidence.js +364 -0
- package/packages/core/release-propagation-work-capture.js +64 -0
- package/packages/core/release-propagation-work-constants.js +34 -0
- package/packages/core/release-propagation-work-control.js +203 -0
- package/packages/core/release-propagation-work-transitions.js +145 -0
- package/packages/core/release-propagation-work.js +517 -0
- package/packages/core/release-propagation.js +34 -158
- package/scripts/aws-windows-jit-controller-core.mjs +269 -0
- package/scripts/aws-windows-jit-controller.mjs +502 -0
- package/scripts/check-internal-architecture.mjs +178 -52
- package/scripts/check-maintainability.mjs +76 -17
- package/scripts/generate-site-bundle.mjs +16 -7
- package/scripts/maintainability-metrics.mjs +24 -4
- package/scripts/release-propagation.mjs +126 -0
- package/scripts/resolve-artifact-transfer-mode.mjs +117 -0
- package/scripts/web-surface-core.mjs +46 -207
- package/scripts/web-surface-routing.mjs +286 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
function executePaperNpmBootstrap(options = {}, runtime) {
|
|
2
|
+
const {
|
|
3
|
+
DEFAULT_BOOTSTRAP_VERSION,
|
|
4
|
+
NPM_REGISTRY,
|
|
5
|
+
PAPER_NPM_BOOTSTRAP_CONTRACT,
|
|
6
|
+
PAPER_PATHS,
|
|
7
|
+
bootstrapPackageShape,
|
|
8
|
+
commandResult,
|
|
9
|
+
expectedPaperTrustedPublisher,
|
|
10
|
+
extractUrls,
|
|
11
|
+
fs,
|
|
12
|
+
jsonText,
|
|
13
|
+
liveNpmAuthObservation,
|
|
14
|
+
liveNpmPackageObservation,
|
|
15
|
+
liveNpmTrustObservation,
|
|
16
|
+
normalizePackageName,
|
|
17
|
+
normalizeRepository,
|
|
18
|
+
os,
|
|
19
|
+
paperConfig,
|
|
20
|
+
path,
|
|
21
|
+
resolvePaperRepository,
|
|
22
|
+
safeParseJson,
|
|
23
|
+
toPosix,
|
|
24
|
+
validatePaperProvisioningAuthority,
|
|
25
|
+
writePaperReceipt,
|
|
26
|
+
} = runtime;
|
|
27
|
+
const {
|
|
28
|
+
cwd = process.cwd(),
|
|
29
|
+
packageName = "",
|
|
30
|
+
bootstrapVersion = DEFAULT_BOOTSTRAP_VERSION,
|
|
31
|
+
registry = NPM_REGISTRY,
|
|
32
|
+
repository = "",
|
|
33
|
+
workflow = "paper-release.yml",
|
|
34
|
+
environment = "",
|
|
35
|
+
execute = false,
|
|
36
|
+
confirmedPackage = "",
|
|
37
|
+
userconfig = "",
|
|
38
|
+
offline = false,
|
|
39
|
+
} = options;
|
|
40
|
+
const resolvedCwd = path.resolve(cwd);
|
|
41
|
+
if (registry !== NPM_REGISTRY) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`paper npm bootstrap requires the official registry ${NPM_REGISTRY}`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (bootstrapVersion !== DEFAULT_BOOTSTRAP_VERSION) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`paper npm bootstrap version is fixed at ${DEFAULT_BOOTSTRAP_VERSION}`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
const configResult = paperConfig(resolvedCwd);
|
|
52
|
+
if (configResult.error) throw new Error(configResult.error);
|
|
53
|
+
const name = normalizePackageName(
|
|
54
|
+
packageName ||
|
|
55
|
+
configResult.loaded.config.publish?.package ||
|
|
56
|
+
configResult.loaded.config.publish?.mainPackage,
|
|
57
|
+
);
|
|
58
|
+
const repo = normalizeRepository(
|
|
59
|
+
repository || resolvePaperRepository(resolvedCwd),
|
|
60
|
+
);
|
|
61
|
+
const provisioning = validatePaperProvisioningAuthority(resolvedCwd);
|
|
62
|
+
if (!provisioning.valid) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`paper npm bootstrap requires a valid provisioning authority: ${provisioning.errors.join("; ")}`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
const expectedPublisher = expectedPaperTrustedPublisher(provisioning.value);
|
|
68
|
+
if (
|
|
69
|
+
provisioning.value.package?.name !== name ||
|
|
70
|
+
expectedPublisher.repository !== repo ||
|
|
71
|
+
expectedPublisher.workflow !== toPosix(workflow).replace(/^\/+/, "") ||
|
|
72
|
+
expectedPublisher.environment !== String(environment || "")
|
|
73
|
+
) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
"paper npm bootstrap coordinates differ from the exact provisioning authority",
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
if (execute && confirmedPackage !== name) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`real npm bootstrap requires --confirm-public-package ${name}`,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
if (execute && offline) {
|
|
84
|
+
throw new Error("real npm bootstrap cannot run with --offline");
|
|
85
|
+
}
|
|
86
|
+
if (execute && (!repo || !workflow)) {
|
|
87
|
+
throw new Error(
|
|
88
|
+
"real npm bootstrap requires GitHub repository and workflow coordinates",
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
const packageObservation = offline
|
|
92
|
+
? {
|
|
93
|
+
status: "unknown",
|
|
94
|
+
exists: null,
|
|
95
|
+
version: "",
|
|
96
|
+
registry,
|
|
97
|
+
errorCode: "offline",
|
|
98
|
+
}
|
|
99
|
+
: liveNpmPackageObservation(name, registry, resolvedCwd);
|
|
100
|
+
const auth = offline
|
|
101
|
+
? {
|
|
102
|
+
status: "unknown",
|
|
103
|
+
authenticated: null,
|
|
104
|
+
identity: "",
|
|
105
|
+
errorCode: "offline",
|
|
106
|
+
}
|
|
107
|
+
: liveNpmAuthObservation(registry, resolvedCwd);
|
|
108
|
+
const plan = {
|
|
109
|
+
schemaVersion: 1,
|
|
110
|
+
contract: PAPER_NPM_BOOTSTRAP_CONTRACT,
|
|
111
|
+
ok: true,
|
|
112
|
+
dryRun: !execute,
|
|
113
|
+
externalMutation: execute,
|
|
114
|
+
package: {
|
|
115
|
+
name,
|
|
116
|
+
bootstrapVersion,
|
|
117
|
+
registry,
|
|
118
|
+
existsBefore: packageObservation.exists,
|
|
119
|
+
observedVersion: packageObservation.version,
|
|
120
|
+
},
|
|
121
|
+
repository: {
|
|
122
|
+
github: repo,
|
|
123
|
+
workflow,
|
|
124
|
+
environment,
|
|
125
|
+
},
|
|
126
|
+
authority: {
|
|
127
|
+
digest: provisioning.value.authorityDigest,
|
|
128
|
+
policyDigest: provisioning.value.policy.policyDigest,
|
|
129
|
+
},
|
|
130
|
+
auth: {
|
|
131
|
+
authenticated: auth.authenticated,
|
|
132
|
+
identity: auth.identity,
|
|
133
|
+
errorCode: auth.errorCode,
|
|
134
|
+
},
|
|
135
|
+
publish: {
|
|
136
|
+
status: packageObservation.exists === true ? "existing" : "planned",
|
|
137
|
+
distTag: "bootstrap",
|
|
138
|
+
access: "public",
|
|
139
|
+
},
|
|
140
|
+
trust: {
|
|
141
|
+
status: "planned",
|
|
142
|
+
urls: [],
|
|
143
|
+
},
|
|
144
|
+
receipts: [],
|
|
145
|
+
nextActions: execute
|
|
146
|
+
? []
|
|
147
|
+
: [
|
|
148
|
+
{
|
|
149
|
+
id: "confirm-public-bootstrap",
|
|
150
|
+
command: `buildchain paper bootstrap npm --execute --confirm-public-package ${name} --json`,
|
|
151
|
+
description:
|
|
152
|
+
"After reviewing this dry-run, bootstrap the exact public package and configure GitHub Trusted Publishing.",
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
};
|
|
156
|
+
if (!execute) {
|
|
157
|
+
const dryRunRoot = fs.mkdtempSync(
|
|
158
|
+
path.join(os.tmpdir(), "buildchain-paper-bootstrap-dry-run-"),
|
|
159
|
+
);
|
|
160
|
+
try {
|
|
161
|
+
fs.writeFileSync(
|
|
162
|
+
path.join(dryRunRoot, "package.json"),
|
|
163
|
+
jsonText(
|
|
164
|
+
bootstrapPackageShape({
|
|
165
|
+
packageName: name,
|
|
166
|
+
version: bootstrapVersion,
|
|
167
|
+
}),
|
|
168
|
+
),
|
|
169
|
+
);
|
|
170
|
+
const configArgs = userconfig ? ["--userconfig", userconfig] : [];
|
|
171
|
+
const pack = commandResult(
|
|
172
|
+
"npm",
|
|
173
|
+
[
|
|
174
|
+
"pack",
|
|
175
|
+
"--dry-run",
|
|
176
|
+
"--json",
|
|
177
|
+
"--ignore-scripts",
|
|
178
|
+
`--registry=${registry}`,
|
|
179
|
+
...configArgs,
|
|
180
|
+
],
|
|
181
|
+
{ cwd: dryRunRoot },
|
|
182
|
+
);
|
|
183
|
+
const publish = commandResult(
|
|
184
|
+
"npm",
|
|
185
|
+
[
|
|
186
|
+
"publish",
|
|
187
|
+
"--dry-run",
|
|
188
|
+
"--ignore-scripts",
|
|
189
|
+
"--access",
|
|
190
|
+
"public",
|
|
191
|
+
"--tag",
|
|
192
|
+
"bootstrap",
|
|
193
|
+
`--registry=${registry}`,
|
|
194
|
+
...configArgs,
|
|
195
|
+
],
|
|
196
|
+
{ cwd: dryRunRoot },
|
|
197
|
+
);
|
|
198
|
+
return {
|
|
199
|
+
...plan,
|
|
200
|
+
ok: pack.ok && publish.ok,
|
|
201
|
+
errorCode: !pack.ok
|
|
202
|
+
? "npm-pack-dry-run-failed"
|
|
203
|
+
: !publish.ok
|
|
204
|
+
? "npm-publish-dry-run-failed"
|
|
205
|
+
: "",
|
|
206
|
+
dryRunChecks: {
|
|
207
|
+
minimalPackageOnly: true,
|
|
208
|
+
pack: {
|
|
209
|
+
status: pack.ok ? "pass" : "fail",
|
|
210
|
+
entryCount: (() => {
|
|
211
|
+
const parsed = safeParseJson(pack.stdout);
|
|
212
|
+
const value = Array.isArray(parsed) ? parsed[0] : parsed;
|
|
213
|
+
return Array.isArray(value?.files) ? value.files.length : 0;
|
|
214
|
+
})(),
|
|
215
|
+
},
|
|
216
|
+
publish: {
|
|
217
|
+
status: publish.ok ? "pass" : "fail",
|
|
218
|
+
registry,
|
|
219
|
+
access: "public",
|
|
220
|
+
distTag: "bootstrap",
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
};
|
|
224
|
+
} finally {
|
|
225
|
+
fs.rmSync(dryRunRoot, { recursive: true, force: true });
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (packageObservation.exists === null) {
|
|
229
|
+
return {
|
|
230
|
+
...plan,
|
|
231
|
+
ok: false,
|
|
232
|
+
errorCode: "npm-package-status-unknown",
|
|
233
|
+
publish: {
|
|
234
|
+
...plan.publish,
|
|
235
|
+
status: "blocked",
|
|
236
|
+
},
|
|
237
|
+
trust: {
|
|
238
|
+
status: "blocked",
|
|
239
|
+
urls: [],
|
|
240
|
+
},
|
|
241
|
+
nextActions: [
|
|
242
|
+
{
|
|
243
|
+
id: "verify-npm-package",
|
|
244
|
+
command: `npm view ${name} version --json --registry=${registry}`,
|
|
245
|
+
description:
|
|
246
|
+
"Resolve whether the exact public package exists before any publish mutation.",
|
|
247
|
+
},
|
|
248
|
+
],
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
if (auth.authenticated !== true) {
|
|
252
|
+
return {
|
|
253
|
+
...plan,
|
|
254
|
+
ok: false,
|
|
255
|
+
errorCode: "npm-auth-required",
|
|
256
|
+
publish: {
|
|
257
|
+
...plan.publish,
|
|
258
|
+
status: "blocked",
|
|
259
|
+
},
|
|
260
|
+
trust: {
|
|
261
|
+
status: "blocked",
|
|
262
|
+
urls: [],
|
|
263
|
+
},
|
|
264
|
+
nextActions: [
|
|
265
|
+
{
|
|
266
|
+
id: "authenticate-npm",
|
|
267
|
+
command: `npm whoami --registry=${registry}`,
|
|
268
|
+
description:
|
|
269
|
+
"Authenticate npm without sharing token contents, then rerun the exact bootstrap command.",
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
const tempRoot = fs.mkdtempSync(
|
|
275
|
+
path.join(os.tmpdir(), "buildchain-paper-bootstrap-"),
|
|
276
|
+
);
|
|
277
|
+
try {
|
|
278
|
+
fs.writeFileSync(
|
|
279
|
+
path.join(tempRoot, "package.json"),
|
|
280
|
+
jsonText(
|
|
281
|
+
bootstrapPackageShape({ packageName: name, version: bootstrapVersion }),
|
|
282
|
+
),
|
|
283
|
+
);
|
|
284
|
+
const configArgs = userconfig ? ["--userconfig", userconfig] : [];
|
|
285
|
+
const pack = commandResult(
|
|
286
|
+
"npm",
|
|
287
|
+
[
|
|
288
|
+
"pack",
|
|
289
|
+
"--dry-run",
|
|
290
|
+
"--json",
|
|
291
|
+
"--ignore-scripts",
|
|
292
|
+
`--registry=${registry}`,
|
|
293
|
+
...configArgs,
|
|
294
|
+
],
|
|
295
|
+
{ cwd: tempRoot },
|
|
296
|
+
);
|
|
297
|
+
if (!pack.ok) {
|
|
298
|
+
return {
|
|
299
|
+
...plan,
|
|
300
|
+
ok: false,
|
|
301
|
+
errorCode: "npm-pack-dry-run-failed",
|
|
302
|
+
publish: { ...plan.publish, status: "blocked" },
|
|
303
|
+
trust: { status: "blocked", urls: [] },
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
const publishDryRun = commandResult(
|
|
307
|
+
"npm",
|
|
308
|
+
[
|
|
309
|
+
"publish",
|
|
310
|
+
"--dry-run",
|
|
311
|
+
"--ignore-scripts",
|
|
312
|
+
"--access",
|
|
313
|
+
"public",
|
|
314
|
+
"--tag",
|
|
315
|
+
"bootstrap",
|
|
316
|
+
`--registry=${registry}`,
|
|
317
|
+
...configArgs,
|
|
318
|
+
],
|
|
319
|
+
{ cwd: tempRoot },
|
|
320
|
+
);
|
|
321
|
+
if (!publishDryRun.ok) {
|
|
322
|
+
return {
|
|
323
|
+
...plan,
|
|
324
|
+
ok: false,
|
|
325
|
+
errorCode: "npm-publish-dry-run-failed",
|
|
326
|
+
publish: { ...plan.publish, status: "blocked" },
|
|
327
|
+
trust: { status: "blocked", urls: [] },
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
let publishStatus =
|
|
331
|
+
packageObservation.exists === true ? "existing" : "published";
|
|
332
|
+
if (packageObservation.exists !== true) {
|
|
333
|
+
const published = commandResult(
|
|
334
|
+
"npm",
|
|
335
|
+
[
|
|
336
|
+
"publish",
|
|
337
|
+
"--ignore-scripts",
|
|
338
|
+
"--access",
|
|
339
|
+
"public",
|
|
340
|
+
"--tag",
|
|
341
|
+
"bootstrap",
|
|
342
|
+
`--registry=${registry}`,
|
|
343
|
+
...configArgs,
|
|
344
|
+
],
|
|
345
|
+
{ cwd: tempRoot, timeout: 60000 },
|
|
346
|
+
);
|
|
347
|
+
if (!published.ok) {
|
|
348
|
+
const failure = {
|
|
349
|
+
...plan,
|
|
350
|
+
ok: false,
|
|
351
|
+
errorCode: "npm-publish-failed",
|
|
352
|
+
publish: { ...plan.publish, status: "failed" },
|
|
353
|
+
trust: { status: "blocked", urls: [] },
|
|
354
|
+
};
|
|
355
|
+
failure.receipts = [
|
|
356
|
+
writePaperReceipt(resolvedCwd, PAPER_PATHS.npmBootstrap, failure),
|
|
357
|
+
];
|
|
358
|
+
return failure;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
const trustArgs = [
|
|
362
|
+
"trust",
|
|
363
|
+
"github",
|
|
364
|
+
name,
|
|
365
|
+
"--repo",
|
|
366
|
+
repo,
|
|
367
|
+
"--file",
|
|
368
|
+
workflow,
|
|
369
|
+
...(environment ? ["--env", environment] : []),
|
|
370
|
+
"--allow-publish",
|
|
371
|
+
"--yes",
|
|
372
|
+
"--json",
|
|
373
|
+
`--registry=${registry}`,
|
|
374
|
+
...configArgs,
|
|
375
|
+
];
|
|
376
|
+
const trustCommand = commandResult("npm", trustArgs, {
|
|
377
|
+
cwd: resolvedCwd,
|
|
378
|
+
timeout: 60000,
|
|
379
|
+
});
|
|
380
|
+
const parsedTrust = safeParseJson(trustCommand.stdout);
|
|
381
|
+
const urls = [
|
|
382
|
+
...extractUrls(
|
|
383
|
+
parsedTrust || `${trustCommand.stdout}\n${trustCommand.stderr}`,
|
|
384
|
+
),
|
|
385
|
+
];
|
|
386
|
+
const trustList =
|
|
387
|
+
trustCommand.ok && urls.length === 0
|
|
388
|
+
? liveNpmTrustObservation(
|
|
389
|
+
name,
|
|
390
|
+
registry,
|
|
391
|
+
resolvedCwd,
|
|
392
|
+
expectedPublisher,
|
|
393
|
+
)
|
|
394
|
+
: {
|
|
395
|
+
status: "unknown",
|
|
396
|
+
configured: null,
|
|
397
|
+
publishers: [],
|
|
398
|
+
errorCode:
|
|
399
|
+
urls.length > 0 ? "web-action-required" : "npm-trust-failed",
|
|
400
|
+
};
|
|
401
|
+
const trustStatus =
|
|
402
|
+
trustCommand.ok && trustList.configured === true
|
|
403
|
+
? "configured"
|
|
404
|
+
: urls.length > 0
|
|
405
|
+
? "action-required"
|
|
406
|
+
: "failed";
|
|
407
|
+
const packageAfter = liveNpmPackageObservation(name, registry, resolvedCwd);
|
|
408
|
+
const packageVerified = packageAfter.exists === true;
|
|
409
|
+
const receipt = {
|
|
410
|
+
...plan,
|
|
411
|
+
ok: trustStatus !== "failed" && packageVerified,
|
|
412
|
+
dryRun: false,
|
|
413
|
+
externalMutation: true,
|
|
414
|
+
errorCode:
|
|
415
|
+
trustStatus === "failed"
|
|
416
|
+
? "npm-trust-failed"
|
|
417
|
+
: packageVerified
|
|
418
|
+
? ""
|
|
419
|
+
: "npm-package-readback-failed",
|
|
420
|
+
package: {
|
|
421
|
+
...plan.package,
|
|
422
|
+
existsAfter: packageAfter.exists,
|
|
423
|
+
observedVersionAfter: packageAfter.version,
|
|
424
|
+
readbackStatus: packageAfter.status,
|
|
425
|
+
},
|
|
426
|
+
publish: {
|
|
427
|
+
...plan.publish,
|
|
428
|
+
status: publishStatus,
|
|
429
|
+
},
|
|
430
|
+
trust: {
|
|
431
|
+
status: trustStatus,
|
|
432
|
+
urls,
|
|
433
|
+
expectedPublisher,
|
|
434
|
+
exactBinding: trustList.exactBinding === true,
|
|
435
|
+
publishers: trustList.publishers,
|
|
436
|
+
},
|
|
437
|
+
nextActions:
|
|
438
|
+
trustStatus === "configured" && packageVerified
|
|
439
|
+
? [
|
|
440
|
+
{
|
|
441
|
+
id: "paper-preflight",
|
|
442
|
+
command: "buildchain paper preflight --json",
|
|
443
|
+
description:
|
|
444
|
+
"Verify package existence and Trusted Publisher binding from live read-only sources.",
|
|
445
|
+
},
|
|
446
|
+
]
|
|
447
|
+
: trustStatus === "action-required" && packageVerified
|
|
448
|
+
? [
|
|
449
|
+
{
|
|
450
|
+
id: "complete-npm-web-action",
|
|
451
|
+
command: "",
|
|
452
|
+
description:
|
|
453
|
+
"Open the exact npm URL returned below, complete the web step, then rerun preflight.",
|
|
454
|
+
urls,
|
|
455
|
+
},
|
|
456
|
+
]
|
|
457
|
+
: !packageVerified
|
|
458
|
+
? [
|
|
459
|
+
{
|
|
460
|
+
id: "verify-npm-package-readback",
|
|
461
|
+
command: `npm view ${name} version --json --registry=${registry}`,
|
|
462
|
+
description:
|
|
463
|
+
"The mutation returned but the official registry did not prove package existence; do not infer success.",
|
|
464
|
+
},
|
|
465
|
+
]
|
|
466
|
+
: [
|
|
467
|
+
{
|
|
468
|
+
id: "retry-npm-trust",
|
|
469
|
+
command: `buildchain paper bootstrap npm --execute --confirm-public-package ${name} --json`,
|
|
470
|
+
description:
|
|
471
|
+
"The package exists; retry only the idempotent Trusted Publisher configuration path.",
|
|
472
|
+
},
|
|
473
|
+
],
|
|
474
|
+
};
|
|
475
|
+
receipt.receipts = [
|
|
476
|
+
writePaperReceipt(resolvedCwd, PAPER_PATHS.npmBootstrap, receipt),
|
|
477
|
+
];
|
|
478
|
+
if (
|
|
479
|
+
packageVerified &&
|
|
480
|
+
(trustStatus === "configured" || trustStatus === "action-required")
|
|
481
|
+
) {
|
|
482
|
+
receipt.receipts.push(
|
|
483
|
+
writePaperReceipt(resolvedCwd, PAPER_PATHS.npmTrust, receipt),
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
return receipt;
|
|
487
|
+
} finally {
|
|
488
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
export { executePaperNpmBootstrap };
|