@kubb/cli 5.3.16 → 5.3.17
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-DQWYjheY.js} +2 -2
- package/dist/{connect-IObjkkpy.js.map → connect-DQWYjheY.js.map} +1 -1
- package/dist/{connect-CYlbWNUk.cjs → connect-c9W1razJ.cjs} +2 -2
- package/dist/{connect-CYlbWNUk.cjs.map → connect-c9W1razJ.cjs.map} +1 -1
- package/dist/{generate-RIE_QgE_.js → generate-BSnIzFH0.js} +2 -2
- package/dist/{generate-RIE_QgE_.js.map → generate-BSnIzFH0.js.map} +1 -1
- package/dist/{generate-By-otZHV.cjs → generate-BoamktRp.cjs} +2 -2
- package/dist/{generate-By-otZHV.cjs.map → generate-BoamktRp.cjs.map} +1 -1
- package/dist/index.cjs +7 -7
- package/dist/index.js +7 -7
- package/dist/{init-m87O7gWD.cjs → init--iLsTi1X.cjs} +2 -2
- package/dist/{init-m87O7gWD.cjs.map → init--iLsTi1X.cjs.map} +1 -1
- package/dist/{init-BTOW_efj.js → init-C6AZG9IZ.js} +2 -2
- package/dist/{init-BTOW_efj.js.map → init-C6AZG9IZ.js.map} +1 -1
- package/dist/{login-CA_xoFp7.js → login-Bkm0Bcwh.js} +2 -2
- package/dist/{login-CA_xoFp7.js.map → login-Bkm0Bcwh.js.map} +1 -1
- package/dist/{login-XpaX0zmW.cjs → login-DICKtsMS.cjs} +2 -2
- package/dist/{login-XpaX0zmW.cjs.map → login-DICKtsMS.cjs.map} +1 -1
- package/dist/{logout-BRZyHSgy.js → logout-CCAt5yNI.js} +2 -2
- package/dist/{logout-BRZyHSgy.js.map → logout-CCAt5yNI.js.map} +1 -1
- package/dist/{logout-CzsW6zdv.cjs → logout-Cq_SjOQf.cjs} +2 -2
- package/dist/{logout-CzsW6zdv.cjs.map → logout-Cq_SjOQf.cjs.map} +1 -1
- package/dist/{package-DvqvX4iy.cjs → package-Bpz2OqOp.cjs} +2 -2
- package/dist/package-Bpz2OqOp.cjs.map +1 -0
- package/dist/package-CO6hZYJK.js +6 -0
- package/dist/package-CO6hZYJK.js.map +1 -0
- package/dist/{run-DQGHRxvY.cjs → run-CHG7Y4OF.cjs} +2 -2
- package/dist/{run-DQGHRxvY.cjs.map → run-CHG7Y4OF.cjs.map} +1 -1
- package/dist/{run-Dy5NxCMm.js → run-CQmDghzm.js} +2 -2
- package/dist/{run-Dy5NxCMm.js.map → run-CQmDghzm.js.map} +1 -1
- package/dist/{run-DjMd8cvr.cjs → run-Cx_Biqws.cjs} +2 -2
- package/dist/{run-DjMd8cvr.cjs.map → run-Cx_Biqws.cjs.map} +1 -1
- package/dist/{run-jbHIvdOg.js → run-D5DrRIpE.js} +2 -2
- package/dist/{run-jbHIvdOg.js.map → run-D5DrRIpE.js.map} +1 -1
- package/dist/{run-DOOtoHGQ.js → run-DgJoQeWU.js} +2 -2
- package/dist/run-DgJoQeWU.js.map +1 -0
- package/dist/{run-BZr3INfK.js → run-Dq11mN4W.js} +2 -2
- package/dist/{run-BZr3INfK.js.map → run-Dq11mN4W.js.map} +1 -1
- package/dist/{run-BkpO4HyT.cjs → run-QtVt-csj.cjs} +2 -2
- package/dist/{run-BkpO4HyT.cjs.map → run-QtVt-csj.cjs.map} +1 -1
- package/dist/{run-DY-3ONFZ.cjs → run-fLBpH170.cjs} +2 -2
- package/dist/run-fLBpH170.cjs.map +1 -0
- package/dist/{snapshot-DJzr_LP8.cjs → snapshot-BTM3dE9L.cjs} +67 -26
- package/dist/snapshot-BTM3dE9L.cjs.map +1 -0
- package/dist/{snapshot-Cv2GHK1Y.js → snapshot-Bxlj-1OJ.js} +67 -26
- package/dist/snapshot-Bxlj-1OJ.js.map +1 -0
- package/dist/{status-BtXF2YAC.cjs → status-BxUqzCGT.cjs} +2 -2
- package/dist/{status-BtXF2YAC.cjs.map → status-BxUqzCGT.cjs.map} +1 -1
- package/dist/{status-DT1nKRUb.js → status-QnFiAJK0.js} +2 -2
- package/dist/{status-DT1nKRUb.js.map → status-QnFiAJK0.js.map} +1 -1
- package/dist/{studio-DDDkhrVO.cjs → studio-BeOQYXoh.cjs} +12 -7
- package/dist/studio-BeOQYXoh.cjs.map +1 -0
- package/dist/{studio-CwZBPZWN.js → studio-C2FsZ4zt.js} +12 -7
- package/dist/studio-C2FsZ4zt.js.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,5 +1,5 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-qbf5tadS.cjs");
|
|
2
|
-
const require_run = require("./run-
|
|
2
|
+
const require_run = require("./run-fLBpH170.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");
|
|
@@ -10,15 +10,19 @@ let node_fs = require("node:fs");
|
|
|
10
10
|
let _kubb_core = require("@kubb/core");
|
|
11
11
|
let _kubb_studio = require("@kubb/studio");
|
|
12
12
|
//#region src/runners/studio/ci.ts
|
|
13
|
-
function
|
|
13
|
+
function readGithubPullRequest(eventPath) {
|
|
14
14
|
if (!eventPath) return;
|
|
15
15
|
try {
|
|
16
16
|
const event = JSON.parse((0, node_fs.readFileSync)(eventPath, "utf8"));
|
|
17
|
-
return event.pull_request?.number ?
|
|
17
|
+
return event.pull_request?.number ? event.pull_request : void 0;
|
|
18
18
|
} catch {
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
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
|
+
}
|
|
22
26
|
/**
|
|
23
27
|
* Detects the CI provider from its environment variables and derives a stable identity from it.
|
|
24
28
|
* The GitHub row reproduces `gh:<repositoryId>:<prNumber>`, the identity `kubb-labs/action` has
|
|
@@ -26,21 +30,32 @@ function readGithubPullRequestNumber(eventPath) {
|
|
|
26
30
|
*/
|
|
27
31
|
function detectCi(env = node_process.default.env) {
|
|
28
32
|
if (env.GITHUB_ACTIONS) {
|
|
29
|
-
const
|
|
33
|
+
const pullRequest = readGithubPullRequest(env.GITHUB_EVENT_PATH);
|
|
30
34
|
const repositoryId = env.GITHUB_REPOSITORY_ID ?? env.GITHUB_REPOSITORY ?? "";
|
|
31
|
-
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;
|
|
32
38
|
return {
|
|
33
39
|
id: `gh:${repositoryId}:${scope}`,
|
|
34
|
-
name: `${env.GITHUB_REPOSITORY ?? "github"}#${scope}`,
|
|
35
|
-
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
|
|
36
46
|
};
|
|
37
47
|
}
|
|
38
48
|
if (env.GITLAB_CI) {
|
|
39
49
|
const scope = env.CI_MERGE_REQUEST_IID ?? env.CI_COMMIT_REF_SLUG ?? "";
|
|
50
|
+
const baseBranch = env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME;
|
|
40
51
|
return {
|
|
41
52
|
id: `gl:${env.CI_PROJECT_ID ?? ""}:${scope}`,
|
|
42
53
|
name: `${env.CI_PROJECT_PATH ?? "gitlab"}#${scope}`,
|
|
43
|
-
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
|
|
44
59
|
};
|
|
45
60
|
}
|
|
46
61
|
if (env.BITBUCKET_BUILD_NUMBER) {
|
|
@@ -115,13 +130,20 @@ function resolveToken(options) {
|
|
|
115
130
|
}
|
|
116
131
|
function resolveCiIdentity(options) {
|
|
117
132
|
const detected = detectCi();
|
|
118
|
-
|
|
133
|
+
const ci = options.id ? {
|
|
119
134
|
id: options.id,
|
|
120
135
|
name: detected?.name ?? options.id,
|
|
121
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
|
|
122
146
|
};
|
|
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
147
|
}
|
|
126
148
|
/** Rejects a bad `--timeout` up front instead of letting it reach `waitForJob` as NaN or <= 0. */
|
|
127
149
|
function resolveTimeoutMs(options) {
|
|
@@ -137,7 +159,7 @@ function assertSecureStudioUrl(studioUrl) {
|
|
|
137
159
|
function absoluteUrl(studioUrl, path) {
|
|
138
160
|
return new URL(path, `${studioUrl}/`).toString();
|
|
139
161
|
}
|
|
140
|
-
function toResult(studioUrl, snapshot, agentSlug) {
|
|
162
|
+
function toResult(studioUrl, snapshot, agentSlug, ci) {
|
|
141
163
|
return {
|
|
142
164
|
id: snapshot.id,
|
|
143
165
|
name: snapshot.name,
|
|
@@ -147,25 +169,33 @@ function toResult(studioUrl, snapshot, agentSlug) {
|
|
|
147
169
|
snapshotIdUrl: absoluteUrl(studioUrl, snapshot.snapshotIdUrl),
|
|
148
170
|
expiresAt: snapshot.expiresAt,
|
|
149
171
|
agentUrl: absoluteUrl(studioUrl, `/agents/${agentSlug}`),
|
|
150
|
-
changes: snapshot.changes
|
|
172
|
+
changes: snapshot.changes,
|
|
173
|
+
branchChanges: snapshot.branchChanges && ci.base ? {
|
|
174
|
+
...snapshot.branchChanges,
|
|
175
|
+
branch: ci.base.branch
|
|
176
|
+
} : void 0
|
|
151
177
|
};
|
|
152
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
|
+
}
|
|
153
184
|
/** One summary line: how many files changed, and since which run. */
|
|
154
185
|
function formatChanges(changes) {
|
|
155
186
|
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}`;
|
|
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`;
|
|
163
192
|
}
|
|
164
193
|
function printSummary(result) {
|
|
165
194
|
require_output.logBlock([
|
|
166
195
|
`${(0, node_util.styleText)("dim", "Package".padEnd(10))} ${result.name ?? "(unnamed)"}@${result.version ?? "0.0.0"}`,
|
|
167
196
|
`${(0, node_util.styleText)("dim", "Tarball".padEnd(10))} ${(0, node_util.styleText)("cyan", result.url)}`,
|
|
168
197
|
`${(0, node_util.styleText)("dim", "Agent".padEnd(10))} ${result.agentUrl}`,
|
|
198
|
+
...result.branchChanges ? [`${(0, node_util.styleText)("dim", "Branch".padEnd(10))} ${formatBranchChanges(result.branchChanges)}`] : [],
|
|
169
199
|
...result.changes ? [`${(0, node_util.styleText)("dim", "Changes".padEnd(10))} ${formatChanges(result.changes)}`] : [],
|
|
170
200
|
`${(0, node_util.styleText)("dim", "Expires".padEnd(10))} ${result.expiresAt}`
|
|
171
201
|
]);
|
|
@@ -198,7 +228,7 @@ async function snapshot(options) {
|
|
|
198
228
|
});
|
|
199
229
|
const { promise: ready, resolve: markReady } = Promise.withResolvers();
|
|
200
230
|
const shutdown = new AbortController();
|
|
201
|
-
const
|
|
231
|
+
const connection = (0, _kubb_studio.runConnection)({
|
|
202
232
|
credentials: { token: agent.token },
|
|
203
233
|
signal: shutdown.signal,
|
|
204
234
|
clientOptions: () => ({
|
|
@@ -218,7 +248,11 @@ async function snapshot(options) {
|
|
|
218
248
|
}
|
|
219
249
|
}),
|
|
220
250
|
onTokenRejected: ({ error }) => Promise.reject(error)
|
|
221
|
-
})
|
|
251
|
+
});
|
|
252
|
+
const connectionLost = new AbortController();
|
|
253
|
+
const connectionEnded = /* @__PURE__ */ new Error("The Kubb Studio connection ended before the snapshot finished");
|
|
254
|
+
connection.then(() => connectionLost.abort(connectionEnded), (error) => connectionLost.abort(error));
|
|
255
|
+
const lost = connection.then(() => Promise.reject(connectionEnded), (error) => Promise.reject(error));
|
|
222
256
|
lost.catch(() => {});
|
|
223
257
|
try {
|
|
224
258
|
let readyTimeout;
|
|
@@ -234,6 +268,8 @@ async function snapshot(options) {
|
|
|
234
268
|
clearTimeout(readyTimeout);
|
|
235
269
|
}
|
|
236
270
|
step("Creating snapshot job");
|
|
271
|
+
const snapshotDeadline = Date.now() + timeoutMs;
|
|
272
|
+
const snapshotTimeoutMs = () => Math.max(snapshotDeadline - Date.now(), 1);
|
|
237
273
|
const job = await (0, _kubb_studio.createJob)({
|
|
238
274
|
studioUrl: options.studioUrl,
|
|
239
275
|
token,
|
|
@@ -241,18 +277,22 @@ async function snapshot(options) {
|
|
|
241
277
|
agentId: agent.id,
|
|
242
278
|
name,
|
|
243
279
|
version: packageVersion,
|
|
244
|
-
commit: ci.commit
|
|
280
|
+
commit: ci.commit,
|
|
281
|
+
baseId: ci.base?.id,
|
|
282
|
+
timeoutMs: snapshotTimeoutMs(),
|
|
283
|
+
signal: connectionLost.signal
|
|
245
284
|
});
|
|
246
285
|
step(`Snapshot job queued: ${job.id}`);
|
|
247
286
|
const finished = await Promise.race([(0, _kubb_studio.waitForJob)({
|
|
248
287
|
studioUrl: options.studioUrl,
|
|
249
288
|
token,
|
|
250
289
|
id: job.id,
|
|
251
|
-
timeoutMs
|
|
290
|
+
timeoutMs: snapshotTimeoutMs(),
|
|
291
|
+
signal: connectionLost.signal
|
|
252
292
|
}), lost]);
|
|
253
293
|
if (finished.status === "failed") throw new Error(finished.error ?? "Snapshot job failed");
|
|
254
294
|
if (!finished.snapshot) throw new Error("Snapshot job succeeded without a snapshot");
|
|
255
|
-
const result = toResult(options.studioUrl, finished.snapshot, agent.slug);
|
|
295
|
+
const result = toResult(options.studioUrl, finished.snapshot, agent.slug, ci);
|
|
256
296
|
step("Snapshot published");
|
|
257
297
|
if (options.json) console.log(JSON.stringify(result));
|
|
258
298
|
if (!options.json) printSummary(result);
|
|
@@ -269,6 +309,7 @@ const runner = async ({ values }) => {
|
|
|
269
309
|
...require_run.createStudioOptions(values),
|
|
270
310
|
token: values.token,
|
|
271
311
|
id: values.id,
|
|
312
|
+
baseId: values.baseId,
|
|
272
313
|
name: values.name,
|
|
273
314
|
packageVersion: values.packageVersion,
|
|
274
315
|
timeout: values.timeout,
|
|
@@ -279,4 +320,4 @@ const runner = async ({ values }) => {
|
|
|
279
320
|
//#endregion
|
|
280
321
|
exports.runner = runner;
|
|
281
322
|
|
|
282
|
-
//# sourceMappingURL=snapshot-
|
|
323
|
+
//# sourceMappingURL=snapshot-BTM3dE9L.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-BTM3dE9L.cjs","names":["readFileSync","process","join","exists","read","dirname","process","styleText","loadConfigs","logLevelMap","createPlainLogger","createAgent","machineTokenFrom","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 { 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\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 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 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
|
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-DgJoQeWU.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";
|
|
@@ -9,15 +9,19 @@ import { readFileSync } from "node:fs";
|
|
|
9
9
|
import { cliReporter, logLevel } from "@kubb/core";
|
|
10
10
|
import { createAgent, createJob, machineTokenFrom, runConnection, waitForJob } from "@kubb/studio";
|
|
11
11
|
//#region src/runners/studio/ci.ts
|
|
12
|
-
function
|
|
12
|
+
function readGithubPullRequest(eventPath) {
|
|
13
13
|
if (!eventPath) return;
|
|
14
14
|
try {
|
|
15
15
|
const event = JSON.parse(readFileSync(eventPath, "utf8"));
|
|
16
|
-
return event.pull_request?.number ?
|
|
16
|
+
return event.pull_request?.number ? event.pull_request : void 0;
|
|
17
17
|
} catch {
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
/** Reproduces GitLab's `CI_COMMIT_REF_SLUG` for a branch it gives no slug of, like a merge request's target. */
|
|
22
|
+
function gitlabRefSlug(ref) {
|
|
23
|
+
return ref.toLowerCase().replace(/[^a-z0-9]/gu, "-").slice(0, 63).replace(/^-+|-+$/g, "");
|
|
24
|
+
}
|
|
21
25
|
/**
|
|
22
26
|
* Detects the CI provider from its environment variables and derives a stable identity from it.
|
|
23
27
|
* The GitHub row reproduces `gh:<repositoryId>:<prNumber>`, the identity `kubb-labs/action` has
|
|
@@ -25,21 +29,32 @@ function readGithubPullRequestNumber(eventPath) {
|
|
|
25
29
|
*/
|
|
26
30
|
function detectCi(env = process.env) {
|
|
27
31
|
if (env.GITHUB_ACTIONS) {
|
|
28
|
-
const
|
|
32
|
+
const pullRequest = readGithubPullRequest(env.GITHUB_EVENT_PATH);
|
|
29
33
|
const repositoryId = env.GITHUB_REPOSITORY_ID ?? env.GITHUB_REPOSITORY ?? "";
|
|
30
|
-
const
|
|
34
|
+
const branch = env.GITHUB_REF?.startsWith("refs/heads/") ? env.GITHUB_REF.slice(11) : void 0;
|
|
35
|
+
const scope = pullRequest?.number ?? (branch ? `refs/heads/${branch}` : env.GITHUB_RUN_ID) ?? "";
|
|
36
|
+
const baseBranch = pullRequest?.base?.ref;
|
|
31
37
|
return {
|
|
32
38
|
id: `gh:${repositoryId}:${scope}`,
|
|
33
|
-
name: `${env.GITHUB_REPOSITORY ?? "github"}#${scope}`,
|
|
34
|
-
commit: env.GITHUB_SHA
|
|
39
|
+
name: `${env.GITHUB_REPOSITORY ?? "github"}#${pullRequest?.number ?? branch ?? scope}`,
|
|
40
|
+
commit: pullRequest?.head?.sha ?? env.GITHUB_SHA,
|
|
41
|
+
base: baseBranch ? {
|
|
42
|
+
branch: baseBranch,
|
|
43
|
+
id: `gh:${repositoryId}:refs/heads/${baseBranch}`
|
|
44
|
+
} : void 0
|
|
35
45
|
};
|
|
36
46
|
}
|
|
37
47
|
if (env.GITLAB_CI) {
|
|
38
48
|
const scope = env.CI_MERGE_REQUEST_IID ?? env.CI_COMMIT_REF_SLUG ?? "";
|
|
49
|
+
const baseBranch = env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME;
|
|
39
50
|
return {
|
|
40
51
|
id: `gl:${env.CI_PROJECT_ID ?? ""}:${scope}`,
|
|
41
52
|
name: `${env.CI_PROJECT_PATH ?? "gitlab"}#${scope}`,
|
|
42
|
-
commit: env.CI_COMMIT_SHA
|
|
53
|
+
commit: env.CI_MERGE_REQUEST_SOURCE_BRANCH_SHA || env.CI_COMMIT_SHA,
|
|
54
|
+
base: baseBranch ? {
|
|
55
|
+
branch: baseBranch,
|
|
56
|
+
id: `gl:${env.CI_PROJECT_ID ?? ""}:${gitlabRefSlug(baseBranch)}`
|
|
57
|
+
} : void 0
|
|
43
58
|
};
|
|
44
59
|
}
|
|
45
60
|
if (env.BITBUCKET_BUILD_NUMBER) {
|
|
@@ -114,13 +129,20 @@ function resolveToken(options) {
|
|
|
114
129
|
}
|
|
115
130
|
function resolveCiIdentity(options) {
|
|
116
131
|
const detected = detectCi();
|
|
117
|
-
|
|
132
|
+
const ci = options.id ? {
|
|
118
133
|
id: options.id,
|
|
119
134
|
name: detected?.name ?? options.id,
|
|
120
135
|
commit: detected?.commit
|
|
136
|
+
} : detected;
|
|
137
|
+
if (!ci) throw new Error("Could not detect a supported CI provider (GitHub Actions, GitLab CI, Bitbucket Pipelines, CircleCI). Pass --id.");
|
|
138
|
+
const base = options.baseId ? {
|
|
139
|
+
branch: options.baseId,
|
|
140
|
+
id: options.baseId
|
|
141
|
+
} : ci.base;
|
|
142
|
+
return {
|
|
143
|
+
...ci,
|
|
144
|
+
base: base?.id === ci.id ? void 0 : base
|
|
121
145
|
};
|
|
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
146
|
}
|
|
125
147
|
/** Rejects a bad `--timeout` up front instead of letting it reach `waitForJob` as NaN or <= 0. */
|
|
126
148
|
function resolveTimeoutMs(options) {
|
|
@@ -136,7 +158,7 @@ function assertSecureStudioUrl(studioUrl) {
|
|
|
136
158
|
function absoluteUrl(studioUrl, path) {
|
|
137
159
|
return new URL(path, `${studioUrl}/`).toString();
|
|
138
160
|
}
|
|
139
|
-
function toResult(studioUrl, snapshot, agentSlug) {
|
|
161
|
+
function toResult(studioUrl, snapshot, agentSlug, ci) {
|
|
140
162
|
return {
|
|
141
163
|
id: snapshot.id,
|
|
142
164
|
name: snapshot.name,
|
|
@@ -146,25 +168,33 @@ function toResult(studioUrl, snapshot, agentSlug) {
|
|
|
146
168
|
snapshotIdUrl: absoluteUrl(studioUrl, snapshot.snapshotIdUrl),
|
|
147
169
|
expiresAt: snapshot.expiresAt,
|
|
148
170
|
agentUrl: absoluteUrl(studioUrl, `/agents/${agentSlug}`),
|
|
149
|
-
changes: snapshot.changes
|
|
171
|
+
changes: snapshot.changes,
|
|
172
|
+
branchChanges: snapshot.branchChanges && ci.base ? {
|
|
173
|
+
...snapshot.branchChanges,
|
|
174
|
+
branch: ci.base.branch
|
|
175
|
+
} : void 0
|
|
150
176
|
};
|
|
151
177
|
}
|
|
178
|
+
/** How many files differ, `against` what. */
|
|
179
|
+
function describeChanges(changes, against) {
|
|
180
|
+
const { added, changed, removed } = changes;
|
|
181
|
+
return added.length + changed.length + removed.length ? `${added.length} added, ${changed.length} changed, ${removed.length} removed ${against}` : `No changes ${against}`;
|
|
182
|
+
}
|
|
152
183
|
/** One summary line: how many files changed, and since which run. */
|
|
153
184
|
function formatChanges(changes) {
|
|
154
185
|
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}`;
|
|
186
|
+
return describeChanges(changes, `since ${changes.base.commit?.slice(0, 7) ?? changes.base.createdAt}`);
|
|
187
|
+
}
|
|
188
|
+
/** One summary line: how the snapshot differs from the base branch's latest one. */
|
|
189
|
+
function formatBranchChanges(changes) {
|
|
190
|
+
return changes.base ? describeChanges(changes, `against ${changes.branch}`) : `No snapshot of ${changes.branch} to compare with`;
|
|
162
191
|
}
|
|
163
192
|
function printSummary(result) {
|
|
164
193
|
logBlock([
|
|
165
194
|
`${styleText("dim", "Package".padEnd(10))} ${result.name ?? "(unnamed)"}@${result.version ?? "0.0.0"}`,
|
|
166
195
|
`${styleText("dim", "Tarball".padEnd(10))} ${styleText("cyan", result.url)}`,
|
|
167
196
|
`${styleText("dim", "Agent".padEnd(10))} ${result.agentUrl}`,
|
|
197
|
+
...result.branchChanges ? [`${styleText("dim", "Branch".padEnd(10))} ${formatBranchChanges(result.branchChanges)}`] : [],
|
|
168
198
|
...result.changes ? [`${styleText("dim", "Changes".padEnd(10))} ${formatChanges(result.changes)}`] : [],
|
|
169
199
|
`${styleText("dim", "Expires".padEnd(10))} ${result.expiresAt}`
|
|
170
200
|
]);
|
|
@@ -197,7 +227,7 @@ async function snapshot(options) {
|
|
|
197
227
|
});
|
|
198
228
|
const { promise: ready, resolve: markReady } = Promise.withResolvers();
|
|
199
229
|
const shutdown = new AbortController();
|
|
200
|
-
const
|
|
230
|
+
const connection = runConnection({
|
|
201
231
|
credentials: { token: agent.token },
|
|
202
232
|
signal: shutdown.signal,
|
|
203
233
|
clientOptions: () => ({
|
|
@@ -217,7 +247,11 @@ async function snapshot(options) {
|
|
|
217
247
|
}
|
|
218
248
|
}),
|
|
219
249
|
onTokenRejected: ({ error }) => Promise.reject(error)
|
|
220
|
-
})
|
|
250
|
+
});
|
|
251
|
+
const connectionLost = new AbortController();
|
|
252
|
+
const connectionEnded = /* @__PURE__ */ new Error("The Kubb Studio connection ended before the snapshot finished");
|
|
253
|
+
connection.then(() => connectionLost.abort(connectionEnded), (error) => connectionLost.abort(error));
|
|
254
|
+
const lost = connection.then(() => Promise.reject(connectionEnded), (error) => Promise.reject(error));
|
|
221
255
|
lost.catch(() => {});
|
|
222
256
|
try {
|
|
223
257
|
let readyTimeout;
|
|
@@ -233,6 +267,8 @@ async function snapshot(options) {
|
|
|
233
267
|
clearTimeout(readyTimeout);
|
|
234
268
|
}
|
|
235
269
|
step("Creating snapshot job");
|
|
270
|
+
const snapshotDeadline = Date.now() + timeoutMs;
|
|
271
|
+
const snapshotTimeoutMs = () => Math.max(snapshotDeadline - Date.now(), 1);
|
|
236
272
|
const job = await createJob({
|
|
237
273
|
studioUrl: options.studioUrl,
|
|
238
274
|
token,
|
|
@@ -240,18 +276,22 @@ async function snapshot(options) {
|
|
|
240
276
|
agentId: agent.id,
|
|
241
277
|
name,
|
|
242
278
|
version: packageVersion,
|
|
243
|
-
commit: ci.commit
|
|
279
|
+
commit: ci.commit,
|
|
280
|
+
baseId: ci.base?.id,
|
|
281
|
+
timeoutMs: snapshotTimeoutMs(),
|
|
282
|
+
signal: connectionLost.signal
|
|
244
283
|
});
|
|
245
284
|
step(`Snapshot job queued: ${job.id}`);
|
|
246
285
|
const finished = await Promise.race([waitForJob({
|
|
247
286
|
studioUrl: options.studioUrl,
|
|
248
287
|
token,
|
|
249
288
|
id: job.id,
|
|
250
|
-
timeoutMs
|
|
289
|
+
timeoutMs: snapshotTimeoutMs(),
|
|
290
|
+
signal: connectionLost.signal
|
|
251
291
|
}), lost]);
|
|
252
292
|
if (finished.status === "failed") throw new Error(finished.error ?? "Snapshot job failed");
|
|
253
293
|
if (!finished.snapshot) throw new Error("Snapshot job succeeded without a snapshot");
|
|
254
|
-
const result = toResult(options.studioUrl, finished.snapshot, agent.slug);
|
|
294
|
+
const result = toResult(options.studioUrl, finished.snapshot, agent.slug, ci);
|
|
255
295
|
step("Snapshot published");
|
|
256
296
|
if (options.json) console.log(JSON.stringify(result));
|
|
257
297
|
if (!options.json) printSummary(result);
|
|
@@ -268,6 +308,7 @@ const runner = async ({ values }) => {
|
|
|
268
308
|
...createStudioOptions(values),
|
|
269
309
|
token: values.token,
|
|
270
310
|
id: values.id,
|
|
311
|
+
baseId: values.baseId,
|
|
271
312
|
name: values.name,
|
|
272
313
|
packageVersion: values.packageVersion,
|
|
273
314
|
timeout: values.timeout,
|
|
@@ -278,4 +319,4 @@ const runner = async ({ values }) => {
|
|
|
278
319
|
//#endregion
|
|
279
320
|
export { runner };
|
|
280
321
|
|
|
281
|
-
//# sourceMappingURL=snapshot-
|
|
322
|
+
//# sourceMappingURL=snapshot-Bxlj-1OJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-Bxlj-1OJ.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 { 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\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 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 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-fLBpH170.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-BxUqzCGT.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status-
|
|
1
|
+
{"version":3,"file":"status-BxUqzCGT.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-DgJoQeWU.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-QnFiAJK0.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status-
|
|
1
|
+
{"version":3,"file":"status-QnFiAJK0.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 = (0, gunshi.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 = (0, gunshi.define)({
|
|
|
138
143
|
...require_shared.logLevelArg
|
|
139
144
|
},
|
|
140
145
|
async run(ctx) {
|
|
141
|
-
const { runner } = await Promise.resolve().then(() => require("./connect-
|
|
146
|
+
const { runner } = await Promise.resolve().then(() => require("./connect-c9W1razJ.cjs"));
|
|
142
147
|
await runner(ctx);
|
|
143
148
|
},
|
|
144
149
|
subCommands: {
|
|
145
|
-
connect: (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./connect-
|
|
146
|
-
login: (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./login-
|
|
147
|
-
logout: (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./logout-
|
|
148
|
-
status: (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./status-
|
|
149
|
-
snapshot: (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./snapshot-
|
|
150
|
+
connect: (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./connect-c9W1razJ.cjs"))).runner, definition$5),
|
|
151
|
+
login: (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./login-DICKtsMS.cjs"))).runner, definition$4),
|
|
152
|
+
logout: (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./logout-Cq_SjOQf.cjs"))).runner, definition$3),
|
|
153
|
+
status: (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./status-BxUqzCGT.cjs"))).runner, definition$1),
|
|
154
|
+
snapshot: (0, gunshi.lazy)(async () => (await Promise.resolve().then(() => require("./snapshot-BTM3dE9L.cjs"))).runner, definition$2)
|
|
150
155
|
}
|
|
151
156
|
});
|
|
152
157
|
//#endregion
|
|
153
158
|
exports.definition = definition;
|
|
154
159
|
|
|
155
|
-
//# sourceMappingURL=studio-
|
|
160
|
+
//# sourceMappingURL=studio-BeOQYXoh.cjs.map
|