@kubb/cli 5.3.16 → 5.3.18
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/{connect-IObjkkpy.js → connect-BP2OiMvo.js} +2 -2
- package/dist/{connect-IObjkkpy.js.map → connect-BP2OiMvo.js.map} +1 -1
- package/dist/{connect-CYlbWNUk.cjs → connect-CHiwWuCI.cjs} +2 -2
- package/dist/{connect-CYlbWNUk.cjs.map → connect-CHiwWuCI.cjs.map} +1 -1
- package/dist/{generate-RIE_QgE_.js → generate-C5NsehkJ.js} +2 -2
- package/dist/{generate-RIE_QgE_.js.map → generate-C5NsehkJ.js.map} +1 -1
- package/dist/{generate-By-otZHV.cjs → generate-CEMZP96A.cjs} +2 -2
- package/dist/{generate-By-otZHV.cjs.map → generate-CEMZP96A.cjs.map} +1 -1
- package/dist/index.cjs +7 -7
- package/dist/index.js +7 -7
- package/dist/{init-m87O7gWD.cjs → init-DMmtgniM.cjs} +2 -2
- package/dist/{init-m87O7gWD.cjs.map → init-DMmtgniM.cjs.map} +1 -1
- package/dist/{init-BTOW_efj.js → init-iw1ENf8f.js} +2 -2
- package/dist/{init-BTOW_efj.js.map → init-iw1ENf8f.js.map} +1 -1
- package/dist/{login-CA_xoFp7.js → login-AEDO32Tf.js} +2 -2
- package/dist/{login-CA_xoFp7.js.map → login-AEDO32Tf.js.map} +1 -1
- package/dist/{login-XpaX0zmW.cjs → login-CihXN93N.cjs} +2 -2
- package/dist/{login-XpaX0zmW.cjs.map → login-CihXN93N.cjs.map} +1 -1
- package/dist/{logout-BRZyHSgy.js → logout-Bw7zyqib.js} +2 -2
- package/dist/{logout-BRZyHSgy.js.map → logout-Bw7zyqib.js.map} +1 -1
- package/dist/{logout-CzsW6zdv.cjs → logout-rW7YPfoH.cjs} +2 -2
- package/dist/{logout-CzsW6zdv.cjs.map → logout-rW7YPfoH.cjs.map} +1 -1
- package/dist/{package-DvqvX4iy.cjs → package-CoU9wEFX.cjs} +2 -2
- package/dist/package-CoU9wEFX.cjs.map +1 -0
- package/dist/package-DV3bDcX_.js +6 -0
- package/dist/package-DV3bDcX_.js.map +1 -0
- package/dist/{run-BZr3INfK.js → run-4mmYto0l.js} +2 -2
- package/dist/{run-BZr3INfK.js.map → run-4mmYto0l.js.map} +1 -1
- package/dist/{run-DQGHRxvY.cjs → run-BT56dyNK.cjs} +2 -2
- package/dist/{run-DQGHRxvY.cjs.map → run-BT56dyNK.cjs.map} +1 -1
- package/dist/{run-BkpO4HyT.cjs → run-C-vNyjI_.cjs} +2 -2
- package/dist/{run-BkpO4HyT.cjs.map → run-C-vNyjI_.cjs.map} +1 -1
- package/dist/{run-DOOtoHGQ.js → run-D6QwS31H.js} +2 -2
- package/dist/run-D6QwS31H.js.map +1 -0
- package/dist/{run-DjMd8cvr.cjs → run-DZ-WUiiL.cjs} +2 -2
- package/dist/{run-DjMd8cvr.cjs.map → run-DZ-WUiiL.cjs.map} +1 -1
- package/dist/{run-DY-3ONFZ.cjs → run-Dp24WE9v.cjs} +2 -2
- package/dist/run-Dp24WE9v.cjs.map +1 -0
- package/dist/{run-jbHIvdOg.js → run-lQMyViFx.js} +2 -2
- package/dist/{run-jbHIvdOg.js.map → run-lQMyViFx.js.map} +1 -1
- package/dist/{run-Dy5NxCMm.js → run-v1KW3dcE.js} +2 -2
- package/dist/{run-Dy5NxCMm.js.map → run-v1KW3dcE.js.map} +1 -1
- package/dist/{snapshot-DJzr_LP8.cjs → snapshot-CixnEgJe.cjs} +71 -26
- package/dist/snapshot-CixnEgJe.cjs.map +1 -0
- package/dist/{snapshot-Cv2GHK1Y.js → snapshot-aiwOrbuI.js} +71 -26
- package/dist/snapshot-aiwOrbuI.js.map +1 -0
- package/dist/{status-BtXF2YAC.cjs → status-CYhqs_P9.cjs} +2 -2
- package/dist/{status-BtXF2YAC.cjs.map → status-CYhqs_P9.cjs.map} +1 -1
- package/dist/{status-DT1nKRUb.js → status-CkKR5TPs.js} +2 -2
- package/dist/{status-DT1nKRUb.js.map → status-CkKR5TPs.js.map} +1 -1
- package/dist/{studio-CwZBPZWN.js → studio-C2ex3VFM.js} +12 -7
- package/dist/studio-C2ex3VFM.js.map +1 -0
- package/dist/{studio-DDDkhrVO.cjs → studio-CVNxoOi0.cjs} +12 -7
- package/dist/studio-CVNxoOi0.cjs.map +1 -0
- package/package.json +7 -7
- package/dist/package-DjDsh9cp.js +0 -6
- package/dist/package-DjDsh9cp.js.map +0 -1
- package/dist/package-DvqvX4iy.cjs.map +0 -1
- package/dist/run-DOOtoHGQ.js.map +0 -1
- package/dist/run-DY-3ONFZ.cjs.map +0 -1
- package/dist/snapshot-Cv2GHK1Y.js.map +0 -1
- package/dist/snapshot-DJzr_LP8.cjs.map +0 -1
- package/dist/studio-CwZBPZWN.js.map +0 -1
- package/dist/studio-DDDkhrVO.cjs.map +0 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-qbf5tadS.cjs");
|
|
2
|
-
const require_run = require("./run-
|
|
2
|
+
const require_run = require("./run-Dp24WE9v.cjs");
|
|
3
3
|
const require_utils = require("./utils-DqUNntyL.cjs");
|
|
4
4
|
const require_output = require("./output-D-9bGS7y.cjs");
|
|
5
5
|
let node_util = require("node:util");
|
|
6
|
+
let node_crypto = require("node:crypto");
|
|
6
7
|
let node_process = require("node:process");
|
|
7
8
|
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
8
9
|
let node_path = require("node:path");
|
|
@@ -10,15 +11,19 @@ let node_fs = require("node:fs");
|
|
|
10
11
|
let _kubb_core = require("@kubb/core");
|
|
11
12
|
let _kubb_studio = require("@kubb/studio");
|
|
12
13
|
//#region src/runners/studio/ci.ts
|
|
13
|
-
function
|
|
14
|
+
function readGithubPullRequest(eventPath) {
|
|
14
15
|
if (!eventPath) return;
|
|
15
16
|
try {
|
|
16
17
|
const event = JSON.parse((0, node_fs.readFileSync)(eventPath, "utf8"));
|
|
17
|
-
return event.pull_request?.number ?
|
|
18
|
+
return event.pull_request?.number ? event.pull_request : void 0;
|
|
18
19
|
} catch {
|
|
19
20
|
return;
|
|
20
21
|
}
|
|
21
22
|
}
|
|
23
|
+
/** Reproduces GitLab's `CI_COMMIT_REF_SLUG` for a branch it gives no slug of, like a merge request's target. */
|
|
24
|
+
function gitlabRefSlug(ref) {
|
|
25
|
+
return ref.toLowerCase().replace(/[^a-z0-9]/gu, "-").slice(0, 63).replace(/^-+|-+$/g, "");
|
|
26
|
+
}
|
|
22
27
|
/**
|
|
23
28
|
* Detects the CI provider from its environment variables and derives a stable identity from it.
|
|
24
29
|
* The GitHub row reproduces `gh:<repositoryId>:<prNumber>`, the identity `kubb-labs/action` has
|
|
@@ -26,21 +31,32 @@ function readGithubPullRequestNumber(eventPath) {
|
|
|
26
31
|
*/
|
|
27
32
|
function detectCi(env = node_process.default.env) {
|
|
28
33
|
if (env.GITHUB_ACTIONS) {
|
|
29
|
-
const
|
|
34
|
+
const pullRequest = readGithubPullRequest(env.GITHUB_EVENT_PATH);
|
|
30
35
|
const repositoryId = env.GITHUB_REPOSITORY_ID ?? env.GITHUB_REPOSITORY ?? "";
|
|
31
|
-
const
|
|
36
|
+
const branch = env.GITHUB_REF?.startsWith("refs/heads/") ? env.GITHUB_REF.slice(11) : void 0;
|
|
37
|
+
const scope = pullRequest?.number ?? (branch ? `refs/heads/${branch}` : env.GITHUB_RUN_ID) ?? "";
|
|
38
|
+
const baseBranch = pullRequest?.base?.ref;
|
|
32
39
|
return {
|
|
33
40
|
id: `gh:${repositoryId}:${scope}`,
|
|
34
|
-
name: `${env.GITHUB_REPOSITORY ?? "github"}#${scope}`,
|
|
35
|
-
commit: env.GITHUB_SHA
|
|
41
|
+
name: `${env.GITHUB_REPOSITORY ?? "github"}#${pullRequest?.number ?? branch ?? scope}`,
|
|
42
|
+
commit: pullRequest?.head?.sha ?? env.GITHUB_SHA,
|
|
43
|
+
base: baseBranch ? {
|
|
44
|
+
branch: baseBranch,
|
|
45
|
+
id: `gh:${repositoryId}:refs/heads/${baseBranch}`
|
|
46
|
+
} : void 0
|
|
36
47
|
};
|
|
37
48
|
}
|
|
38
49
|
if (env.GITLAB_CI) {
|
|
39
50
|
const scope = env.CI_MERGE_REQUEST_IID ?? env.CI_COMMIT_REF_SLUG ?? "";
|
|
51
|
+
const baseBranch = env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME;
|
|
40
52
|
return {
|
|
41
53
|
id: `gl:${env.CI_PROJECT_ID ?? ""}:${scope}`,
|
|
42
54
|
name: `${env.CI_PROJECT_PATH ?? "gitlab"}#${scope}`,
|
|
43
|
-
commit: env.CI_COMMIT_SHA
|
|
55
|
+
commit: env.CI_MERGE_REQUEST_SOURCE_BRANCH_SHA || env.CI_COMMIT_SHA,
|
|
56
|
+
base: baseBranch ? {
|
|
57
|
+
branch: baseBranch,
|
|
58
|
+
id: `gl:${env.CI_PROJECT_ID ?? ""}:${gitlabRefSlug(baseBranch)}`
|
|
59
|
+
} : void 0
|
|
44
60
|
};
|
|
45
61
|
}
|
|
46
62
|
if (env.BITBUCKET_BUILD_NUMBER) {
|
|
@@ -115,13 +131,20 @@ function resolveToken(options) {
|
|
|
115
131
|
}
|
|
116
132
|
function resolveCiIdentity(options) {
|
|
117
133
|
const detected = detectCi();
|
|
118
|
-
|
|
134
|
+
const ci = options.id ? {
|
|
119
135
|
id: options.id,
|
|
120
136
|
name: detected?.name ?? options.id,
|
|
121
137
|
commit: detected?.commit
|
|
138
|
+
} : detected;
|
|
139
|
+
if (!ci) throw new Error("Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id.");
|
|
140
|
+
const base = options.baseId ? {
|
|
141
|
+
branch: options.baseId,
|
|
142
|
+
id: options.baseId
|
|
143
|
+
} : ci.base;
|
|
144
|
+
return {
|
|
145
|
+
...ci,
|
|
146
|
+
base: base?.id === ci.id ? void 0 : base
|
|
122
147
|
};
|
|
123
|
-
if (!detected) throw new Error("Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id.");
|
|
124
|
-
return detected;
|
|
125
148
|
}
|
|
126
149
|
/** Rejects a bad `--timeout` up front instead of letting it reach `waitForJob` as NaN or <= 0. */
|
|
127
150
|
function resolveTimeoutMs(options) {
|
|
@@ -137,7 +160,7 @@ function assertSecureStudioUrl(studioUrl) {
|
|
|
137
160
|
function absoluteUrl(studioUrl, path) {
|
|
138
161
|
return new URL(path, `${studioUrl}/`).toString();
|
|
139
162
|
}
|
|
140
|
-
function toResult(studioUrl, snapshot, agentSlug) {
|
|
163
|
+
function toResult(studioUrl, snapshot, agentSlug, ci) {
|
|
141
164
|
return {
|
|
142
165
|
id: snapshot.id,
|
|
143
166
|
name: snapshot.name,
|
|
@@ -147,25 +170,33 @@ function toResult(studioUrl, snapshot, agentSlug) {
|
|
|
147
170
|
snapshotIdUrl: absoluteUrl(studioUrl, snapshot.snapshotIdUrl),
|
|
148
171
|
expiresAt: snapshot.expiresAt,
|
|
149
172
|
agentUrl: absoluteUrl(studioUrl, `/agents/${agentSlug}`),
|
|
150
|
-
changes: snapshot.changes
|
|
173
|
+
changes: snapshot.changes,
|
|
174
|
+
branchChanges: snapshot.branchChanges && ci.base ? {
|
|
175
|
+
...snapshot.branchChanges,
|
|
176
|
+
branch: ci.base.branch
|
|
177
|
+
} : void 0
|
|
151
178
|
};
|
|
152
179
|
}
|
|
180
|
+
/** How many files differ, `against` what. */
|
|
181
|
+
function describeChanges(changes, against) {
|
|
182
|
+
const { added, changed, removed } = changes;
|
|
183
|
+
return added.length + changed.length + removed.length ? `${added.length} added, ${changed.length} changed, ${removed.length} removed ${against}` : `No changes ${against}`;
|
|
184
|
+
}
|
|
153
185
|
/** One summary line: how many files changed, and since which run. */
|
|
154
186
|
function formatChanges(changes) {
|
|
155
187
|
if (!changes.base) return "First snapshot";
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const since = changes.base.commit ? changes.base.commit.slice(0, 7) : changes.base.createdAt;
|
|
162
|
-
return changes.added.length + changes.changed.length + changes.removed.length ? `${counts} since ${since}` : `No changes since ${since}`;
|
|
188
|
+
return describeChanges(changes, `since ${changes.base.commit?.slice(0, 7) ?? changes.base.createdAt}`);
|
|
189
|
+
}
|
|
190
|
+
/** One summary line: how the snapshot differs from the base branch's latest one. */
|
|
191
|
+
function formatBranchChanges(changes) {
|
|
192
|
+
return changes.base ? describeChanges(changes, `against ${changes.branch}`) : `No snapshot of ${changes.branch} to compare with`;
|
|
163
193
|
}
|
|
164
194
|
function printSummary(result) {
|
|
165
195
|
require_output.logBlock([
|
|
166
196
|
`${(0, node_util.styleText)("dim", "Package".padEnd(10))} ${result.name ?? "(unnamed)"}@${result.version ?? "0.0.0"}`,
|
|
167
197
|
`${(0, node_util.styleText)("dim", "Tarball".padEnd(10))} ${(0, node_util.styleText)("cyan", result.url)}`,
|
|
168
198
|
`${(0, node_util.styleText)("dim", "Agent".padEnd(10))} ${result.agentUrl}`,
|
|
199
|
+
...result.branchChanges ? [`${(0, node_util.styleText)("dim", "Branch".padEnd(10))} ${formatBranchChanges(result.branchChanges)}`] : [],
|
|
169
200
|
...result.changes ? [`${(0, node_util.styleText)("dim", "Changes".padEnd(10))} ${formatChanges(result.changes)}`] : [],
|
|
170
201
|
`${(0, node_util.styleText)("dim", "Expires".padEnd(10))} ${result.expiresAt}`
|
|
171
202
|
]);
|
|
@@ -196,13 +227,15 @@ async function snapshot(options) {
|
|
|
196
227
|
name: ci.name,
|
|
197
228
|
machineToken: (0, _kubb_studio.machineTokenFrom)(ci.id)
|
|
198
229
|
});
|
|
230
|
+
const instanceId = (0, node_crypto.randomUUID)();
|
|
199
231
|
const { promise: ready, resolve: markReady } = Promise.withResolvers();
|
|
200
232
|
const shutdown = new AbortController();
|
|
201
|
-
const
|
|
233
|
+
const connection = (0, _kubb_studio.runConnection)({
|
|
202
234
|
credentials: { token: agent.token },
|
|
203
235
|
signal: shutdown.signal,
|
|
204
236
|
clientOptions: () => ({
|
|
205
237
|
studioUrl: options.studioUrl,
|
|
238
|
+
instanceId,
|
|
206
239
|
configPath,
|
|
207
240
|
root: node_process.default.cwd(),
|
|
208
241
|
version: options.version,
|
|
@@ -218,7 +251,11 @@ async function snapshot(options) {
|
|
|
218
251
|
}
|
|
219
252
|
}),
|
|
220
253
|
onTokenRejected: ({ error }) => Promise.reject(error)
|
|
221
|
-
})
|
|
254
|
+
});
|
|
255
|
+
const connectionLost = new AbortController();
|
|
256
|
+
const connectionEnded = /* @__PURE__ */ new Error("The Kubb Studio connection ended before the snapshot finished");
|
|
257
|
+
connection.then(() => connectionLost.abort(connectionEnded), (error) => connectionLost.abort(error));
|
|
258
|
+
const lost = connection.then(() => Promise.reject(connectionEnded), (error) => Promise.reject(error));
|
|
222
259
|
lost.catch(() => {});
|
|
223
260
|
try {
|
|
224
261
|
let readyTimeout;
|
|
@@ -234,25 +271,32 @@ async function snapshot(options) {
|
|
|
234
271
|
clearTimeout(readyTimeout);
|
|
235
272
|
}
|
|
236
273
|
step("Creating snapshot job");
|
|
274
|
+
const snapshotDeadline = Date.now() + timeoutMs;
|
|
275
|
+
const snapshotTimeoutMs = () => Math.max(snapshotDeadline - Date.now(), 1);
|
|
237
276
|
const job = await (0, _kubb_studio.createJob)({
|
|
238
277
|
studioUrl: options.studioUrl,
|
|
239
278
|
token,
|
|
240
279
|
type: "snapshot",
|
|
241
280
|
agentId: agent.id,
|
|
281
|
+
instanceId,
|
|
242
282
|
name,
|
|
243
283
|
version: packageVersion,
|
|
244
|
-
commit: ci.commit
|
|
284
|
+
commit: ci.commit,
|
|
285
|
+
baseId: ci.base?.id,
|
|
286
|
+
timeoutMs: snapshotTimeoutMs(),
|
|
287
|
+
signal: connectionLost.signal
|
|
245
288
|
});
|
|
246
289
|
step(`Snapshot job queued: ${job.id}`);
|
|
247
290
|
const finished = await Promise.race([(0, _kubb_studio.waitForJob)({
|
|
248
291
|
studioUrl: options.studioUrl,
|
|
249
292
|
token,
|
|
250
293
|
id: job.id,
|
|
251
|
-
timeoutMs
|
|
294
|
+
timeoutMs: snapshotTimeoutMs(),
|
|
295
|
+
signal: connectionLost.signal
|
|
252
296
|
}), lost]);
|
|
253
297
|
if (finished.status === "failed") throw new Error(finished.error ?? "Snapshot job failed");
|
|
254
298
|
if (!finished.snapshot) throw new Error("Snapshot job succeeded without a snapshot");
|
|
255
|
-
const result = toResult(options.studioUrl, finished.snapshot, agent.slug);
|
|
299
|
+
const result = toResult(options.studioUrl, finished.snapshot, agent.slug, ci);
|
|
256
300
|
step("Snapshot published");
|
|
257
301
|
if (options.json) console.log(JSON.stringify(result));
|
|
258
302
|
if (!options.json) printSummary(result);
|
|
@@ -269,6 +313,7 @@ const runner = async ({ values }) => {
|
|
|
269
313
|
...require_run.createStudioOptions(values),
|
|
270
314
|
token: values.token,
|
|
271
315
|
id: values.id,
|
|
316
|
+
baseId: values.baseId,
|
|
272
317
|
name: values.name,
|
|
273
318
|
packageVersion: values.packageVersion,
|
|
274
319
|
timeout: values.timeout,
|
|
@@ -279,4 +324,4 @@ const runner = async ({ values }) => {
|
|
|
279
324
|
//#endregion
|
|
280
325
|
exports.runner = runner;
|
|
281
326
|
|
|
282
|
-
//# sourceMappingURL=snapshot-
|
|
327
|
+
//# sourceMappingURL=snapshot-CixnEgJe.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-CixnEgJe.cjs","names":["readFileSync","process","join","exists","read","dirname","process","styleText","loadConfigs","logLevelMap","createPlainLogger","createAgent","machineTokenFrom","randomUUID","runConnection","setupReporters","cliReporter","createJob","waitForJob","createStudioOptions","run"],"sources":["../src/runners/studio/ci.ts","../src/runners/studio/snapshot.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport process from 'node:process'\n\n/**\n * Stable identity for the CI agent a snapshot run registers or reuses.\n */\nexport type CiContext = {\n /**\n * Fed into the machine token, so the same merge or pull request reuses one agent.\n */\n id: string\n /**\n * Agent display name shown in Studio.\n */\n name: string\n /** The commit this run builds, so the next snapshot can diff against it. */\n commit?: string\n /** The branch a pull request merges into, and the `id` runs on that branch register under. */\n base?: { branch: string; id: string }\n}\n\ntype GithubPullRequest = { number: number; head?: { sha?: string }; base?: { ref?: string } }\n\nfunction readGithubPullRequest(eventPath: string | undefined): GithubPullRequest | undefined {\n if (!eventPath) {\n return undefined\n }\n\n try {\n const event = JSON.parse(readFileSync(eventPath, 'utf8')) as { pull_request?: GithubPullRequest }\n return event.pull_request?.number ? event.pull_request : undefined\n } catch {\n return undefined\n }\n}\n\n/** Reproduces GitLab's `CI_COMMIT_REF_SLUG` for a branch it gives no slug of, like a merge request's target. */\nexport function gitlabRefSlug(ref: string): string {\n return ref\n .toLowerCase()\n .replace(/[^a-z0-9]/gu, '-')\n .slice(0, 63)\n .replace(/^-+|-+$/g, '')\n}\n\n/**\n * Detects the CI provider from its environment variables and derives a stable identity from it.\n * The GitHub row reproduces `gh:<repositoryId>:<prNumber>`, the identity `kubb-labs/action` has\n * always registered agents under, so an existing repository keeps reusing its agent.\n */\nexport function detectCi(env: Record<string, string | undefined> = process.env): CiContext | null {\n if (env.GITHUB_ACTIONS) {\n const pullRequest = readGithubPullRequest(env.GITHUB_EVENT_PATH)\n const repositoryId = env.GITHUB_REPOSITORY_ID ?? env.GITHUB_REPOSITORY ?? ''\n const branch = env.GITHUB_REF?.startsWith('refs/heads/') ? env.GITHUB_REF.slice('refs/heads/'.length) : undefined\n // A branch run is scoped by its ref, which a pull request number never collides with.\n const scope = pullRequest?.number ?? (branch ? `refs/heads/${branch}` : env.GITHUB_RUN_ID) ?? ''\n const baseBranch = pullRequest?.base?.ref\n\n return {\n id: `gh:${repositoryId}:${scope}`,\n name: `${env.GITHUB_REPOSITORY ?? 'github'}#${pullRequest?.number ?? branch ?? scope}`,\n // The head commit, not the merge commit a pull request run checks out.\n commit: pullRequest?.head?.sha ?? env.GITHUB_SHA,\n base: baseBranch ? { branch: baseBranch, id: `gh:${repositoryId}:refs/heads/${baseBranch}` } : undefined,\n }\n }\n\n if (env.GITLAB_CI) {\n const scope = env.CI_MERGE_REQUEST_IID ?? env.CI_COMMIT_REF_SLUG ?? ''\n const baseBranch = env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME\n\n return {\n id: `gl:${env.CI_PROJECT_ID ?? ''}:${scope}`,\n name: `${env.CI_PROJECT_PATH ?? 'gitlab'}#${scope}`,\n commit: env.CI_MERGE_REQUEST_SOURCE_BRANCH_SHA || env.CI_COMMIT_SHA,\n base: baseBranch ? { branch: baseBranch, id: `gl:${env.CI_PROJECT_ID ?? ''}:${gitlabRefSlug(baseBranch)}` } : undefined,\n }\n }\n\n if (env.BITBUCKET_BUILD_NUMBER) {\n const scope = env.BITBUCKET_PR_ID ?? env.BITBUCKET_BRANCH ?? ''\n\n return { id: `bb:${env.BITBUCKET_REPO_UUID ?? ''}:${scope}`, name: `${env.BITBUCKET_REPO_FULL_NAME ?? 'bitbucket'}#${scope}`, commit: env.BITBUCKET_COMMIT }\n }\n\n if (env.CIRCLECI) {\n // Owner-qualified: two projects with the same name under different CircleCI orgs must not\n // collide on one agent, since registering it purges the other project's live sessions.\n const owner = env.CIRCLE_PROJECT_USERNAME ?? ''\n const project = env.CIRCLE_PROJECT_REPONAME ?? 'circleci'\n const scope = env.CIRCLE_PR_NUMBER ?? env.CIRCLE_BRANCH ?? ''\n\n return { id: `circle:${owner}:${project}:${scope}`, name: `${owner ? `${owner}/` : ''}${project}#${scope}`, commit: env.CIRCLE_SHA1 }\n }\n\n return null\n}\n","import { randomUUID } from 'node:crypto'\nimport { dirname, join } from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport { exists, read } from '@internals/utils'\nimport { cliReporter, logLevel as logLevelMap } from '@kubb/core'\nimport { createAgent, createJob, machineTokenFrom, runConnection, waitForJob, type StudioSnapshot, type StudioSnapshotChanges } from '@kubb/studio'\nimport { logBlock } from '../../loggers/output.ts'\nimport { createPlainLogger } from '../../loggers/plainLogger.ts'\nimport setupReporters from '../../loggers/utils.ts'\nimport { type CiContext, detectCi } from './ci.ts'\nimport { createStudioOptions, loadConfigs, run, type SnapshotOptions } from './run.ts'\nimport type { definition } from '../../commands/studio/snapshot.ts'\nimport type { CommandRunner } from 'gunshi'\n\n/**\n * How long to wait for Studio's `studio:ready` acknowledgement, above the client's own 10s\n * handshake-ack timeout.\n */\nconst READY_TIMEOUT_MS = 15_000\n\n/**\n * Longest `--timeout` accepted. Job records expire from Studio's storage after an hour.\n */\nconst MAX_TIMEOUT_SECONDS = 3600\n\nconst LOOPBACK_HOSTS = new Set(['localhost', '127.0.0.1', '::1'])\n\nasync function findPackageJson(startDirectory: string): Promise<{ name: string; version: string }> {\n let directory = startDirectory\n\n for (;;) {\n const file = join(directory, 'package.json')\n\n if (await exists(file)) {\n const packageJson = JSON.parse(await read(file)) as Partial<{ name: string; version: string }>\n\n if (packageJson.name && packageJson.version) {\n return { name: packageJson.name, version: packageJson.version }\n }\n }\n\n const parent = dirname(directory)\n\n if (parent === directory) {\n break\n }\n\n directory = parent\n }\n\n throw new Error(`No package.json with a name and a version found above ${startDirectory}`)\n}\n\n/** Reads package.json only for whichever of name/version --name and --version did not supply. */\nasync function resolvePackageMetadata(options: SnapshotOptions): Promise<{ name: string; version: string }> {\n if (options.name && options.packageVersion) {\n return { name: options.name, version: options.packageVersion }\n }\n\n const packageMetadata = await findPackageJson(process.cwd())\n\n return { name: options.name ?? packageMetadata.name, version: options.packageVersion ?? packageMetadata.version }\n}\n\nfunction resolveToken(options: SnapshotOptions): string {\n const token = options.token ?? process.env.KUBB_TOKEN\n\n if (!token) {\n throw new Error('An organization CI API key is required. Pass --token or set KUBB_TOKEN.')\n }\n\n return token\n}\n\nfunction resolveCiIdentity(options: SnapshotOptions): CiContext {\n const detected = detectCi()\n // A custom --id drops the detected base, since runs on that branch may use a custom id too.\n const ci = options.id ? { id: options.id, name: detected?.name ?? options.id, commit: detected?.commit } : detected\n\n if (!ci) {\n throw new Error('Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id.')\n }\n\n // An explicit --base-id may not name a branch, so it labels the comparison itself.\n const base = options.baseId ? { branch: options.baseId, id: options.baseId } : ci.base\n\n return { ...ci, base: base?.id === ci.id ? undefined : base }\n}\n\n/** Rejects a bad `--timeout` up front instead of letting it reach `waitForJob` as NaN or <= 0. */\nfunction resolveTimeoutMs(options: SnapshotOptions): number {\n const seconds = options.timeout ?? 600\n\n if (!Number.isFinite(seconds) || seconds <= 0) {\n throw new Error('--timeout must be a positive number of seconds')\n }\n\n return Math.min(seconds, MAX_TIMEOUT_SECONDS) * 1000\n}\n\n/** The CI key is a credential, so refuse to send it anywhere but HTTPS or a loopback dev host. */\nfunction assertSecureStudioUrl(studioUrl: string): void {\n const url = new URL(studioUrl)\n\n if (url.protocol !== 'https:' && !LOOPBACK_HOSTS.has(url.hostname)) {\n throw new Error(`Refusing to send the CI API key to ${studioUrl}. Use an https:// Studio URL, or a loopback host for local development.`)\n }\n}\n\nfunction absoluteUrl(studioUrl: string, path: string): string {\n return new URL(path, `${studioUrl}/`).toString()\n}\n\ntype SnapshotResult = {\n id: string\n name: string | null\n version: string | null\n integrity: string | null\n url: string\n snapshotIdUrl: string\n expiresAt: string\n agentUrl: string\n /** What changed since the previous snapshot of this package on this agent. */\n changes?: StudioSnapshotChanges\n /** What differs from the latest snapshot of the base branch, named by `branch`. */\n branchChanges?: StudioSnapshotChanges & { branch: string }\n}\n\nfunction toResult(studioUrl: string, snapshot: StudioSnapshot, agentSlug: string, ci: CiContext): SnapshotResult {\n return {\n id: snapshot.id,\n name: snapshot.name,\n version: snapshot.version,\n integrity: snapshot.integrity,\n url: absoluteUrl(studioUrl, snapshot.url),\n snapshotIdUrl: absoluteUrl(studioUrl, snapshot.snapshotIdUrl),\n expiresAt: snapshot.expiresAt,\n agentUrl: absoluteUrl(studioUrl, `/agents/${agentSlug}`),\n changes: snapshot.changes,\n branchChanges: snapshot.branchChanges && ci.base ? { ...snapshot.branchChanges, branch: ci.base.branch } : undefined,\n }\n}\n\n/** How many files differ, `against` what. */\nfunction describeChanges(changes: StudioSnapshotChanges, against: string): string {\n const { added, changed, removed } = changes\n\n return added.length + changed.length + removed.length\n ? `${added.length} added, ${changed.length} changed, ${removed.length} removed ${against}`\n : `No changes ${against}`\n}\n\n/** One summary line: how many files changed, and since which run. */\nexport function formatChanges(changes: StudioSnapshotChanges): string {\n if (!changes.base) {\n return 'First snapshot'\n }\n\n return describeChanges(changes, `since ${changes.base.commit?.slice(0, 7) ?? changes.base.createdAt}`)\n}\n\n/** One summary line: how the snapshot differs from the base branch's latest one. */\nexport function formatBranchChanges(changes: StudioSnapshotChanges & { branch: string }): string {\n return changes.base ? describeChanges(changes, `against ${changes.branch}`) : `No snapshot of ${changes.branch} to compare with`\n}\n\nfunction printSummary(result: SnapshotResult): void {\n logBlock([\n `${styleText('dim', 'Package'.padEnd(10))} ${result.name ?? '(unnamed)'}@${result.version ?? '0.0.0'}`,\n `${styleText('dim', 'Tarball'.padEnd(10))} ${styleText('cyan', result.url)}`,\n `${styleText('dim', 'Agent'.padEnd(10))} ${result.agentUrl}`,\n ...(result.branchChanges ? [`${styleText('dim', 'Branch'.padEnd(10))} ${formatBranchChanges(result.branchChanges)}`] : []),\n ...(result.changes ? [`${styleText('dim', 'Changes'.padEnd(10))} ${formatChanges(result.changes)}`] : []),\n `${styleText('dim', 'Expires'.padEnd(10))} ${result.expiresAt}`,\n ])\n}\n\n/**\n * Generates a Kubb Studio snapshot from a script: registers or reuses a CI agent, connects it,\n * queues a snapshot job, and polls until the tarball is ready. A snapshot job runs generation and\n * packs the tarball in one step, so this needs no separate generation run.\n */\nexport async function snapshot(options: SnapshotOptions): Promise<void> {\n const timeoutMs = resolveTimeoutMs(options)\n const token = resolveToken(options)\n assertSecureStudioUrl(options.studioUrl)\n const { configPath } = await loadConfigs(options)\n const ci = resolveCiIdentity(options)\n const { name, version: packageVersion } = await resolvePackageMetadata(options)\n const logLevel = logLevelMap[options.logLevel ?? 'info']\n\n // Set before the first `getMachineToken()` call (inside the connection), so the WebSocket\n // session registers under the same machine token `createAgent` just registered with Studio.\n process.env.KUBB_AGENT_SECRET = ci.id\n\n const write = options.json ? (line: string) => console.error(line) : (line: string) => console.log(line)\n const logger = createPlainLogger(write)\n const step = (message: string) => {\n if (logLevel > logLevelMap.silent) {\n write(message)\n }\n }\n\n step('Creating Kubb Studio agent')\n\n const agent = await createAgent({ studioUrl: options.studioUrl, token, name: ci.name, machineToken: machineTokenFrom(ci.id) })\n // Overlapping runs of one pipeline connect under the same CI agent. Naming this process lets the\n // snapshot job run here, on this run's checkout, and not on another run's.\n const instanceId = randomUUID()\n\n const { promise: ready, resolve: markReady } = Promise.withResolvers<void>()\n const shutdown = new AbortController()\n\n const connection = runConnection({\n credentials: { token: agent.token },\n signal: shutdown.signal,\n clientOptions: () => ({\n studioUrl: options.studioUrl,\n instanceId,\n configPath,\n root: process.cwd(),\n version: options.version,\n // Flags only: a script is never prompted and never reuses a saved answer.\n permissions: options.permission,\n loadConfig: async () => (await loadConfigs(options)).config,\n installLogger: async (hooks) => {\n await setupReporters(hooks, { logLevel, reporters: [cliReporter], logger })\n hooks.hook('studio:ready', () => markReady())\n },\n }),\n // A CI agent's token comes from the organization key, so there is no pairing to fall back to.\n onTokenRejected: ({ error }) => Promise.reject(error),\n })\n const connectionLost = new AbortController()\n const connectionEnded = new Error('The Kubb Studio connection ended before the snapshot finished')\n void connection.then(\n () => connectionLost.abort(connectionEnded),\n (error) => connectionLost.abort(error),\n )\n const lost = connection.then(\n () => Promise.reject(connectionEnded),\n (error) => Promise.reject(error),\n )\n void lost.catch(() => {})\n\n try {\n let readyTimeout: ReturnType<typeof setTimeout> | undefined\n try {\n await Promise.race([\n ready,\n lost,\n new Promise<never>((_, reject) => {\n readyTimeout = setTimeout(() => reject(new Error('Timed out waiting for Kubb Studio to confirm the agent was ready')), READY_TIMEOUT_MS)\n }),\n ])\n } finally {\n clearTimeout(readyTimeout)\n }\n\n step('Creating snapshot job')\n\n const snapshotDeadline = Date.now() + timeoutMs\n const snapshotTimeoutMs = () => Math.max(snapshotDeadline - Date.now(), 1)\n\n const job = await createJob({\n studioUrl: options.studioUrl,\n token,\n type: 'snapshot',\n agentId: agent.id,\n instanceId,\n name,\n version: packageVersion,\n commit: ci.commit,\n baseId: ci.base?.id,\n timeoutMs: snapshotTimeoutMs(),\n signal: connectionLost.signal,\n })\n step(`Snapshot job queued: ${job.id}`)\n const finished = await Promise.race([\n waitForJob({\n studioUrl: options.studioUrl,\n token,\n id: job.id,\n timeoutMs: snapshotTimeoutMs(),\n signal: connectionLost.signal,\n }),\n lost,\n ])\n\n if (finished.status === 'failed') {\n throw new Error(finished.error ?? 'Snapshot job failed')\n }\n\n if (!finished.snapshot) {\n throw new Error('Snapshot job succeeded without a snapshot')\n }\n\n const result = toResult(options.studioUrl, finished.snapshot, agent.slug, ci)\n\n step('Snapshot published')\n\n if (options.json) {\n console.log(JSON.stringify(result))\n }\n if (!options.json) {\n printSummary(result)\n }\n } catch (error) {\n step('Snapshot failed')\n throw error\n } finally {\n step('Disconnecting from Kubb Studio')\n // Not awaited: a half-open socket must not hold the run open.\n shutdown.abort()\n }\n}\n\nexport const runner: CommandRunner<{ args: typeof definition.args; extensions: {} }> = async ({ values }) => {\n const options: SnapshotOptions = {\n ...createStudioOptions(values),\n token: values.token,\n id: values.id,\n baseId: values.baseId,\n name: values.name,\n packageVersion: values.packageVersion,\n timeout: values.timeout,\n json: values.json,\n }\n await run(options, () => snapshot(options), { json: options.json })\n}\n"],"mappings":"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"}
|
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
import "./rolldown-runtime-C0LytTxp.js";
|
|
2
|
-
import { a as run, c as exists, l as read, n as createStudioOptions, r as loadConfigs } from "./run-
|
|
2
|
+
import { a as run, c as exists, l as read, n as createStudioOptions, r as loadConfigs } from "./run-D6QwS31H.js";
|
|
3
3
|
import { d as createPlainLogger, u as setupReporters } from "./utils-TpILNAy7.js";
|
|
4
4
|
import { r as logBlock } from "./output-C_Gk4p-8.js";
|
|
5
5
|
import { styleText } from "node:util";
|
|
6
|
+
import { randomUUID } from "node:crypto";
|
|
6
7
|
import process from "node:process";
|
|
7
8
|
import { dirname, join } from "node:path";
|
|
8
9
|
import { readFileSync } from "node:fs";
|
|
9
10
|
import { cliReporter, logLevel } from "@kubb/core";
|
|
10
11
|
import { createAgent, createJob, machineTokenFrom, runConnection, waitForJob } from "@kubb/studio";
|
|
11
12
|
//#region src/runners/studio/ci.ts
|
|
12
|
-
function
|
|
13
|
+
function readGithubPullRequest(eventPath) {
|
|
13
14
|
if (!eventPath) return;
|
|
14
15
|
try {
|
|
15
16
|
const event = JSON.parse(readFileSync(eventPath, "utf8"));
|
|
16
|
-
return event.pull_request?.number ?
|
|
17
|
+
return event.pull_request?.number ? event.pull_request : void 0;
|
|
17
18
|
} catch {
|
|
18
19
|
return;
|
|
19
20
|
}
|
|
20
21
|
}
|
|
22
|
+
/** Reproduces GitLab's `CI_COMMIT_REF_SLUG` for a branch it gives no slug of, like a merge request's target. */
|
|
23
|
+
function gitlabRefSlug(ref) {
|
|
24
|
+
return ref.toLowerCase().replace(/[^a-z0-9]/gu, "-").slice(0, 63).replace(/^-+|-+$/g, "");
|
|
25
|
+
}
|
|
21
26
|
/**
|
|
22
27
|
* Detects the CI provider from its environment variables and derives a stable identity from it.
|
|
23
28
|
* The GitHub row reproduces `gh:<repositoryId>:<prNumber>`, the identity `kubb-labs/action` has
|
|
@@ -25,21 +30,32 @@ function readGithubPullRequestNumber(eventPath) {
|
|
|
25
30
|
*/
|
|
26
31
|
function detectCi(env = process.env) {
|
|
27
32
|
if (env.GITHUB_ACTIONS) {
|
|
28
|
-
const
|
|
33
|
+
const pullRequest = readGithubPullRequest(env.GITHUB_EVENT_PATH);
|
|
29
34
|
const repositoryId = env.GITHUB_REPOSITORY_ID ?? env.GITHUB_REPOSITORY ?? "";
|
|
30
|
-
const
|
|
35
|
+
const branch = env.GITHUB_REF?.startsWith("refs/heads/") ? env.GITHUB_REF.slice(11) : void 0;
|
|
36
|
+
const scope = pullRequest?.number ?? (branch ? `refs/heads/${branch}` : env.GITHUB_RUN_ID) ?? "";
|
|
37
|
+
const baseBranch = pullRequest?.base?.ref;
|
|
31
38
|
return {
|
|
32
39
|
id: `gh:${repositoryId}:${scope}`,
|
|
33
|
-
name: `${env.GITHUB_REPOSITORY ?? "github"}#${scope}`,
|
|
34
|
-
commit: env.GITHUB_SHA
|
|
40
|
+
name: `${env.GITHUB_REPOSITORY ?? "github"}#${pullRequest?.number ?? branch ?? scope}`,
|
|
41
|
+
commit: pullRequest?.head?.sha ?? env.GITHUB_SHA,
|
|
42
|
+
base: baseBranch ? {
|
|
43
|
+
branch: baseBranch,
|
|
44
|
+
id: `gh:${repositoryId}:refs/heads/${baseBranch}`
|
|
45
|
+
} : void 0
|
|
35
46
|
};
|
|
36
47
|
}
|
|
37
48
|
if (env.GITLAB_CI) {
|
|
38
49
|
const scope = env.CI_MERGE_REQUEST_IID ?? env.CI_COMMIT_REF_SLUG ?? "";
|
|
50
|
+
const baseBranch = env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME;
|
|
39
51
|
return {
|
|
40
52
|
id: `gl:${env.CI_PROJECT_ID ?? ""}:${scope}`,
|
|
41
53
|
name: `${env.CI_PROJECT_PATH ?? "gitlab"}#${scope}`,
|
|
42
|
-
commit: env.CI_COMMIT_SHA
|
|
54
|
+
commit: env.CI_MERGE_REQUEST_SOURCE_BRANCH_SHA || env.CI_COMMIT_SHA,
|
|
55
|
+
base: baseBranch ? {
|
|
56
|
+
branch: baseBranch,
|
|
57
|
+
id: `gl:${env.CI_PROJECT_ID ?? ""}:${gitlabRefSlug(baseBranch)}`
|
|
58
|
+
} : void 0
|
|
43
59
|
};
|
|
44
60
|
}
|
|
45
61
|
if (env.BITBUCKET_BUILD_NUMBER) {
|
|
@@ -114,13 +130,20 @@ function resolveToken(options) {
|
|
|
114
130
|
}
|
|
115
131
|
function resolveCiIdentity(options) {
|
|
116
132
|
const detected = detectCi();
|
|
117
|
-
|
|
133
|
+
const ci = options.id ? {
|
|
118
134
|
id: options.id,
|
|
119
135
|
name: detected?.name ?? options.id,
|
|
120
136
|
commit: detected?.commit
|
|
137
|
+
} : detected;
|
|
138
|
+
if (!ci) throw new Error("Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id.");
|
|
139
|
+
const base = options.baseId ? {
|
|
140
|
+
branch: options.baseId,
|
|
141
|
+
id: options.baseId
|
|
142
|
+
} : ci.base;
|
|
143
|
+
return {
|
|
144
|
+
...ci,
|
|
145
|
+
base: base?.id === ci.id ? void 0 : base
|
|
121
146
|
};
|
|
122
|
-
if (!detected) throw new Error("Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id.");
|
|
123
|
-
return detected;
|
|
124
147
|
}
|
|
125
148
|
/** Rejects a bad `--timeout` up front instead of letting it reach `waitForJob` as NaN or <= 0. */
|
|
126
149
|
function resolveTimeoutMs(options) {
|
|
@@ -136,7 +159,7 @@ function assertSecureStudioUrl(studioUrl) {
|
|
|
136
159
|
function absoluteUrl(studioUrl, path) {
|
|
137
160
|
return new URL(path, `${studioUrl}/`).toString();
|
|
138
161
|
}
|
|
139
|
-
function toResult(studioUrl, snapshot, agentSlug) {
|
|
162
|
+
function toResult(studioUrl, snapshot, agentSlug, ci) {
|
|
140
163
|
return {
|
|
141
164
|
id: snapshot.id,
|
|
142
165
|
name: snapshot.name,
|
|
@@ -146,25 +169,33 @@ function toResult(studioUrl, snapshot, agentSlug) {
|
|
|
146
169
|
snapshotIdUrl: absoluteUrl(studioUrl, snapshot.snapshotIdUrl),
|
|
147
170
|
expiresAt: snapshot.expiresAt,
|
|
148
171
|
agentUrl: absoluteUrl(studioUrl, `/agents/${agentSlug}`),
|
|
149
|
-
changes: snapshot.changes
|
|
172
|
+
changes: snapshot.changes,
|
|
173
|
+
branchChanges: snapshot.branchChanges && ci.base ? {
|
|
174
|
+
...snapshot.branchChanges,
|
|
175
|
+
branch: ci.base.branch
|
|
176
|
+
} : void 0
|
|
150
177
|
};
|
|
151
178
|
}
|
|
179
|
+
/** How many files differ, `against` what. */
|
|
180
|
+
function describeChanges(changes, against) {
|
|
181
|
+
const { added, changed, removed } = changes;
|
|
182
|
+
return added.length + changed.length + removed.length ? `${added.length} added, ${changed.length} changed, ${removed.length} removed ${against}` : `No changes ${against}`;
|
|
183
|
+
}
|
|
152
184
|
/** One summary line: how many files changed, and since which run. */
|
|
153
185
|
function formatChanges(changes) {
|
|
154
186
|
if (!changes.base) return "First snapshot";
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const since = changes.base.commit ? changes.base.commit.slice(0, 7) : changes.base.createdAt;
|
|
161
|
-
return changes.added.length + changes.changed.length + changes.removed.length ? `${counts} since ${since}` : `No changes since ${since}`;
|
|
187
|
+
return describeChanges(changes, `since ${changes.base.commit?.slice(0, 7) ?? changes.base.createdAt}`);
|
|
188
|
+
}
|
|
189
|
+
/** One summary line: how the snapshot differs from the base branch's latest one. */
|
|
190
|
+
function formatBranchChanges(changes) {
|
|
191
|
+
return changes.base ? describeChanges(changes, `against ${changes.branch}`) : `No snapshot of ${changes.branch} to compare with`;
|
|
162
192
|
}
|
|
163
193
|
function printSummary(result) {
|
|
164
194
|
logBlock([
|
|
165
195
|
`${styleText("dim", "Package".padEnd(10))} ${result.name ?? "(unnamed)"}@${result.version ?? "0.0.0"}`,
|
|
166
196
|
`${styleText("dim", "Tarball".padEnd(10))} ${styleText("cyan", result.url)}`,
|
|
167
197
|
`${styleText("dim", "Agent".padEnd(10))} ${result.agentUrl}`,
|
|
198
|
+
...result.branchChanges ? [`${styleText("dim", "Branch".padEnd(10))} ${formatBranchChanges(result.branchChanges)}`] : [],
|
|
168
199
|
...result.changes ? [`${styleText("dim", "Changes".padEnd(10))} ${formatChanges(result.changes)}`] : [],
|
|
169
200
|
`${styleText("dim", "Expires".padEnd(10))} ${result.expiresAt}`
|
|
170
201
|
]);
|
|
@@ -195,13 +226,15 @@ async function snapshot(options) {
|
|
|
195
226
|
name: ci.name,
|
|
196
227
|
machineToken: machineTokenFrom(ci.id)
|
|
197
228
|
});
|
|
229
|
+
const instanceId = randomUUID();
|
|
198
230
|
const { promise: ready, resolve: markReady } = Promise.withResolvers();
|
|
199
231
|
const shutdown = new AbortController();
|
|
200
|
-
const
|
|
232
|
+
const connection = runConnection({
|
|
201
233
|
credentials: { token: agent.token },
|
|
202
234
|
signal: shutdown.signal,
|
|
203
235
|
clientOptions: () => ({
|
|
204
236
|
studioUrl: options.studioUrl,
|
|
237
|
+
instanceId,
|
|
205
238
|
configPath,
|
|
206
239
|
root: process.cwd(),
|
|
207
240
|
version: options.version,
|
|
@@ -217,7 +250,11 @@ async function snapshot(options) {
|
|
|
217
250
|
}
|
|
218
251
|
}),
|
|
219
252
|
onTokenRejected: ({ error }) => Promise.reject(error)
|
|
220
|
-
})
|
|
253
|
+
});
|
|
254
|
+
const connectionLost = new AbortController();
|
|
255
|
+
const connectionEnded = /* @__PURE__ */ new Error("The Kubb Studio connection ended before the snapshot finished");
|
|
256
|
+
connection.then(() => connectionLost.abort(connectionEnded), (error) => connectionLost.abort(error));
|
|
257
|
+
const lost = connection.then(() => Promise.reject(connectionEnded), (error) => Promise.reject(error));
|
|
221
258
|
lost.catch(() => {});
|
|
222
259
|
try {
|
|
223
260
|
let readyTimeout;
|
|
@@ -233,25 +270,32 @@ async function snapshot(options) {
|
|
|
233
270
|
clearTimeout(readyTimeout);
|
|
234
271
|
}
|
|
235
272
|
step("Creating snapshot job");
|
|
273
|
+
const snapshotDeadline = Date.now() + timeoutMs;
|
|
274
|
+
const snapshotTimeoutMs = () => Math.max(snapshotDeadline - Date.now(), 1);
|
|
236
275
|
const job = await createJob({
|
|
237
276
|
studioUrl: options.studioUrl,
|
|
238
277
|
token,
|
|
239
278
|
type: "snapshot",
|
|
240
279
|
agentId: agent.id,
|
|
280
|
+
instanceId,
|
|
241
281
|
name,
|
|
242
282
|
version: packageVersion,
|
|
243
|
-
commit: ci.commit
|
|
283
|
+
commit: ci.commit,
|
|
284
|
+
baseId: ci.base?.id,
|
|
285
|
+
timeoutMs: snapshotTimeoutMs(),
|
|
286
|
+
signal: connectionLost.signal
|
|
244
287
|
});
|
|
245
288
|
step(`Snapshot job queued: ${job.id}`);
|
|
246
289
|
const finished = await Promise.race([waitForJob({
|
|
247
290
|
studioUrl: options.studioUrl,
|
|
248
291
|
token,
|
|
249
292
|
id: job.id,
|
|
250
|
-
timeoutMs
|
|
293
|
+
timeoutMs: snapshotTimeoutMs(),
|
|
294
|
+
signal: connectionLost.signal
|
|
251
295
|
}), lost]);
|
|
252
296
|
if (finished.status === "failed") throw new Error(finished.error ?? "Snapshot job failed");
|
|
253
297
|
if (!finished.snapshot) throw new Error("Snapshot job succeeded without a snapshot");
|
|
254
|
-
const result = toResult(options.studioUrl, finished.snapshot, agent.slug);
|
|
298
|
+
const result = toResult(options.studioUrl, finished.snapshot, agent.slug, ci);
|
|
255
299
|
step("Snapshot published");
|
|
256
300
|
if (options.json) console.log(JSON.stringify(result));
|
|
257
301
|
if (!options.json) printSummary(result);
|
|
@@ -268,6 +312,7 @@ const runner = async ({ values }) => {
|
|
|
268
312
|
...createStudioOptions(values),
|
|
269
313
|
token: values.token,
|
|
270
314
|
id: values.id,
|
|
315
|
+
baseId: values.baseId,
|
|
271
316
|
name: values.name,
|
|
272
317
|
packageVersion: values.packageVersion,
|
|
273
318
|
timeout: values.timeout,
|
|
@@ -278,4 +323,4 @@ const runner = async ({ values }) => {
|
|
|
278
323
|
//#endregion
|
|
279
324
|
export { runner };
|
|
280
325
|
|
|
281
|
-
//# sourceMappingURL=snapshot-
|
|
326
|
+
//# sourceMappingURL=snapshot-aiwOrbuI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-aiwOrbuI.js","names":["logLevel","logLevelMap"],"sources":["../src/runners/studio/ci.ts","../src/runners/studio/snapshot.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport process from 'node:process'\n\n/**\n * Stable identity for the CI agent a snapshot run registers or reuses.\n */\nexport type CiContext = {\n /**\n * Fed into the machine token, so the same merge or pull request reuses one agent.\n */\n id: string\n /**\n * Agent display name shown in Studio.\n */\n name: string\n /** The commit this run builds, so the next snapshot can diff against it. */\n commit?: string\n /** The branch a pull request merges into, and the `id` runs on that branch register under. */\n base?: { branch: string; id: string }\n}\n\ntype GithubPullRequest = { number: number; head?: { sha?: string }; base?: { ref?: string } }\n\nfunction readGithubPullRequest(eventPath: string | undefined): GithubPullRequest | undefined {\n if (!eventPath) {\n return undefined\n }\n\n try {\n const event = JSON.parse(readFileSync(eventPath, 'utf8')) as { pull_request?: GithubPullRequest }\n return event.pull_request?.number ? event.pull_request : undefined\n } catch {\n return undefined\n }\n}\n\n/** Reproduces GitLab's `CI_COMMIT_REF_SLUG` for a branch it gives no slug of, like a merge request's target. */\nexport function gitlabRefSlug(ref: string): string {\n return ref\n .toLowerCase()\n .replace(/[^a-z0-9]/gu, '-')\n .slice(0, 63)\n .replace(/^-+|-+$/g, '')\n}\n\n/**\n * Detects the CI provider from its environment variables and derives a stable identity from it.\n * The GitHub row reproduces `gh:<repositoryId>:<prNumber>`, the identity `kubb-labs/action` has\n * always registered agents under, so an existing repository keeps reusing its agent.\n */\nexport function detectCi(env: Record<string, string | undefined> = process.env): CiContext | null {\n if (env.GITHUB_ACTIONS) {\n const pullRequest = readGithubPullRequest(env.GITHUB_EVENT_PATH)\n const repositoryId = env.GITHUB_REPOSITORY_ID ?? env.GITHUB_REPOSITORY ?? ''\n const branch = env.GITHUB_REF?.startsWith('refs/heads/') ? env.GITHUB_REF.slice('refs/heads/'.length) : undefined\n // A branch run is scoped by its ref, which a pull request number never collides with.\n const scope = pullRequest?.number ?? (branch ? `refs/heads/${branch}` : env.GITHUB_RUN_ID) ?? ''\n const baseBranch = pullRequest?.base?.ref\n\n return {\n id: `gh:${repositoryId}:${scope}`,\n name: `${env.GITHUB_REPOSITORY ?? 'github'}#${pullRequest?.number ?? branch ?? scope}`,\n // The head commit, not the merge commit a pull request run checks out.\n commit: pullRequest?.head?.sha ?? env.GITHUB_SHA,\n base: baseBranch ? { branch: baseBranch, id: `gh:${repositoryId}:refs/heads/${baseBranch}` } : undefined,\n }\n }\n\n if (env.GITLAB_CI) {\n const scope = env.CI_MERGE_REQUEST_IID ?? env.CI_COMMIT_REF_SLUG ?? ''\n const baseBranch = env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME\n\n return {\n id: `gl:${env.CI_PROJECT_ID ?? ''}:${scope}`,\n name: `${env.CI_PROJECT_PATH ?? 'gitlab'}#${scope}`,\n commit: env.CI_MERGE_REQUEST_SOURCE_BRANCH_SHA || env.CI_COMMIT_SHA,\n base: baseBranch ? { branch: baseBranch, id: `gl:${env.CI_PROJECT_ID ?? ''}:${gitlabRefSlug(baseBranch)}` } : undefined,\n }\n }\n\n if (env.BITBUCKET_BUILD_NUMBER) {\n const scope = env.BITBUCKET_PR_ID ?? env.BITBUCKET_BRANCH ?? ''\n\n return { id: `bb:${env.BITBUCKET_REPO_UUID ?? ''}:${scope}`, name: `${env.BITBUCKET_REPO_FULL_NAME ?? 'bitbucket'}#${scope}`, commit: env.BITBUCKET_COMMIT }\n }\n\n if (env.CIRCLECI) {\n // Owner-qualified: two projects with the same name under different CircleCI orgs must not\n // collide on one agent, since registering it purges the other project's live sessions.\n const owner = env.CIRCLE_PROJECT_USERNAME ?? ''\n const project = env.CIRCLE_PROJECT_REPONAME ?? 'circleci'\n const scope = env.CIRCLE_PR_NUMBER ?? env.CIRCLE_BRANCH ?? ''\n\n return { id: `circle:${owner}:${project}:${scope}`, name: `${owner ? `${owner}/` : ''}${project}#${scope}`, commit: env.CIRCLE_SHA1 }\n }\n\n return null\n}\n","import { randomUUID } from 'node:crypto'\nimport { dirname, join } from 'node:path'\nimport process from 'node:process'\nimport { styleText } from 'node:util'\nimport { exists, read } from '@internals/utils'\nimport { cliReporter, logLevel as logLevelMap } from '@kubb/core'\nimport { createAgent, createJob, machineTokenFrom, runConnection, waitForJob, type StudioSnapshot, type StudioSnapshotChanges } from '@kubb/studio'\nimport { logBlock } from '../../loggers/output.ts'\nimport { createPlainLogger } from '../../loggers/plainLogger.ts'\nimport setupReporters from '../../loggers/utils.ts'\nimport { type CiContext, detectCi } from './ci.ts'\nimport { createStudioOptions, loadConfigs, run, type SnapshotOptions } from './run.ts'\nimport type { definition } from '../../commands/studio/snapshot.ts'\nimport type { CommandRunner } from 'gunshi'\n\n/**\n * How long to wait for Studio's `studio:ready` acknowledgement, above the client's own 10s\n * handshake-ack timeout.\n */\nconst READY_TIMEOUT_MS = 15_000\n\n/**\n * Longest `--timeout` accepted. Job records expire from Studio's storage after an hour.\n */\nconst MAX_TIMEOUT_SECONDS = 3600\n\nconst LOOPBACK_HOSTS = new Set(['localhost', '127.0.0.1', '::1'])\n\nasync function findPackageJson(startDirectory: string): Promise<{ name: string; version: string }> {\n let directory = startDirectory\n\n for (;;) {\n const file = join(directory, 'package.json')\n\n if (await exists(file)) {\n const packageJson = JSON.parse(await read(file)) as Partial<{ name: string; version: string }>\n\n if (packageJson.name && packageJson.version) {\n return { name: packageJson.name, version: packageJson.version }\n }\n }\n\n const parent = dirname(directory)\n\n if (parent === directory) {\n break\n }\n\n directory = parent\n }\n\n throw new Error(`No package.json with a name and a version found above ${startDirectory}`)\n}\n\n/** Reads package.json only for whichever of name/version --name and --version did not supply. */\nasync function resolvePackageMetadata(options: SnapshotOptions): Promise<{ name: string; version: string }> {\n if (options.name && options.packageVersion) {\n return { name: options.name, version: options.packageVersion }\n }\n\n const packageMetadata = await findPackageJson(process.cwd())\n\n return { name: options.name ?? packageMetadata.name, version: options.packageVersion ?? packageMetadata.version }\n}\n\nfunction resolveToken(options: SnapshotOptions): string {\n const token = options.token ?? process.env.KUBB_TOKEN\n\n if (!token) {\n throw new Error('An organization CI API key is required. Pass --token or set KUBB_TOKEN.')\n }\n\n return token\n}\n\nfunction resolveCiIdentity(options: SnapshotOptions): CiContext {\n const detected = detectCi()\n // A custom --id drops the detected base, since runs on that branch may use a custom id too.\n const ci = options.id ? { id: options.id, name: detected?.name ?? options.id, commit: detected?.commit } : detected\n\n if (!ci) {\n throw new Error('Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id.')\n }\n\n // An explicit --base-id may not name a branch, so it labels the comparison itself.\n const base = options.baseId ? { branch: options.baseId, id: options.baseId } : ci.base\n\n return { ...ci, base: base?.id === ci.id ? undefined : base }\n}\n\n/** Rejects a bad `--timeout` up front instead of letting it reach `waitForJob` as NaN or <= 0. */\nfunction resolveTimeoutMs(options: SnapshotOptions): number {\n const seconds = options.timeout ?? 600\n\n if (!Number.isFinite(seconds) || seconds <= 0) {\n throw new Error('--timeout must be a positive number of seconds')\n }\n\n return Math.min(seconds, MAX_TIMEOUT_SECONDS) * 1000\n}\n\n/** The CI key is a credential, so refuse to send it anywhere but HTTPS or a loopback dev host. */\nfunction assertSecureStudioUrl(studioUrl: string): void {\n const url = new URL(studioUrl)\n\n if (url.protocol !== 'https:' && !LOOPBACK_HOSTS.has(url.hostname)) {\n throw new Error(`Refusing to send the CI API key to ${studioUrl}. Use an https:// Studio URL, or a loopback host for local development.`)\n }\n}\n\nfunction absoluteUrl(studioUrl: string, path: string): string {\n return new URL(path, `${studioUrl}/`).toString()\n}\n\ntype SnapshotResult = {\n id: string\n name: string | null\n version: string | null\n integrity: string | null\n url: string\n snapshotIdUrl: string\n expiresAt: string\n agentUrl: string\n /** What changed since the previous snapshot of this package on this agent. */\n changes?: StudioSnapshotChanges\n /** What differs from the latest snapshot of the base branch, named by `branch`. */\n branchChanges?: StudioSnapshotChanges & { branch: string }\n}\n\nfunction toResult(studioUrl: string, snapshot: StudioSnapshot, agentSlug: string, ci: CiContext): SnapshotResult {\n return {\n id: snapshot.id,\n name: snapshot.name,\n version: snapshot.version,\n integrity: snapshot.integrity,\n url: absoluteUrl(studioUrl, snapshot.url),\n snapshotIdUrl: absoluteUrl(studioUrl, snapshot.snapshotIdUrl),\n expiresAt: snapshot.expiresAt,\n agentUrl: absoluteUrl(studioUrl, `/agents/${agentSlug}`),\n changes: snapshot.changes,\n branchChanges: snapshot.branchChanges && ci.base ? { ...snapshot.branchChanges, branch: ci.base.branch } : undefined,\n }\n}\n\n/** How many files differ, `against` what. */\nfunction describeChanges(changes: StudioSnapshotChanges, against: string): string {\n const { added, changed, removed } = changes\n\n return added.length + changed.length + removed.length\n ? `${added.length} added, ${changed.length} changed, ${removed.length} removed ${against}`\n : `No changes ${against}`\n}\n\n/** One summary line: how many files changed, and since which run. */\nexport function formatChanges(changes: StudioSnapshotChanges): string {\n if (!changes.base) {\n return 'First snapshot'\n }\n\n return describeChanges(changes, `since ${changes.base.commit?.slice(0, 7) ?? changes.base.createdAt}`)\n}\n\n/** One summary line: how the snapshot differs from the base branch's latest one. */\nexport function formatBranchChanges(changes: StudioSnapshotChanges & { branch: string }): string {\n return changes.base ? describeChanges(changes, `against ${changes.branch}`) : `No snapshot of ${changes.branch} to compare with`\n}\n\nfunction printSummary(result: SnapshotResult): void {\n logBlock([\n `${styleText('dim', 'Package'.padEnd(10))} ${result.name ?? '(unnamed)'}@${result.version ?? '0.0.0'}`,\n `${styleText('dim', 'Tarball'.padEnd(10))} ${styleText('cyan', result.url)}`,\n `${styleText('dim', 'Agent'.padEnd(10))} ${result.agentUrl}`,\n ...(result.branchChanges ? [`${styleText('dim', 'Branch'.padEnd(10))} ${formatBranchChanges(result.branchChanges)}`] : []),\n ...(result.changes ? [`${styleText('dim', 'Changes'.padEnd(10))} ${formatChanges(result.changes)}`] : []),\n `${styleText('dim', 'Expires'.padEnd(10))} ${result.expiresAt}`,\n ])\n}\n\n/**\n * Generates a Kubb Studio snapshot from a script: registers or reuses a CI agent, connects it,\n * queues a snapshot job, and polls until the tarball is ready. A snapshot job runs generation and\n * packs the tarball in one step, so this needs no separate generation run.\n */\nexport async function snapshot(options: SnapshotOptions): Promise<void> {\n const timeoutMs = resolveTimeoutMs(options)\n const token = resolveToken(options)\n assertSecureStudioUrl(options.studioUrl)\n const { configPath } = await loadConfigs(options)\n const ci = resolveCiIdentity(options)\n const { name, version: packageVersion } = await resolvePackageMetadata(options)\n const logLevel = logLevelMap[options.logLevel ?? 'info']\n\n // Set before the first `getMachineToken()` call (inside the connection), so the WebSocket\n // session registers under the same machine token `createAgent` just registered with Studio.\n process.env.KUBB_AGENT_SECRET = ci.id\n\n const write = options.json ? (line: string) => console.error(line) : (line: string) => console.log(line)\n const logger = createPlainLogger(write)\n const step = (message: string) => {\n if (logLevel > logLevelMap.silent) {\n write(message)\n }\n }\n\n step('Creating Kubb Studio agent')\n\n const agent = await createAgent({ studioUrl: options.studioUrl, token, name: ci.name, machineToken: machineTokenFrom(ci.id) })\n // Overlapping runs of one pipeline connect under the same CI agent. Naming this process lets the\n // snapshot job run here, on this run's checkout, and not on another run's.\n const instanceId = randomUUID()\n\n const { promise: ready, resolve: markReady } = Promise.withResolvers<void>()\n const shutdown = new AbortController()\n\n const connection = runConnection({\n credentials: { token: agent.token },\n signal: shutdown.signal,\n clientOptions: () => ({\n studioUrl: options.studioUrl,\n instanceId,\n configPath,\n root: process.cwd(),\n version: options.version,\n // Flags only: a script is never prompted and never reuses a saved answer.\n permissions: options.permission,\n loadConfig: async () => (await loadConfigs(options)).config,\n installLogger: async (hooks) => {\n await setupReporters(hooks, { logLevel, reporters: [cliReporter], logger })\n hooks.hook('studio:ready', () => markReady())\n },\n }),\n // A CI agent's token comes from the organization key, so there is no pairing to fall back to.\n onTokenRejected: ({ error }) => Promise.reject(error),\n })\n const connectionLost = new AbortController()\n const connectionEnded = new Error('The Kubb Studio connection ended before the snapshot finished')\n void connection.then(\n () => connectionLost.abort(connectionEnded),\n (error) => connectionLost.abort(error),\n )\n const lost = connection.then(\n () => Promise.reject(connectionEnded),\n (error) => Promise.reject(error),\n )\n void lost.catch(() => {})\n\n try {\n let readyTimeout: ReturnType<typeof setTimeout> | undefined\n try {\n await Promise.race([\n ready,\n lost,\n new Promise<never>((_, reject) => {\n readyTimeout = setTimeout(() => reject(new Error('Timed out waiting for Kubb Studio to confirm the agent was ready')), READY_TIMEOUT_MS)\n }),\n ])\n } finally {\n clearTimeout(readyTimeout)\n }\n\n step('Creating snapshot job')\n\n const snapshotDeadline = Date.now() + timeoutMs\n const snapshotTimeoutMs = () => Math.max(snapshotDeadline - Date.now(), 1)\n\n const job = await createJob({\n studioUrl: options.studioUrl,\n token,\n type: 'snapshot',\n agentId: agent.id,\n instanceId,\n name,\n version: packageVersion,\n commit: ci.commit,\n baseId: ci.base?.id,\n timeoutMs: snapshotTimeoutMs(),\n signal: connectionLost.signal,\n })\n step(`Snapshot job queued: ${job.id}`)\n const finished = await Promise.race([\n waitForJob({\n studioUrl: options.studioUrl,\n token,\n id: job.id,\n timeoutMs: snapshotTimeoutMs(),\n signal: connectionLost.signal,\n }),\n lost,\n ])\n\n if (finished.status === 'failed') {\n throw new Error(finished.error ?? 'Snapshot job failed')\n }\n\n if (!finished.snapshot) {\n throw new Error('Snapshot job succeeded without a snapshot')\n }\n\n const result = toResult(options.studioUrl, finished.snapshot, agent.slug, ci)\n\n step('Snapshot published')\n\n if (options.json) {\n console.log(JSON.stringify(result))\n }\n if (!options.json) {\n printSummary(result)\n }\n } catch (error) {\n step('Snapshot failed')\n throw error\n } finally {\n step('Disconnecting from Kubb Studio')\n // Not awaited: a half-open socket must not hold the run open.\n shutdown.abort()\n }\n}\n\nexport const runner: CommandRunner<{ args: typeof definition.args; extensions: {} }> = async ({ values }) => {\n const options: SnapshotOptions = {\n ...createStudioOptions(values),\n token: values.token,\n id: values.id,\n baseId: values.baseId,\n name: values.name,\n packageVersion: values.packageVersion,\n timeout: values.timeout,\n json: values.json,\n }\n await run(options, () => snapshot(options), { json: options.json })\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
require("./rolldown-runtime-qbf5tadS.cjs");
|
|
2
|
-
const require_run = require("./run-
|
|
2
|
+
const require_run = require("./run-Dp24WE9v.cjs");
|
|
3
3
|
//#region src/runners/studio/status.ts
|
|
4
4
|
const runner = async ({ values }) => {
|
|
5
5
|
const options = require_run.createStudioOptions(values);
|
|
@@ -8,4 +8,4 @@ const runner = async ({ values }) => {
|
|
|
8
8
|
//#endregion
|
|
9
9
|
exports.runner = runner;
|
|
10
10
|
|
|
11
|
-
//# sourceMappingURL=status-
|
|
11
|
+
//# sourceMappingURL=status-CYhqs_P9.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status-
|
|
1
|
+
{"version":3,"file":"status-CYhqs_P9.cjs","names":["createStudioOptions","run","status"],"sources":["../src/runners/studio/status.ts"],"sourcesContent":["import type { CommandRunner } from 'gunshi'\nimport type { definition } from '../../commands/studio/status.ts'\nimport { createStudioOptions, run, status } from './run.ts'\n\nexport const runner: CommandRunner<{ args: typeof definition.args; extensions: {} }> = async ({ values }) => {\n const options = createStudioOptions(values)\n await run(options, () => status(options))\n}\n"],"mappings":";;;AAIA,MAAa,SAA0E,OAAO,EAAE,aAAa;CAC3G,MAAM,UAAUA,YAAAA,oBAAoB,MAAM;CAC1C,MAAMC,YAAAA,IAAI,eAAeC,YAAAA,OAAO,OAAO,CAAC;AAC1C"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./rolldown-runtime-C0LytTxp.js";
|
|
2
|
-
import { a as run, n as createStudioOptions, o as status } from "./run-
|
|
2
|
+
import { a as run, n as createStudioOptions, o as status } from "./run-D6QwS31H.js";
|
|
3
3
|
//#region src/runners/studio/status.ts
|
|
4
4
|
const runner = async ({ values }) => {
|
|
5
5
|
const options = createStudioOptions(values);
|
|
@@ -8,4 +8,4 @@ const runner = async ({ values }) => {
|
|
|
8
8
|
//#endregion
|
|
9
9
|
export { runner };
|
|
10
10
|
|
|
11
|
-
//# sourceMappingURL=status-
|
|
11
|
+
//# sourceMappingURL=status-CkKR5TPs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status-
|
|
1
|
+
{"version":3,"file":"status-CkKR5TPs.js","names":[],"sources":["../src/runners/studio/status.ts"],"sourcesContent":["import type { CommandRunner } from 'gunshi'\nimport type { definition } from '../../commands/studio/status.ts'\nimport { createStudioOptions, run, status } from './run.ts'\n\nexport const runner: CommandRunner<{ args: typeof definition.args; extensions: {} }> = async ({ values }) => {\n const options = createStudioOptions(values)\n await run(options, () => status(options))\n}\n"],"mappings":";;;AAIA,MAAa,SAA0E,OAAO,EAAE,aAAa;CAC3G,MAAM,UAAU,oBAAoB,MAAM;CAC1C,MAAM,IAAI,eAAe,OAAO,OAAO,CAAC;AAC1C"}
|
|
@@ -75,6 +75,11 @@ const definition$2 = define({
|
|
|
75
75
|
type: "string",
|
|
76
76
|
description: "Stable identity for the CI agent, such as a pull request. Auto-detected on GitHub Actions, GitLab CI, Bitbucket Pipelines and CircleCI"
|
|
77
77
|
},
|
|
78
|
+
baseId: {
|
|
79
|
+
type: "string",
|
|
80
|
+
description: "Identity of another CI agent, such as the base branch's, to also compare this snapshot with. Auto-detected on GitHub pull requests and GitLab merge requests",
|
|
81
|
+
toKebab: true
|
|
82
|
+
},
|
|
78
83
|
name: {
|
|
79
84
|
type: "string",
|
|
80
85
|
description: "Package name for the generated tarball. Defaults to the name in package.json"
|
|
@@ -138,18 +143,18 @@ const definition = define({
|
|
|
138
143
|
...logLevelArg
|
|
139
144
|
},
|
|
140
145
|
async run(ctx) {
|
|
141
|
-
const { runner } = await import("./connect-
|
|
146
|
+
const { runner } = await import("./connect-BP2OiMvo.js");
|
|
142
147
|
await runner(ctx);
|
|
143
148
|
},
|
|
144
149
|
subCommands: {
|
|
145
|
-
connect: lazy(async () => (await import("./connect-
|
|
146
|
-
login: lazy(async () => (await import("./login-
|
|
147
|
-
logout: lazy(async () => (await import("./logout-
|
|
148
|
-
status: lazy(async () => (await import("./status-
|
|
149
|
-
snapshot: lazy(async () => (await import("./snapshot-
|
|
150
|
+
connect: lazy(async () => (await import("./connect-BP2OiMvo.js")).runner, definition$5),
|
|
151
|
+
login: lazy(async () => (await import("./login-AEDO32Tf.js")).runner, definition$4),
|
|
152
|
+
logout: lazy(async () => (await import("./logout-Bw7zyqib.js")).runner, definition$3),
|
|
153
|
+
status: lazy(async () => (await import("./status-CkKR5TPs.js")).runner, definition$1),
|
|
154
|
+
snapshot: lazy(async () => (await import("./snapshot-aiwOrbuI.js")).runner, definition$2)
|
|
150
155
|
}
|
|
151
156
|
});
|
|
152
157
|
//#endregion
|
|
153
158
|
export { definition };
|
|
154
159
|
|
|
155
|
-
//# sourceMappingURL=studio-
|
|
160
|
+
//# sourceMappingURL=studio-C2ex3VFM.js.map
|