@gjsify/cli 0.64.24 → 0.64.26-next.312
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/cli.gjs.mjs +43 -43
- package/lib/commands/onboard.d.ts +3 -0
- package/lib/commands/onboard.js +39 -7
- package/lib/commands/trust.js +10 -1
- package/lib/utils/npm-oidc.d.ts +6 -0
- package/lib/utils/npm-oidc.js +7 -0
- package/lib/utils/ship/nested-bundles.js +4 -1
- package/package.json +22 -21
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Command } from '../types/index.js';
|
|
2
|
+
import { type PublishOutcome } from './publish.js';
|
|
2
3
|
interface OnboardOptions {
|
|
3
4
|
repository?: string;
|
|
4
5
|
workflow: string;
|
|
@@ -18,4 +19,6 @@ interface OnboardOptions {
|
|
|
18
19
|
yes?: boolean;
|
|
19
20
|
}
|
|
20
21
|
export declare const onboardCommand: Command<unknown, OnboardOptions>;
|
|
22
|
+
/** Human-readable reason for a failed publish outcome. */
|
|
23
|
+
export declare function describePublishFailure(pub: PublishOutcome): string;
|
|
21
24
|
export {};
|
package/lib/commands/onboard.js
CHANGED
|
@@ -36,6 +36,7 @@ import { DEFAULT_REGISTRY, whoami } from '@gjsify/npm-registry';
|
|
|
36
36
|
import { filterWorkspaces } from '@gjsify/workspace';
|
|
37
37
|
import { hasAnyCredential, loadNpmrc } from '../utils/load-npmrc.js';
|
|
38
38
|
import { OtpProvider } from '../utils/npm-otp.js';
|
|
39
|
+
import { OIDC_VERIFY_IN_CI_HINT } from '../utils/npm-oidc.js';
|
|
39
40
|
import { writeAroundPrompt } from '../utils/prompt-output.js';
|
|
40
41
|
import { publishWorkspace } from './publish.js';
|
|
41
42
|
import { createTrustRequester } from './trust.js';
|
|
@@ -549,6 +550,10 @@ export const onboardCommand = {
|
|
|
549
550
|
log(' Re-run to pick them up — the sweep is idempotent and skips everything already configured. ' +
|
|
550
551
|
`A lower --write-concurrency (currently ${writeConcurrency}) provokes the limit less.`);
|
|
551
552
|
}
|
|
553
|
+
if (!dryRun) {
|
|
554
|
+
log();
|
|
555
|
+
log(OIDC_VERIFY_IN_CI_HINT);
|
|
556
|
+
}
|
|
552
557
|
finish(results, plans, { asJson, dryRun, failed, root, sources, discovered: all.length });
|
|
553
558
|
},
|
|
554
559
|
};
|
|
@@ -663,13 +668,21 @@ async function buildIfPresent(ws, log) {
|
|
|
663
668
|
throw new Error(`build exited with code ${code}`);
|
|
664
669
|
}
|
|
665
670
|
/** Human-readable reason for a failed publish outcome. */
|
|
666
|
-
function describePublishFailure(pub) {
|
|
671
|
+
export function describePublishFailure(pub) {
|
|
672
|
+
if (pub.ok) {
|
|
673
|
+
return `unexpected successful publish outcome: ${pub.action}`;
|
|
674
|
+
}
|
|
667
675
|
switch (pub.action) {
|
|
668
676
|
case 'otp-required':
|
|
669
677
|
return 'npm required a 2FA code (re-run with --otp, or on a TTY)';
|
|
670
|
-
case 'oidc-failed':
|
|
671
|
-
|
|
672
|
-
return
|
|
678
|
+
case 'oidc-failed': {
|
|
679
|
+
const msg = pub.error instanceof Error ? pub.error.message : String(pub.error);
|
|
680
|
+
return `OIDC token exchange failed: ${msg}`;
|
|
681
|
+
}
|
|
682
|
+
case 'oidc-no-token': {
|
|
683
|
+
const msg = pub.error instanceof Error ? pub.error.message : String(pub.error);
|
|
684
|
+
return `OIDC token exchange unavailable and no fallback token: ${msg}`;
|
|
685
|
+
}
|
|
673
686
|
case 'diagnostic':
|
|
674
687
|
return `HTTP 404 (${pub.diag.reason})`;
|
|
675
688
|
case 'publish-unconfirmed':
|
|
@@ -687,9 +700,28 @@ function describePublishFailure(pub) {
|
|
|
687
700
|
return (`not published — ${pub.missing.length} required pin(s) name a package ${pub.registry} does not ` +
|
|
688
701
|
`have: ${pub.missing.map((m) => `${m.block}.${m.name}@${m.spec}`).join(', ')}. Bootstrap the ` +
|
|
689
702
|
`target BEFORE its dependent; that order is a correctness property`);
|
|
703
|
+
case 'held-unpublished-dependency': {
|
|
704
|
+
const reasons = pub.reasons.map((r) => `${r.block}.${r.name}@${r.version} (${r.detail})`).join(', ');
|
|
705
|
+
return (`not published — ${pub.reasons.length} intra-repo pin(s) name a version ${pub.registry} does not serve ` +
|
|
706
|
+
`yet: ${reasons}. The package is held until the dependency is available.`);
|
|
707
|
+
}
|
|
690
708
|
case 'error':
|
|
691
|
-
return `HTTP ${pub.status} ${pub.statusText}`;
|
|
692
|
-
default:
|
|
693
|
-
|
|
709
|
+
return `HTTP ${pub.status} ${pub.statusText}: ${pub.text}`;
|
|
710
|
+
default: {
|
|
711
|
+
// Exhaustiveness check: if this compiles, every PublishOutcome action is handled above.
|
|
712
|
+
const _exhaustive = pub;
|
|
713
|
+
return assertNeverDescribeFailure(_exhaustive);
|
|
714
|
+
}
|
|
694
715
|
}
|
|
695
716
|
}
|
|
717
|
+
/**
|
|
718
|
+
* Fallback renderer for a future PublishOutcome action this switch does not know yet.
|
|
719
|
+
* Kept separate so the `never` assignment above stays the compile-time exhaustiveness check.
|
|
720
|
+
*/
|
|
721
|
+
function assertNeverDescribeFailure(pub) {
|
|
722
|
+
const anyPub = pub;
|
|
723
|
+
const action = typeof anyPub.action === 'string' ? anyPub.action : 'unknown';
|
|
724
|
+
const error = anyPub.error;
|
|
725
|
+
const msg = error instanceof Error ? error.message : error ? String(error) : '';
|
|
726
|
+
return `publish failed: ${action}${msg ? ` — ${msg}` : ''}`;
|
|
727
|
+
}
|
package/lib/commands/trust.js
CHANGED
|
@@ -22,6 +22,7 @@ import { DEFAULT_REGISTRY, buildHeaders, registryFor, whoami } from '@gjsify/npm
|
|
|
22
22
|
import { discoverWorkspaces, filterWorkspaces } from '@gjsify/workspace';
|
|
23
23
|
import { mergePublishables } from '../utils/publishable-packages.js';
|
|
24
24
|
import { hasAnyCredential, loadNpmrc } from '../utils/load-npmrc.js';
|
|
25
|
+
import { OIDC_VERIFY_IN_CI_HINT } from '../utils/npm-oidc.js';
|
|
25
26
|
import { OtpProvider, withOtpRetry } from '../utils/npm-otp.js';
|
|
26
27
|
import { classifyTrustList, githubTrustBody, normalizeWorkflowFile, parseRepoFromGitRemote, trustUrl, validateRepository, } from '../utils/trust-registry.js';
|
|
27
28
|
export const trustCommand = {
|
|
@@ -245,7 +246,15 @@ export const trustCommand = {
|
|
|
245
246
|
console.log('Failed (re-run `gjsify trust` — it is incremental; usually a lapsed 2FA window or rate-limit):');
|
|
246
247
|
for (const f of failures)
|
|
247
248
|
console.log(` ${f}`);
|
|
248
|
-
|
|
249
|
+
if (!dryRun) {
|
|
250
|
+
console.log();
|
|
251
|
+
console.log(OIDC_VERIFY_IN_CI_HINT);
|
|
252
|
+
}
|
|
253
|
+
return process.exit(1);
|
|
254
|
+
}
|
|
255
|
+
if (!dryRun) {
|
|
256
|
+
console.log();
|
|
257
|
+
console.log(OIDC_VERIFY_IN_CI_HINT);
|
|
249
258
|
}
|
|
250
259
|
},
|
|
251
260
|
};
|
package/lib/utils/npm-oidc.d.ts
CHANGED
|
@@ -45,6 +45,12 @@ export declare class OidcExchangeError extends Error {
|
|
|
45
45
|
*/
|
|
46
46
|
claims?: Record<string, unknown> | undefined);
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Post-bootstrap hint printed by `gjsify onboard` and `gjsify trust`.
|
|
50
|
+
* The trust entry can be stored locally, but the OIDC exchange can only be
|
|
51
|
+
* verified inside GitHub Actions where `ACTIONS_ID_TOKEN_REQUEST_URL` exists.
|
|
52
|
+
*/
|
|
53
|
+
export declare const OIDC_VERIFY_IN_CI_HINT: string;
|
|
48
54
|
/**
|
|
49
55
|
* Decode the non-secret payload of a JWT — the middle base64url segment. A GitHub OIDC
|
|
50
56
|
* id-token's payload is public metadata about the workflow run; the SIGNATURE is what makes it
|
package/lib/utils/npm-oidc.js
CHANGED
|
@@ -43,6 +43,13 @@ export class OidcExchangeError extends Error {
|
|
|
43
43
|
this.name = 'OidcExchangeError';
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Post-bootstrap hint printed by `gjsify onboard` and `gjsify trust`.
|
|
48
|
+
* The trust entry can be stored locally, but the OIDC exchange can only be
|
|
49
|
+
* verified inside GitHub Actions where `ACTIONS_ID_TOKEN_REQUEST_URL` exists.
|
|
50
|
+
*/
|
|
51
|
+
export const OIDC_VERIFY_IN_CI_HINT = 'Trust entries are stored but the OIDC exchange is only verifiable in CI: ' +
|
|
52
|
+
'run `gh workflow run release.yml --ref main -f verify_only=true -f skip_publish=true` and check for ✗ lines.';
|
|
46
53
|
/**
|
|
47
54
|
* Decode the non-secret payload of a JWT — the middle base64url segment. A GitHub OIDC
|
|
48
55
|
* id-token's payload is public metadata about the workflow run; the SIGNATURE is what makes it
|
|
@@ -45,7 +45,10 @@ export function stageSubordinates(input) {
|
|
|
45
45
|
const abs = join(bundle.source, ...rel.split(posix.sep));
|
|
46
46
|
files.push({
|
|
47
47
|
path: posix.join(bundleRoot, rel),
|
|
48
|
-
|
|
48
|
+
// A bundle's own executable is executable whatever the source's mode
|
|
49
|
+
// says: NTFS carries no POSIX bits, so `stagedMode` reads 0o644 there
|
|
50
|
+
// and a darwin stage assembled on win32 would ship a dead `.appex`.
|
|
51
|
+
mode: /^Contents\/MacOS\/[^/]+$/.test(rel) ? 0o755 : stagedMode(rel, abs),
|
|
49
52
|
source: { kind: 'file', path: abs },
|
|
50
53
|
});
|
|
51
54
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/cli",
|
|
3
|
-
"version": "0.64.
|
|
3
|
+
"version": "0.64.26-next.312",
|
|
4
4
|
"description": "CLI for Gjsify",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -142,22 +142,22 @@
|
|
|
142
142
|
"cli"
|
|
143
143
|
],
|
|
144
144
|
"dependencies": {
|
|
145
|
-
"@gjsify/blueprint": "
|
|
146
|
-
"@gjsify/buffer": "
|
|
147
|
-
"@gjsify/create-app": "
|
|
148
|
-
"@gjsify/node-globals": "
|
|
149
|
-
"@gjsify/node-polyfills": "
|
|
150
|
-
"@gjsify/npm-registry": "
|
|
151
|
-
"@gjsify/resolve-npm": "
|
|
152
|
-
"@gjsify/rolldown-plugin-gjsify": "
|
|
153
|
-
"@gjsify/vite-plugin-blueprint": "
|
|
154
|
-
"@gjsify/rolldown-plugin-pnp": "
|
|
155
|
-
"@gjsify/semver": "
|
|
156
|
-
"@gjsify/tar": "
|
|
157
|
-
"@gjsify/tsc": "
|
|
158
|
-
"@gjsify/utils": "
|
|
159
|
-
"@gjsify/web-polyfills": "
|
|
160
|
-
"@gjsify/workspace": "
|
|
145
|
+
"@gjsify/blueprint": "0.64.26-next.312",
|
|
146
|
+
"@gjsify/buffer": "0.64.26-next.312",
|
|
147
|
+
"@gjsify/create-app": "0.64.26-next.312",
|
|
148
|
+
"@gjsify/node-globals": "0.64.26-next.312",
|
|
149
|
+
"@gjsify/node-polyfills": "0.64.26-next.312",
|
|
150
|
+
"@gjsify/npm-registry": "0.64.26-next.312",
|
|
151
|
+
"@gjsify/resolve-npm": "0.64.26-next.312",
|
|
152
|
+
"@gjsify/rolldown-plugin-gjsify": "0.64.26-next.312",
|
|
153
|
+
"@gjsify/vite-plugin-blueprint": "0.64.26-next.312",
|
|
154
|
+
"@gjsify/rolldown-plugin-pnp": "0.64.26-next.312",
|
|
155
|
+
"@gjsify/semver": "0.64.26-next.312",
|
|
156
|
+
"@gjsify/tar": "0.64.26-next.312",
|
|
157
|
+
"@gjsify/tsc": "0.64.26-next.312",
|
|
158
|
+
"@gjsify/utils": "0.64.26-next.312",
|
|
159
|
+
"@gjsify/web-polyfills": "0.64.26-next.312",
|
|
160
|
+
"@gjsify/workspace": "0.64.26-next.312",
|
|
161
161
|
"acorn": "^8.17.0",
|
|
162
162
|
"cosmiconfig": "^9.0.2",
|
|
163
163
|
"get-tsconfig": "^4.14.0",
|
|
@@ -166,13 +166,13 @@
|
|
|
166
166
|
"yargs": "^18.0.0"
|
|
167
167
|
},
|
|
168
168
|
"devDependencies": {
|
|
169
|
-
"@gjsify/unit": "
|
|
169
|
+
"@gjsify/unit": "0.64.26-next.312",
|
|
170
170
|
"@types/yargs": "^17.0.35",
|
|
171
171
|
"typescript": "^6.0.3"
|
|
172
172
|
},
|
|
173
173
|
"peerDependencies": {
|
|
174
|
-
"@gjsify/oxfmt-native": "
|
|
175
|
-
"@gjsify/rolldown-native": "
|
|
174
|
+
"@gjsify/oxfmt-native": "0.64.26-next.312",
|
|
175
|
+
"@gjsify/rolldown-native": "0.64.26-next.312"
|
|
176
176
|
},
|
|
177
177
|
"peerDependenciesMeta": {
|
|
178
178
|
"@gjsify/oxfmt-native": {
|
|
@@ -191,5 +191,6 @@
|
|
|
191
191
|
"bugs": {
|
|
192
192
|
"url": "https://github.com/gjsify/gjsify/issues"
|
|
193
193
|
},
|
|
194
|
-
"homepage": "https://github.com/gjsify/gjsify/tree/main/packages/infra/cli#readme"
|
|
194
|
+
"homepage": "https://github.com/gjsify/gjsify/tree/main/packages/infra/cli#readme",
|
|
195
|
+
"gitHead": "75fa6155a8f1fa0f7e5d70c43418ae41ecac8c0e"
|
|
195
196
|
}
|