putitoutthere 0.1.43 → 0.1.45

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.
Files changed (82) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/MIGRATIONS.md +632 -0
  3. package/README.md +342 -94
  4. package/action.yml +5 -5
  5. package/dist/action.js +2 -2
  6. package/dist/action.js.map +1 -1
  7. package/dist/cascade.d.ts +1 -1
  8. package/dist/cascade.js +2 -2
  9. package/dist/cli.d.ts +9 -6
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/cli.js +12 -426
  12. package/dist/cli.js.map +1 -1
  13. package/dist/config.d.ts +13 -61
  14. package/dist/config.d.ts.map +1 -1
  15. package/dist/config.js +31 -45
  16. package/dist/config.js.map +1 -1
  17. package/dist/git.js +1 -1
  18. package/dist/git.js.map +1 -1
  19. package/dist/handlers/npm-platform.d.ts.map +1 -1
  20. package/dist/handlers/npm-platform.js +5 -1
  21. package/dist/handlers/npm-platform.js.map +1 -1
  22. package/dist/handlers/pypi.d.ts.map +1 -1
  23. package/dist/handlers/pypi.js +29 -6
  24. package/dist/handlers/pypi.js.map +1 -1
  25. package/dist/plan.d.ts +0 -1
  26. package/dist/plan.d.ts.map +1 -1
  27. package/dist/plan.js +19 -18
  28. package/dist/plan.js.map +1 -1
  29. package/dist/preflight.js +1 -1
  30. package/dist/preflight.js.map +1 -1
  31. package/dist/publish.d.ts +0 -10
  32. package/dist/publish.d.ts.map +1 -1
  33. package/dist/publish.js +6 -52
  34. package/dist/publish.js.map +1 -1
  35. package/dist/types.d.ts +1 -21
  36. package/dist/types.d.ts.map +1 -1
  37. package/dist/types.js.map +1 -1
  38. package/package.json +5 -3
  39. package/dist/auth.d.ts +0 -68
  40. package/dist/auth.d.ts.map +0 -1
  41. package/dist/auth.js +0 -285
  42. package/dist/auth.js.map +0 -1
  43. package/dist/doctor.d.ts +0 -115
  44. package/dist/doctor.d.ts.map +0 -1
  45. package/dist/doctor.js +0 -292
  46. package/dist/doctor.js.map +0 -1
  47. package/dist/init.d.ts +0 -59
  48. package/dist/init.d.ts.map +0 -1
  49. package/dist/init.js +0 -181
  50. package/dist/init.js.map +0 -1
  51. package/dist/keyring.d.ts +0 -35
  52. package/dist/keyring.d.ts.map +0 -1
  53. package/dist/keyring.js +0 -88
  54. package/dist/keyring.js.map +0 -1
  55. package/dist/oidc-policy.d.ts +0 -145
  56. package/dist/oidc-policy.d.ts.map +0 -1
  57. package/dist/oidc-policy.js +0 -383
  58. package/dist/oidc-policy.js.map +0 -1
  59. package/dist/preflight-run.d.ts +0 -47
  60. package/dist/preflight-run.d.ts.map +0 -1
  61. package/dist/preflight-run.js +0 -197
  62. package/dist/preflight-run.js.map +0 -1
  63. package/dist/registries/crates-trust.d.ts +0 -69
  64. package/dist/registries/crates-trust.d.ts.map +0 -1
  65. package/dist/registries/crates-trust.js +0 -95
  66. package/dist/registries/crates-trust.js.map +0 -1
  67. package/dist/release.d.ts +0 -36
  68. package/dist/release.d.ts.map +0 -1
  69. package/dist/release.js +0 -102
  70. package/dist/release.js.map +0 -1
  71. package/dist/templates.d.ts +0 -43
  72. package/dist/templates.d.ts.map +0 -1
  73. package/dist/templates.js +0 -310
  74. package/dist/templates.js.map +0 -1
  75. package/dist/token-scope.d.ts +0 -65
  76. package/dist/token-scope.d.ts.map +0 -1
  77. package/dist/token-scope.js +0 -163
  78. package/dist/token-scope.js.map +0 -1
  79. package/dist/token.d.ts +0 -211
  80. package/dist/token.d.ts.map +0 -1
  81. package/dist/token.js +0 -719
  82. package/dist/token.js.map +0 -1
package/dist/auth.js DELETED
@@ -1,285 +0,0 @@
1
- /**
2
- * `auth login/logout/status` — OAuth Device Flow against the
3
- * `putitoutthere-cli` GitHub App (client ID committed to
4
- * docs/guide/auth.md).
5
- *
6
- * Scope: optional. The rest of the CLI authenticates to registries
7
- * via env vars; this subcommand exists so `token list` (and later
8
- * features) can read repo-secret metadata from GitHub on behalf of
9
- * the user. If `auth login` has never been run, those features
10
- * degrade gracefully — see #98.
11
- *
12
- * Token values are never logged or written to stdout. They flow
13
- * through the `Keyring` abstraction (see `src/keyring.ts`); in logs
14
- * a token is identified by the first 8 hex chars of its SHA-256.
15
- */
16
- import { defaultKeyring } from './keyring.js';
17
- /** Public client ID of the `putitoutthere-cli` GitHub App (#104). */
18
- export const CLIENT_ID = 'Iv23lio0NtN1koa0Rwle';
19
- const GITHUB_DEVICE_URL = 'https://github.com/login/device/code';
20
- const GITHUB_TOKEN_URL = 'https://github.com/login/oauth/access_token';
21
- const GITHUB_API_USER = 'https://api.github.com/user';
22
- const GRANT_DEVICE = 'urn:ietf:params:oauth:grant-type:device_code';
23
- const GRANT_REFRESH = 'refresh_token';
24
- /** Seconds of slack to refresh a token before it actually expires. */
25
- const REFRESH_SKEW_SECONDS = 60;
26
- /** Bumped when GitHub returns `slow_down`. */
27
- const SLOW_DOWN_BUMP_SECONDS = 5;
28
- // ---- login -------------------------------------------------------------
29
- export async function login(opts = {}) {
30
- const clientId = opts.clientId ?? CLIENT_ID;
31
- const fetchFn = opts.fetchFn ?? fetch;
32
- const keyring = opts.keyring ?? defaultKeyring();
33
- const now = opts.now ?? epochSeconds;
34
- const sleep = opts.sleep ?? realSleep;
35
- const onPrompt = opts.onPrompt ?? (() => undefined);
36
- const device = await requestDeviceCode(fetchFn, clientId);
37
- onPrompt({
38
- userCode: device.user_code,
39
- verificationUri: device.verification_uri,
40
- expiresInSeconds: device.expires_in,
41
- });
42
- const tokens = await pollForToken(fetchFn, sleep, clientId, device);
43
- const account = await fetchLogin(fetchFn, tokens.access_token);
44
- const issuedAt = now();
45
- const stored = {
46
- account,
47
- access_token: tokens.access_token,
48
- refresh_token: tokens.refresh_token,
49
- access_token_expires_at: issuedAt + tokens.expires_in,
50
- refresh_token_expires_at: issuedAt + tokens.refresh_token_expires_in,
51
- };
52
- await keyring.set(stored);
53
- return { account, expiresAt: stored.access_token_expires_at };
54
- }
55
- // ---- logout ------------------------------------------------------------
56
- export async function logout(opts = {}) {
57
- const keyring = opts.keyring ?? defaultKeyring();
58
- const existing = await keyring.get();
59
- if (!existing)
60
- return { wiped: false };
61
- await keyring.delete();
62
- return { wiped: true };
63
- }
64
- // ---- status ------------------------------------------------------------
65
- export async function status(opts = {}) {
66
- const fetchFn = opts.fetchFn ?? fetch;
67
- const keyring = opts.keyring ?? defaultKeyring();
68
- const now = opts.now ?? epochSeconds;
69
- const stored = await keyring.get();
70
- if (!stored) {
71
- return {
72
- authenticated: false,
73
- reason: 'not_logged_in',
74
- message: 'Not logged in. Run `putitoutthere auth login`.',
75
- };
76
- }
77
- let working = stored;
78
- const soonExpired = now() >= stored.access_token_expires_at - REFRESH_SKEW_SECONDS;
79
- if (soonExpired) {
80
- const refreshed = await tryRefresh(fetchFn, keyring, working, now);
81
- if (!refreshed) {
82
- return {
83
- authenticated: false,
84
- reason: 'refresh_failed',
85
- message: 'Session expired. Run `putitoutthere auth login`.',
86
- };
87
- }
88
- working = refreshed;
89
- }
90
- const probe = await probeUser(fetchFn, working.access_token);
91
- if (probe.ok) {
92
- return {
93
- authenticated: true,
94
- account: probe.login,
95
- expiresAt: working.access_token_expires_at,
96
- };
97
- }
98
- if (probe.status !== 401) {
99
- // Network or 5xx — don't wipe credentials over a transient blip.
100
- return {
101
- authenticated: false,
102
- reason: 'refresh_failed',
103
- message: `GitHub /user probe failed (${probe.status}).`,
104
- };
105
- }
106
- // 401 with a still-unexpired token => credential actually revoked.
107
- // Try one refresh before giving up, in case the server clock drifted.
108
- const refreshed = await tryRefresh(fetchFn, keyring, working, now);
109
- if (!refreshed) {
110
- return {
111
- authenticated: false,
112
- reason: 'revoked',
113
- message: 'Token rejected by GitHub. Run `putitoutthere auth login`.',
114
- };
115
- }
116
- const reprobe = await probeUser(fetchFn, refreshed.access_token);
117
- if (!reprobe.ok) {
118
- return {
119
- authenticated: false,
120
- reason: 'revoked',
121
- message: 'Token rejected by GitHub. Run `putitoutthere auth login`.',
122
- };
123
- }
124
- return {
125
- authenticated: true,
126
- account: reprobe.login,
127
- expiresAt: refreshed.access_token_expires_at,
128
- };
129
- }
130
- async function requestDeviceCode(fetchFn, clientId) {
131
- const res = await fetchFn(GITHUB_DEVICE_URL, {
132
- method: 'POST',
133
- headers: {
134
- accept: 'application/json',
135
- 'content-type': 'application/x-www-form-urlencoded',
136
- },
137
- body: new URLSearchParams({ client_id: clientId }).toString(),
138
- });
139
- if (!res.ok) {
140
- throw new Error(`device code request failed: HTTP ${res.status}`);
141
- }
142
- const body = await res.json();
143
- /* v8 ignore next 3 -- defensive; GitHub always returns the documented fields on 2xx. */
144
- if (!isDeviceCodeResponse(body)) {
145
- throw new Error('device code response missing expected fields');
146
- }
147
- return body;
148
- }
149
- async function pollForToken(fetchFn, sleep, clientId, device) {
150
- let intervalSec = device.interval;
151
- const deadline = Date.now() + device.expires_in * 1000;
152
- while (Date.now() < deadline) {
153
- await sleep(intervalSec * 1000);
154
- const res = await fetchFn(GITHUB_TOKEN_URL, {
155
- method: 'POST',
156
- headers: {
157
- accept: 'application/json',
158
- 'content-type': 'application/x-www-form-urlencoded',
159
- },
160
- body: new URLSearchParams({
161
- client_id: clientId,
162
- device_code: device.device_code,
163
- grant_type: GRANT_DEVICE,
164
- }).toString(),
165
- });
166
- const body = (await res.json());
167
- if (isTokenResponse(body))
168
- return body;
169
- const error = typeof body.error === 'string' ? body.error : 'unknown_error';
170
- if (error === 'authorization_pending')
171
- continue;
172
- if (error === 'slow_down') {
173
- intervalSec += SLOW_DOWN_BUMP_SECONDS;
174
- continue;
175
- }
176
- if (error === 'access_denied') {
177
- throw new Error('authorization denied by user');
178
- }
179
- if (error === 'expired_token') {
180
- throw new Error('device code expired before approval');
181
- }
182
- /* v8 ignore start -- unknown error codes + wall-clock deadline are both defensive; GitHub's error set is exhaustive and the server's expired_token fires first. */
183
- throw new Error(`device flow error: ${error}`);
184
- }
185
- throw new Error('device code expired before approval');
186
- }
187
- /* v8 ignore stop */
188
- async function tryRefresh(fetchFn, keyring, current, now) {
189
- const res = await fetchFn(GITHUB_TOKEN_URL, {
190
- method: 'POST',
191
- headers: {
192
- accept: 'application/json',
193
- 'content-type': 'application/x-www-form-urlencoded',
194
- },
195
- body: new URLSearchParams({
196
- client_id: CLIENT_ID,
197
- refresh_token: current.refresh_token,
198
- grant_type: GRANT_REFRESH,
199
- }).toString(),
200
- });
201
- if (!res.ok)
202
- return null;
203
- const body = (await res.json());
204
- if (!isTokenResponse(body))
205
- return null;
206
- const issuedAt = now();
207
- const next = {
208
- account: current.account,
209
- access_token: body.access_token,
210
- refresh_token: body.refresh_token,
211
- access_token_expires_at: issuedAt + body.expires_in,
212
- refresh_token_expires_at: issuedAt + body.refresh_token_expires_in,
213
- };
214
- await keyring.set(next);
215
- return next;
216
- }
217
- async function fetchLogin(fetchFn, accessToken) {
218
- const res = await fetchFn(GITHUB_API_USER, {
219
- headers: {
220
- authorization: `Bearer ${accessToken}`,
221
- accept: 'application/vnd.github+json',
222
- 'user-agent': 'putitoutthere',
223
- },
224
- });
225
- /* v8 ignore next 3 -- fetchLogin runs only after a successful token grant; the happy-path is covered. */
226
- if (!res.ok) {
227
- throw new Error(`GitHub /user failed: HTTP ${res.status}`);
228
- }
229
- const body = (await res.json());
230
- /* v8 ignore next 3 -- defensive: GitHub has never shipped /user without a login field. */
231
- if (typeof body.login !== 'string') {
232
- throw new Error('GitHub /user response missing login');
233
- }
234
- return body.login;
235
- }
236
- async function probeUser(fetchFn, accessToken) {
237
- try {
238
- const res = await fetchFn(GITHUB_API_USER, {
239
- headers: {
240
- authorization: `Bearer ${accessToken}`,
241
- accept: 'application/vnd.github+json',
242
- 'user-agent': 'putitoutthere',
243
- },
244
- });
245
- if (!res.ok)
246
- return { ok: false, status: res.status };
247
- const body = (await res.json());
248
- /* v8 ignore next -- defensive: GitHub has never shipped /user without a login field. */
249
- if (typeof body.login !== 'string')
250
- return { ok: false, status: res.status };
251
- return { ok: true, login: body.login };
252
- /* v8 ignore next 3 -- network-throw catch; msw can't model a pre-HTTP throw cleanly. */
253
- }
254
- catch {
255
- return { ok: false, status: 0 };
256
- }
257
- }
258
- // ---- helpers -----------------------------------------------------------
259
- function isDeviceCodeResponse(v) {
260
- if (!v || typeof v !== 'object')
261
- return false;
262
- const o = v;
263
- return (typeof o.device_code === 'string' &&
264
- typeof o.user_code === 'string' &&
265
- typeof o.verification_uri === 'string' &&
266
- typeof o.expires_in === 'number' &&
267
- typeof o.interval === 'number');
268
- }
269
- function isTokenResponse(v) {
270
- if (!v || typeof v !== 'object')
271
- return false;
272
- const o = v;
273
- return (typeof o.access_token === 'string' &&
274
- typeof o.expires_in === 'number' &&
275
- typeof o.refresh_token === 'string' &&
276
- typeof o.refresh_token_expires_in === 'number');
277
- }
278
- function epochSeconds() {
279
- return Math.floor(Date.now() / 1000);
280
- }
281
- /* v8 ignore next 3 -- real timer; every test injects `sleep`. */
282
- function realSleep(ms) {
283
- return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
284
- }
285
- //# sourceMappingURL=auth.js.map
package/dist/auth.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
package/dist/doctor.d.ts DELETED
@@ -1,115 +0,0 @@
1
- /**
2
- * `putitoutthere doctor` — pre-flight validator.
3
- *
4
- * Validates: config parses; every package has a resolvable kind; every
5
- * package has usable credentials (OIDC or per-kind token). Returns a
6
- * structured report rather than throwing so the CLI can render it as
7
- * a table.
8
- *
9
- * When `checkArtifacts` is on, also walks the plan and checks each
10
- * expected artifact directory. Silent-skips when plan can't run (no
11
- * git state / no commits) so `doctor` stays useful in contexts that
12
- * don't have a release history yet.
13
- *
14
- * Issue #23. Plan: §21.1, §16.4.7. Artifact check: #89.
15
- */
16
- import { type WorkflowFile } from './oidc-policy.js';
17
- import { fetchCratesTrustPolicy, type CratesTrustMismatch } from './registries/crates-trust.js';
18
- import { type AuthResult } from './preflight.js';
19
- import { type DeepCheckRow, type InspectFn } from './token-scope.js';
20
- export interface DoctorOptions {
21
- cwd: string;
22
- configPath?: string;
23
- /** When true, walks the plan and checks each artifact dir exists. */
24
- checkArtifacts?: boolean;
25
- /**
26
- * When true, resolve each package's token and run a live `inspect`
27
- * to cross-check publish scope against the config. Slower (hits the
28
- * registries); off by default. See #110.
29
- */
30
- deep?: boolean;
31
- /** Override for tests; defaults to the real `inspect`. */
32
- inspectFn?: InspectFn;
33
- /**
34
- * Override for tests of the crates.io trust-policy cross-check.
35
- * Defaults to the real `fetchCratesTrustPolicy`. Accepting `null`
36
- * here means "use the default".
37
- */
38
- cratesIoFetch?: typeof fetchCratesTrustPolicy;
39
- }
40
- export interface DoctorReport {
41
- ok: boolean;
42
- issues: string[];
43
- packages: Array<{
44
- name: string;
45
- kind: string;
46
- auth: AuthResult['via'];
47
- /** Populated when `deep: true`. */
48
- scope?: string;
49
- scope_match?: DeepCheckRow['match'];
50
- }>;
51
- artifacts?: Array<{
52
- package: string;
53
- target: string;
54
- artifact_name: string;
55
- present: boolean;
56
- expected: string;
57
- }>;
58
- /**
59
- * Trust-policy (local) check results. See `checkTrustPolicyLocal`.
60
- * `undefined` when no publish workflow was found (e.g. a bare repo
61
- * with no `.github/workflows/` yet — no signal, no noise).
62
- */
63
- trustPolicy?: TrustPolicyReport;
64
- /**
65
- * Trust-policy (declared) check results. See #189. `undefined` when
66
- * no package has a `[package.trust_policy]` block.
67
- */
68
- trustPolicyDeclared?: TrustPolicyDeclaredReport;
69
- /**
70
- * Trust-policy (crates.io) cross-check. `undefined` when the phase
71
- * didn't run (e.g. no `CRATES_IO_DOCTOR_TOKEN`, or no crates with
72
- * `trust_policy` declared).
73
- */
74
- trustPolicyCratesIo?: TrustPolicyCratesIoReport;
75
- }
76
- export interface TrustPolicyReport {
77
- workflows: Array<{
78
- filename: string;
79
- permissions_ok: boolean;
80
- environment_ok: boolean;
81
- invocation_ok: boolean;
82
- issues: string[];
83
- }>;
84
- }
85
- export interface TrustPolicyDeclaredReport {
86
- /** One entry per package with a `[package.trust_policy]` block. */
87
- packages: Array<{
88
- name: string;
89
- workflow_ok: boolean;
90
- environment_ok: boolean;
91
- ref_ok: boolean;
92
- issues: string[];
93
- }>;
94
- }
95
- export interface TrustPolicyCratesIoReport {
96
- /** `'skipped'` when the token was missing; other values are per-crate statuses. */
97
- status: 'ran' | 'skipped';
98
- reason?: string;
99
- crates: Array<{
100
- name: string;
101
- status: 'ok' | 'mismatch' | 'skip-transient' | 'auth-failed';
102
- reason?: string;
103
- mismatches?: CratesTrustMismatch[];
104
- }>;
105
- }
106
- export declare function doctor(opts: DoctorOptions): Promise<DoctorReport>;
107
- /**
108
- * Exported for CLI rendering: the explicit "what's NOT checked" line
109
- * we surface below the trust-policy phase so a green doctor output
110
- * doesn't imply the filename landmine is caught.
111
- */
112
- export declare const TRUST_POLICY_SCOPE_NOTE = "note: declare `[package.trust_policy]` to have `doctor` diff workflow + environment against the config. Registry cross-check is crates.io-only (set `CRATES_IO_DOCTOR_TOKEN`); PyPI and npm are declaration-only.";
113
- /** Re-exported for callers that want to construct a `TrustPolicyReport` or inspect workflows directly. */
114
- export type { WorkflowFile };
115
- //# sourceMappingURL=doctor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}