tegami 1.1.3 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +3 -3
- package/dist/{error-BhMYq9iW.js → error-CAsrGb6e.js} +6 -1
- package/dist/{generate-Bg86OJP4.js → generate-Cnd8RiKO.js} +1 -1
- package/dist/generators/simple.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -4
- package/dist/{npm-CaBYeOeV.js → npm-4iA03RvC.js} +8 -174
- package/dist/plugins/cargo.d.ts +1 -1
- package/dist/plugins/cargo.js +2 -2
- package/dist/plugins/git.d.ts +1 -1
- package/dist/plugins/git.js +1 -1
- package/dist/plugins/github.d.ts +3 -47
- package/dist/plugins/github.js +34 -46
- package/dist/plugins/gitlab.d.ts +3 -47
- package/dist/plugins/gitlab.js +41 -49
- package/dist/plugins/go.d.ts +1 -1
- package/dist/plugins/go.js +2 -2
- package/dist/providers/npm.d.ts +1 -1
- package/dist/providers/npm.js +1 -1
- package/dist/{draft-CzUiQasJ.js → publish-Bt3e1RPs.js} +188 -6
- package/dist/{types-DEyZ2r-2.d.ts → types-BbwOrNZ2.d.ts} +8 -3
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js +2 -2
- package/dist/version-request-BQwP7EWa.d.ts +57 -0
- package/dist/version-request-DvWVAYj2.js +427 -0
- package/package.json +1 -1
- package/dist/version-request-DlLpLLK3.js +0 -445
package/dist/plugins/gitlab.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { A as WorkspacePackage, b as TegamiContext,
|
|
1
|
+
import { A as WorkspacePackage, b as TegamiContext, s as TegamiPlugin, t as Awaitable, v as PublishPlan } from "../types-BbwOrNZ2.js";
|
|
2
2
|
import { GitPluginOptions } from "./git.js";
|
|
3
|
+
import { t as VersionRequestOptions } from "../version-request-BQwP7EWa.js";
|
|
3
4
|
|
|
4
5
|
//#region src/plugins/gitlab.d.ts
|
|
5
6
|
interface GitlabRelease {
|
|
@@ -8,51 +9,6 @@ interface GitlabRelease {
|
|
|
8
9
|
/** Release notes */
|
|
9
10
|
notes?: string;
|
|
10
11
|
}
|
|
11
|
-
interface VersionMergeRequest {
|
|
12
|
-
/** Merge request title. */
|
|
13
|
-
title?: string;
|
|
14
|
-
/** Merge request body. */
|
|
15
|
-
body?: string;
|
|
16
|
-
}
|
|
17
|
-
interface VersionMergeRequestOptions {
|
|
18
|
-
/**
|
|
19
|
-
* Create the MR even outside of CI.
|
|
20
|
-
*
|
|
21
|
-
* @default false
|
|
22
|
-
*/
|
|
23
|
-
forceCreate?: boolean;
|
|
24
|
-
/**
|
|
25
|
-
* Merge request branch. Publish group MRs are created under `<branch>/`.
|
|
26
|
-
*
|
|
27
|
-
* @default "tegami/version-packages"
|
|
28
|
-
*/
|
|
29
|
-
branch?: string;
|
|
30
|
-
/**
|
|
31
|
-
* Merge request base branch.
|
|
32
|
-
*
|
|
33
|
-
* @default "main"
|
|
34
|
-
*/
|
|
35
|
-
base?: string;
|
|
36
|
-
/**
|
|
37
|
-
* Publish groups to split into separate version MRs, each entry is a package (or a list of
|
|
38
|
-
* packages) to version & publish together. Packages not covered by any group are collected
|
|
39
|
-
* into an extra "unlisted packages" MR.
|
|
40
|
-
*
|
|
41
|
-
* Merging a group MR publishes only its members, the remaining MRs are re-synced on every
|
|
42
|
-
* publish run until all of them are merged & published.
|
|
43
|
-
*/
|
|
44
|
-
groups?: (string | string[])[];
|
|
45
|
-
/**
|
|
46
|
-
* Override details for a version MR.
|
|
47
|
-
*
|
|
48
|
-
* Only called at version-time: publish group MRs re-synced at publish-time keep the stored
|
|
49
|
-
* title and use a default body.
|
|
50
|
-
*/
|
|
51
|
-
create?: (this: TegamiContext, opts: {
|
|
52
|
-
draft: Draft;
|
|
53
|
-
publishGroup?: string[];
|
|
54
|
-
}) => Awaitable<VersionMergeRequest>;
|
|
55
|
-
}
|
|
56
12
|
/** Options for creating GitLab releases after a successful publish. */
|
|
57
13
|
interface GitLabPluginOptions extends GitPluginOptions {
|
|
58
14
|
/** GitLab repository. */
|
|
@@ -91,7 +47,7 @@ interface GitLabPluginOptions extends GitPluginOptions {
|
|
|
91
47
|
*
|
|
92
48
|
* Defaults to enabled in CI and disabled locally.
|
|
93
49
|
*/
|
|
94
|
-
versionMr?:
|
|
50
|
+
versionMr?: VersionRequestOptions | false;
|
|
95
51
|
}
|
|
96
52
|
/** Create GitLab releases for successfully published packages after the whole plan succeeds. */
|
|
97
53
|
declare function gitlab(options?: GitLabPluginOptions): TegamiPlugin[];
|
package/dist/plugins/gitlab.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { i as formatPackageVersion, r as formatNpmDistTag } from "../semver-EKJ8yK5U.js";
|
|
2
|
-
import { t as changelogFilename } from "../generate-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { t as changelogFilename } from "../generate-Cnd8RiKO.js";
|
|
3
|
+
import { c as joinPath, n as execFailure, o as cached, r as fetchFailure, s as isCI } from "../error-CAsrGb6e.js";
|
|
4
|
+
import { a as createDraft, l as readChangelogEntries } from "../publish-Bt3e1RPs.js";
|
|
5
5
|
import { git } from "./git.js";
|
|
6
|
-
import { t as onVersionRequest } from "../version-request-
|
|
6
|
+
import { t as onVersionRequest } from "../version-request-DvWVAYj2.js";
|
|
7
7
|
import { readFile, writeFile } from "node:fs/promises";
|
|
8
8
|
import { basename, join, relative, resolve } from "node:path";
|
|
9
9
|
import { x } from "tinyexec";
|
|
@@ -31,12 +31,12 @@ async function releaseExistsByTag(repo, tag, options = {}) {
|
|
|
31
31
|
const { encodedProjectPath } = parseGitLabRepo(repo);
|
|
32
32
|
const response = await gitlabRequest(options, `/projects/${encodedProjectPath}/releases/${encodeURIComponent(tag)}`, { method: "HEAD" });
|
|
33
33
|
if (response.status === 404) return false;
|
|
34
|
-
if (!response.ok) throw
|
|
34
|
+
if (!response.ok) throw await fetchFailure(`Failed to get GitLab release for ${tag}`, response);
|
|
35
35
|
return true;
|
|
36
36
|
}
|
|
37
37
|
async function createRelease(repo, options) {
|
|
38
38
|
const { encodedProjectPath } = parseGitLabRepo(repo);
|
|
39
|
-
|
|
39
|
+
const response = await gitlabRequest(options, `/projects/${encodedProjectPath}/releases`, {
|
|
40
40
|
method: "POST",
|
|
41
41
|
headers: { "Content-Type": "application/json" },
|
|
42
42
|
body: JSON.stringify({
|
|
@@ -44,7 +44,8 @@ async function createRelease(repo, options) {
|
|
|
44
44
|
name: options.title,
|
|
45
45
|
description: options.notes
|
|
46
46
|
})
|
|
47
|
-
})
|
|
47
|
+
});
|
|
48
|
+
if (!response.ok) throw await fetchFailure(`Failed to create GitLab release for ${options.tag}`, response);
|
|
48
49
|
}
|
|
49
50
|
async function findOpenMergeRequest(repo, options) {
|
|
50
51
|
const { encodedProjectPath } = parseGitLabRepo(repo);
|
|
@@ -54,12 +55,12 @@ async function findOpenMergeRequest(repo, options) {
|
|
|
54
55
|
});
|
|
55
56
|
if (options.base) params.set("target_branch", options.base);
|
|
56
57
|
const response = await gitlabRequest(options, `/projects/${encodedProjectPath}/merge_requests?${params}`);
|
|
57
|
-
if (!response.ok) throw
|
|
58
|
+
if (!response.ok) throw await fetchFailure("Failed to check for an existing version merge request", response);
|
|
58
59
|
return (await response.json())[0]?.iid;
|
|
59
60
|
}
|
|
60
61
|
async function updateMergeRequest(repo, number, options) {
|
|
61
62
|
const { encodedProjectPath } = parseGitLabRepo(repo);
|
|
62
|
-
|
|
63
|
+
const response = await gitlabRequest(options, `/projects/${encodedProjectPath}/merge_requests/${number}`, {
|
|
63
64
|
method: "PUT",
|
|
64
65
|
headers: { "Content-Type": "application/json" },
|
|
65
66
|
body: JSON.stringify({
|
|
@@ -67,11 +68,12 @@ async function updateMergeRequest(repo, number, options) {
|
|
|
67
68
|
description: options.body,
|
|
68
69
|
target_branch: options.base
|
|
69
70
|
})
|
|
70
|
-
})
|
|
71
|
+
});
|
|
72
|
+
if (!response.ok) throw await fetchFailure("Failed to update the version merge request", response);
|
|
71
73
|
}
|
|
72
74
|
async function createMergeRequest(repo, options) {
|
|
73
75
|
const { encodedProjectPath } = parseGitLabRepo(repo);
|
|
74
|
-
|
|
76
|
+
const response = await gitlabRequest(options, `/projects/${encodedProjectPath}/merge_requests`, {
|
|
75
77
|
method: "POST",
|
|
76
78
|
headers: { "Content-Type": "application/json" },
|
|
77
79
|
body: JSON.stringify({
|
|
@@ -80,12 +82,13 @@ async function createMergeRequest(repo, options) {
|
|
|
80
82
|
source_branch: options.head,
|
|
81
83
|
target_branch: options.base
|
|
82
84
|
})
|
|
83
|
-
})
|
|
85
|
+
});
|
|
86
|
+
if (!response.ok) throw await fetchFailure("Failed to create the version merge request", response);
|
|
84
87
|
}
|
|
85
88
|
async function getMergeRequest(repo, number, options = {}) {
|
|
86
89
|
const { encodedProjectPath } = parseGitLabRepo(repo);
|
|
87
90
|
const response = await gitlabRequest(options, `/projects/${encodedProjectPath}/merge_requests/${number}`);
|
|
88
|
-
if (!response.ok) throw
|
|
91
|
+
if (!response.ok) throw await fetchFailure(`Failed to resolve merge request !${number}`, response);
|
|
89
92
|
const data = await response.json();
|
|
90
93
|
let sourceProjectPath;
|
|
91
94
|
if (data.source_project_id !== void 0) {
|
|
@@ -102,7 +105,7 @@ async function getMergeRequest(repo, number, options = {}) {
|
|
|
102
105
|
async function listMergeRequestsForCommit(repo, commitSha, options = {}) {
|
|
103
106
|
const { encodedProjectPath } = parseGitLabRepo(repo);
|
|
104
107
|
const response = await gitlabRequest(options, `/projects/${encodedProjectPath}/repository/commits/${commitSha}/merge_requests`);
|
|
105
|
-
if (!response.ok) throw
|
|
108
|
+
if (!response.ok) throw await fetchFailure(`Failed to list merge requests for commit ${commitSha.slice(0, 7)}`, response);
|
|
106
109
|
return (await response.json()).map((mergeRequest) => ({
|
|
107
110
|
number: mergeRequest.iid,
|
|
108
111
|
title: mergeRequest.title,
|
|
@@ -114,7 +117,7 @@ async function findMergeRequestCommentByPrefix(repo, mergeRequestNumber, prefix,
|
|
|
114
117
|
let page = 1;
|
|
115
118
|
while (true) {
|
|
116
119
|
const response = await gitlabRequest(options, `/projects/${encodedProjectPath}/merge_requests/${mergeRequestNumber}/notes?per_page=100&page=${page}`);
|
|
117
|
-
if (!response.ok) throw
|
|
120
|
+
if (!response.ok) throw await fetchFailure("Failed to list merge request comments", response);
|
|
118
121
|
const batch = await response.json();
|
|
119
122
|
if (batch.length === 0) break;
|
|
120
123
|
const comment = batch.find((comment) => comment.body.startsWith(prefix));
|
|
@@ -125,19 +128,21 @@ async function findMergeRequestCommentByPrefix(repo, mergeRequestNumber, prefix,
|
|
|
125
128
|
}
|
|
126
129
|
async function updateMergeRequestComment(repo, mergeRequestNumber, commentId, body, options = {}) {
|
|
127
130
|
const { encodedProjectPath } = parseGitLabRepo(repo);
|
|
128
|
-
|
|
131
|
+
const response = await gitlabRequest(options, `/projects/${encodedProjectPath}/merge_requests/${mergeRequestNumber}/notes/${commentId}`, {
|
|
129
132
|
method: "PUT",
|
|
130
133
|
headers: { "Content-Type": "application/json" },
|
|
131
134
|
body: JSON.stringify({ body })
|
|
132
|
-
})
|
|
135
|
+
});
|
|
136
|
+
if (!response.ok) throw await fetchFailure("Failed to update merge request comment", response);
|
|
133
137
|
}
|
|
134
138
|
async function createMergeRequestComment(repo, mergeRequestNumber, body, options = {}) {
|
|
135
139
|
const { encodedProjectPath } = parseGitLabRepo(repo);
|
|
136
|
-
|
|
140
|
+
const response = await gitlabRequest(options, `/projects/${encodedProjectPath}/merge_requests/${mergeRequestNumber}/notes`, {
|
|
137
141
|
method: "POST",
|
|
138
142
|
headers: { "Content-Type": "application/json" },
|
|
139
143
|
body: JSON.stringify({ body })
|
|
140
|
-
})
|
|
144
|
+
});
|
|
145
|
+
if (!response.ok) throw await fetchFailure("Failed to create merge request comment", response);
|
|
141
146
|
}
|
|
142
147
|
//#endregion
|
|
143
148
|
//#region src/plugins/gitlab/cli.ts
|
|
@@ -311,38 +316,36 @@ function gitlab(options = {}) {
|
|
|
311
316
|
}
|
|
312
317
|
const versionRequests = onVersionRequest({
|
|
313
318
|
name: "gitlab",
|
|
314
|
-
summary: "Merge this MR to publish the versioned packages.",
|
|
315
319
|
options: options.versionMr,
|
|
316
|
-
|
|
320
|
+
canCreate(context) {
|
|
317
321
|
const { repo, token } = context.gitlab ?? {};
|
|
318
322
|
return Boolean(repo && token);
|
|
319
323
|
},
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
324
|
+
async upsert(context, request, update) {
|
|
325
|
+
const repo = context.gitlab.repo;
|
|
326
|
+
const api = gitLabApiOptions(context.gitlab);
|
|
327
|
+
const openMr = await findOpenMergeRequest(repo, {
|
|
328
|
+
head: request.head,
|
|
329
|
+
base: request.base,
|
|
330
|
+
...api
|
|
325
331
|
});
|
|
326
|
-
|
|
327
|
-
create(context, request) {
|
|
328
|
-
return createMergeRequest(context.gitlab.repo, {
|
|
332
|
+
if (openMr === void 0) await createMergeRequest(repo, {
|
|
329
333
|
title: request.title,
|
|
330
334
|
body: request.body,
|
|
331
335
|
head: request.head,
|
|
332
336
|
base: request.base,
|
|
333
|
-
...
|
|
337
|
+
...api
|
|
334
338
|
});
|
|
335
|
-
|
|
336
|
-
update(context, number, request) {
|
|
337
|
-
return updateMergeRequest(context.gitlab.repo, number, {
|
|
339
|
+
else if (update) await updateMergeRequest(repo, openMr, {
|
|
338
340
|
title: request.title,
|
|
339
341
|
body: request.body,
|
|
340
342
|
base: request.base,
|
|
341
|
-
...
|
|
343
|
+
...api
|
|
342
344
|
});
|
|
343
345
|
}
|
|
344
346
|
});
|
|
345
|
-
|
|
347
|
+
const plugin = {
|
|
348
|
+
...versionRequests,
|
|
346
349
|
name: "gitlab",
|
|
347
350
|
init() {
|
|
348
351
|
this.gitlab = {
|
|
@@ -353,7 +356,7 @@ function gitlab(options = {}) {
|
|
|
353
356
|
};
|
|
354
357
|
},
|
|
355
358
|
async resolvePlanStatus({ plan }) {
|
|
356
|
-
if (versionRequests.resolvePlanStatus() === "pending") return "pending";
|
|
359
|
+
if (versionRequests.resolvePlanStatus.call(this, { plan }) === "pending") return "pending";
|
|
357
360
|
const { repo, token } = this.gitlab;
|
|
358
361
|
if (!repo || !token || releaseOptions === false) return;
|
|
359
362
|
const requiredTags = /* @__PURE__ */ new Set();
|
|
@@ -425,20 +428,9 @@ function gitlab(options = {}) {
|
|
|
425
428
|
gitlabRemoteUrl(repo, token, webUrl)
|
|
426
429
|
], { nodeOptions: { cwd: this.cwd } });
|
|
427
430
|
if (result.exitCode !== 0) throw execFailure("Failed to configure git remote for GitLab CI.", result);
|
|
428
|
-
},
|
|
429
|
-
initCliDraft() {
|
|
430
|
-
versionRequests.initCliDraft.call(this);
|
|
431
|
-
},
|
|
432
|
-
applyCliDraft(draft) {
|
|
433
|
-
return versionRequests.applyCliDraft.call(this, draft);
|
|
434
|
-
},
|
|
435
|
-
initPublishPlan(opts) {
|
|
436
|
-
versionRequests.initPublishPlan.call(this, opts);
|
|
437
|
-
},
|
|
438
|
-
beforePublishAll(opts) {
|
|
439
|
-
return versionRequests.beforePublishAll.call(this, opts);
|
|
440
431
|
}
|
|
441
|
-
}
|
|
432
|
+
};
|
|
433
|
+
return [git(options), plugin];
|
|
442
434
|
}
|
|
443
435
|
function createChangelogRenderer(context) {
|
|
444
436
|
const { repo, webUrl } = context.gitlab;
|
package/dist/plugins/go.d.ts
CHANGED
package/dist/plugins/go.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as isNodeError, n as execFailure, r as fetchFailure } from "../error-CAsrGb6e.js";
|
|
2
2
|
import { n as _validateReport, t as _createStandardSchema } from "../_createStandardSchema-BGQyz-uA.js";
|
|
3
3
|
import { n as WorkspacePackage } from "../graph-BmXTJZxx.js";
|
|
4
4
|
import { relative, resolve } from "node:path";
|
|
@@ -524,7 +524,7 @@ async function isModulePublished(module, version) {
|
|
|
524
524
|
const response = await fetch(`https://proxy.golang.org/${encodeURIComponent(module)}/@v/${formatted}.info`);
|
|
525
525
|
if (response.status === 200) return true;
|
|
526
526
|
if (response.status === 404) return false;
|
|
527
|
-
throw
|
|
527
|
+
throw await fetchFailure(`Unable to validate ${module}@${formatted} against proxy.golang.org`, response);
|
|
528
528
|
}
|
|
529
529
|
//#endregion
|
|
530
530
|
export { GoPackage, go };
|
package/dist/providers/npm.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as NpmPackage, S as NpmGraph, l as NpmPluginOptions, u as npm, x as DependencySpec } from "../types-
|
|
1
|
+
import { C as NpmPackage, S as NpmGraph, l as NpmPluginOptions, u as npm, x as DependencySpec } from "../types-BbwOrNZ2.js";
|
|
2
2
|
export { type DependencySpec, type NpmGraph, NpmPackage, NpmPluginOptions, npm };
|
package/dist/providers/npm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as NpmPackage, t as npm } from "../npm-
|
|
1
|
+
import { n as NpmPackage, t as npm } from "../npm-4iA03RvC.js";
|
|
2
2
|
export { NpmPackage, npm };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { a as maxBump } from "./semver-EKJ8yK5U.js";
|
|
2
|
-
import {
|
|
2
|
+
import { i as handlePluginError, l as somePromise } from "./error-CAsrGb6e.js";
|
|
3
3
|
import { t as _accessExpressionAsString } from "./_accessExpressionAsString-QhbUZzwv.js";
|
|
4
4
|
import { n as _validateReport, t as _createStandardSchema } from "./_createStandardSchema-BGQyz-uA.js";
|
|
5
5
|
import { n as validateChangelogFrontmatter, t as renderChangelog } from "./shared-C_iSTp_s.js";
|
|
6
6
|
import { simpleGenerator } from "./generators/simple.js";
|
|
7
7
|
import { t as _assertGuard } from "./_assertGuard-BBn2NbSz.js";
|
|
8
|
-
import { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
8
|
+
import fs, { mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
9
9
|
import path, { basename, dirname, join } from "node:path";
|
|
10
10
|
import * as semver$1 from "semver";
|
|
11
11
|
import { parse as parse$1, stringify } from "yaml";
|
|
@@ -178,10 +178,14 @@ function headingToBump(depth) {
|
|
|
178
178
|
/**
|
|
179
179
|
* the data structure of `publish-lock.yaml` file.
|
|
180
180
|
*/
|
|
181
|
-
var PublishLock = class {
|
|
181
|
+
var PublishLock = class PublishLock {
|
|
182
|
+
/** namespace -> data array */
|
|
182
183
|
data;
|
|
183
|
-
constructor(
|
|
184
|
-
|
|
184
|
+
constructor(input = /* @__PURE__ */ new Map()) {
|
|
185
|
+
if (input instanceof PublishLock) {
|
|
186
|
+
this.data = /* @__PURE__ */ new Map();
|
|
187
|
+
for (const [k, v] of input.data) this.data.set(k, [...v]);
|
|
188
|
+
} else this.data = input;
|
|
185
189
|
}
|
|
186
190
|
/** write data to namespace, note that the `data` must be serializable in yaml */
|
|
187
191
|
write(namespace, data) {
|
|
@@ -618,4 +622,182 @@ function attachChangelog(draft, entry) {
|
|
|
618
622
|
draft.changelogs.push(entry);
|
|
619
623
|
}
|
|
620
624
|
//#endregion
|
|
621
|
-
|
|
625
|
+
//#region src/plans/publish.ts
|
|
626
|
+
async function initPublishPlan(context, options) {
|
|
627
|
+
let lock;
|
|
628
|
+
try {
|
|
629
|
+
lock = parsePublishLock(await fs.readFile(context.lockPath, "utf8"));
|
|
630
|
+
} catch {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
let data;
|
|
634
|
+
const packages = /* @__PURE__ */ new Map();
|
|
635
|
+
const changelogs = /* @__PURE__ */ new Map();
|
|
636
|
+
while (data = lock.read("core:changelogs")) {
|
|
637
|
+
const validated = validateChangelogStore(data);
|
|
638
|
+
if (!validated.success) continue;
|
|
639
|
+
const entry = validated.data;
|
|
640
|
+
const parsed = parseChangelogFile(entry.filename, entry.content);
|
|
641
|
+
if (!parsed) continue;
|
|
642
|
+
changelogs.set(parsed.id, parsed);
|
|
643
|
+
}
|
|
644
|
+
while (data = lock.read("core:packages")) {
|
|
645
|
+
const validated = validatePackageStore(data);
|
|
646
|
+
if (!validated.success) continue;
|
|
647
|
+
const parsed = validated.data;
|
|
648
|
+
if (!context.graph.get(parsed.id)) continue;
|
|
649
|
+
const pkgChangelogs = [];
|
|
650
|
+
for (const id of parsed.changelogIds ?? []) {
|
|
651
|
+
const entry = changelogs.get(id);
|
|
652
|
+
if (entry) pkgChangelogs.push(entry);
|
|
653
|
+
}
|
|
654
|
+
packages.set(parsed.id, {
|
|
655
|
+
changelogs: pkgChangelogs,
|
|
656
|
+
updated: parsed.updated
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
const plan = {
|
|
660
|
+
options,
|
|
661
|
+
changelogs,
|
|
662
|
+
packages
|
|
663
|
+
};
|
|
664
|
+
for (const plugin of context.plugins) await handlePluginError(plugin, "initPublishPlan", () => plugin.initPublishPlan?.call(context, {
|
|
665
|
+
lock,
|
|
666
|
+
plan
|
|
667
|
+
}));
|
|
668
|
+
return plan;
|
|
669
|
+
}
|
|
670
|
+
function resolvePublishTargets(plan) {
|
|
671
|
+
/** the iteration order = publish order */
|
|
672
|
+
const orderedMap = /* @__PURE__ */ new Map();
|
|
673
|
+
let lastSplitIndex = -1;
|
|
674
|
+
/** package id -> true while scanning hard wait, false while scanning optional wait */
|
|
675
|
+
const stack = /* @__PURE__ */ new Map();
|
|
676
|
+
function scan(id) {
|
|
677
|
+
const preflight = plan.packages.get(id)?.preflight;
|
|
678
|
+
if (!preflight || !preflight.shouldPublish) return;
|
|
679
|
+
switch (stack.get(id)) {
|
|
680
|
+
case true: throw new Error(`circular reference of deps: ${[...stack.keys(), id].join(" -> ")}`);
|
|
681
|
+
case false: return;
|
|
682
|
+
}
|
|
683
|
+
let ordered = orderedMap.get(id);
|
|
684
|
+
if (ordered) return ordered;
|
|
685
|
+
let split = false;
|
|
686
|
+
if (preflight.wait) {
|
|
687
|
+
stack.set(id, true);
|
|
688
|
+
for (const dep of preflight.wait) {
|
|
689
|
+
const ordered = scan(dep);
|
|
690
|
+
split ||= ordered !== void 0 && ordered.index >= lastSplitIndex;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
if (preflight.optionalWait) {
|
|
694
|
+
stack.set(id, false);
|
|
695
|
+
for (const dep of preflight.optionalWait) {
|
|
696
|
+
const ordered = scan(dep);
|
|
697
|
+
split ||= ordered !== void 0 && ordered.index >= lastSplitIndex;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
stack.delete(id);
|
|
701
|
+
ordered = {
|
|
702
|
+
split,
|
|
703
|
+
index: orderedMap.size
|
|
704
|
+
};
|
|
705
|
+
if (split) lastSplitIndex = ordered.index;
|
|
706
|
+
orderedMap.set(id, ordered);
|
|
707
|
+
return ordered;
|
|
708
|
+
}
|
|
709
|
+
for (const id of plan.packages.keys()) scan(id);
|
|
710
|
+
return orderedMap;
|
|
711
|
+
}
|
|
712
|
+
async function runPublishPlan(context, plan) {
|
|
713
|
+
const { dryRun = false, unstable_maxChunk = 5 } = plan.options;
|
|
714
|
+
for (const plugin of context.plugins) await handlePluginError(plugin, "beforePublishAll", () => plugin.beforePublishAll?.call(context, { plan }));
|
|
715
|
+
async function publish(pkg) {
|
|
716
|
+
if (dryRun) return { type: "published" };
|
|
717
|
+
try {
|
|
718
|
+
for (const plugin of context.plugins) if (await handlePluginError(plugin, "willPublish", () => plugin.willPublish?.call(context, { pkg })) === false) return { type: "skipped" };
|
|
719
|
+
for (const plugin of context.plugins) {
|
|
720
|
+
const publishResult = await handlePluginError(plugin, "publish", () => plugin.publish?.call(context, {
|
|
721
|
+
pkg,
|
|
722
|
+
plan
|
|
723
|
+
}));
|
|
724
|
+
if (publishResult) return publishResult;
|
|
725
|
+
}
|
|
726
|
+
} catch (e) {
|
|
727
|
+
return {
|
|
728
|
+
type: "failed",
|
|
729
|
+
error: e instanceof Error ? e.message : String(e)
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
return {
|
|
733
|
+
type: "failed",
|
|
734
|
+
error: `There is no plugin to publish package "${pkg.id}", please make sure the package has a supported provider plugin.`
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
let promises = [];
|
|
738
|
+
for (const [id, { split }] of resolvePublishTargets(plan)) {
|
|
739
|
+
const pkg = context.graph.get(id);
|
|
740
|
+
const packagePlan = plan.packages.get(pkg.id);
|
|
741
|
+
if (!pkg || !packagePlan) continue;
|
|
742
|
+
if (split || promises.length >= unstable_maxChunk) {
|
|
743
|
+
await Promise.all(promises);
|
|
744
|
+
promises = [];
|
|
745
|
+
}
|
|
746
|
+
promises.push(publish(pkg).then(async (result) => {
|
|
747
|
+
packagePlan.publishResult = result;
|
|
748
|
+
if (result.type === "skipped") return;
|
|
749
|
+
for (const plugin of context.plugins) await handlePluginError(plugin, "afterPublish", () => plugin.afterPublish?.call(context, {
|
|
750
|
+
pkg,
|
|
751
|
+
plan
|
|
752
|
+
}));
|
|
753
|
+
}));
|
|
754
|
+
}
|
|
755
|
+
await Promise.all(promises);
|
|
756
|
+
for (const packagePlan of plan.packages.values()) packagePlan.publishResult ??= { type: "skipped" };
|
|
757
|
+
for (const plugin of context.plugins) await handlePluginError(plugin, "afterPublishAll", () => plugin.afterPublishAll?.call(context, { plan }));
|
|
758
|
+
}
|
|
759
|
+
async function runPreflights(context, plan) {
|
|
760
|
+
const { graph } = context;
|
|
761
|
+
await Promise.all(Array.from(plan.packages, async ([id, packagePlan]) => {
|
|
762
|
+
const pkg = graph.get(id);
|
|
763
|
+
packagePlan.preflight = { shouldPublish: false };
|
|
764
|
+
if (!packagePlan.updated) return;
|
|
765
|
+
for (const plugin of context.plugins) {
|
|
766
|
+
const res = await handlePluginError(plugin, "publishPreflight", () => plugin.publishPreflight?.call(context, {
|
|
767
|
+
pkg,
|
|
768
|
+
plan
|
|
769
|
+
}));
|
|
770
|
+
if (res) {
|
|
771
|
+
packagePlan.preflight = res;
|
|
772
|
+
break;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}));
|
|
776
|
+
if (plan.options.packages) {
|
|
777
|
+
const only = /* @__PURE__ */ new Set();
|
|
778
|
+
function addOnly(id) {
|
|
779
|
+
if (only.has(id)) return;
|
|
780
|
+
const preflight = plan.packages.get(id)?.preflight;
|
|
781
|
+
if (!preflight) return;
|
|
782
|
+
only.add(id);
|
|
783
|
+
if (preflight.wait) for (const dep of preflight.wait) addOnly(dep);
|
|
784
|
+
if (preflight.optionalWait) for (const dep of preflight.optionalWait) addOnly(dep);
|
|
785
|
+
}
|
|
786
|
+
for (const name of plan.options.packages) for (const pkg of graph.getByName(name)) addOnly(pkg.id);
|
|
787
|
+
for (const [id, packagePlan] of plan.packages) {
|
|
788
|
+
if (only.has(id)) continue;
|
|
789
|
+
packagePlan.preflight.shouldPublish = false;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
for (const plugin of context.plugins) await handlePluginError(plugin, "afterPreflight", () => plugin.afterPreflight?.call(context, { plan }));
|
|
793
|
+
}
|
|
794
|
+
async function publishPlanStatus(plan, context) {
|
|
795
|
+
for (const plugin of context.plugins) {
|
|
796
|
+
const status = await handlePluginError(plugin, "resolvePlanStatus", () => plugin.resolvePlanStatus?.call(context, { plan }));
|
|
797
|
+
if (Array.isArray(status) && await somePromise(status, (v) => v === "pending")) return "pending";
|
|
798
|
+
if (status === "pending") return "pending";
|
|
799
|
+
}
|
|
800
|
+
return "success";
|
|
801
|
+
}
|
|
802
|
+
//#endregion
|
|
803
|
+
export { createDraft as a, parseChangelogFile as c, runPublishPlan as i, readChangelogEntries as l, publishPlanStatus as n, PublishLock as o, runPreflights as r, parsePublishLock as s, initPublishPlan as t };
|
|
@@ -560,6 +560,10 @@ interface PublishPlan {
|
|
|
560
560
|
changelogs: Map<string, ChangelogEntry>;
|
|
561
561
|
/** id -> package data. The package id will always exist in package graph, stale items will be pruned at init-time */
|
|
562
562
|
packages: Map<string, PackagePublishPlan>;
|
|
563
|
+
/** generated by GitHub/GitLab plugin (internal) */
|
|
564
|
+
$versionRequest?: {
|
|
565
|
+
publishGroups: Map<string, "active" | "pending">;
|
|
566
|
+
};
|
|
563
567
|
}
|
|
564
568
|
interface PackagePublishPlan {
|
|
565
569
|
changelogs: ChangelogEntry[];
|
|
@@ -586,6 +590,8 @@ interface PublishOptions {
|
|
|
586
590
|
* Publish only the given packages and their dependencies.
|
|
587
591
|
*
|
|
588
592
|
* Each entry can be a package id, package name, or `group:name`.
|
|
593
|
+
*
|
|
594
|
+
* When empty, no packages will be published.
|
|
589
595
|
*/
|
|
590
596
|
packages?: string[];
|
|
591
597
|
/**
|
|
@@ -609,9 +615,8 @@ type PackagePublishResult = {
|
|
|
609
615
|
declare class PublishLock {
|
|
610
616
|
/** namespace -> data array */
|
|
611
617
|
private readonly data;
|
|
612
|
-
constructor(
|
|
613
|
-
|
|
614
|
-
data?: Map<string, unknown[]>);
|
|
618
|
+
constructor(lock: PublishLock);
|
|
619
|
+
constructor(data?: Map<string, unknown[]>);
|
|
615
620
|
/** write data to namespace, note that the `data` must be serializable in yaml */
|
|
616
621
|
write(namespace: string, data: unknown): void;
|
|
617
622
|
read(namespace: string): unknown | undefined;
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -2,9 +2,10 @@ import { Result } from "tinyexec";
|
|
|
2
2
|
|
|
3
3
|
//#region src/utils/error.d.ts
|
|
4
4
|
declare function execFailure(context: string, result: Awaited<Result>): Error;
|
|
5
|
+
declare function fetchFailure(context: string, response: Response): Promise<Error>;
|
|
5
6
|
//#endregion
|
|
6
7
|
//#region src/utils/common.d.ts
|
|
7
8
|
declare const isCI: () => boolean;
|
|
8
9
|
declare function joinPath(...paths: string[]): string;
|
|
9
10
|
//#endregion
|
|
10
|
-
export { execFailure, isCI, joinPath };
|
|
11
|
+
export { execFailure, fetchFailure, isCI, joinPath };
|
package/dist/utils/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as execFailure,
|
|
2
|
-
export { execFailure, isCI, joinPath };
|
|
1
|
+
import { c as joinPath, n as execFailure, r as fetchFailure, s as isCI } from "../error-CAsrGb6e.js";
|
|
2
|
+
export { execFailure, fetchFailure, isCI, joinPath };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { b as TegamiContext, j as Draft, m as PublishLock, t as Awaitable, v as PublishPlan } from "./types-BbwOrNZ2.js";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/version-request.d.ts
|
|
4
|
+
interface VersionRequestOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Create the pull/merge request even outside of CI.
|
|
7
|
+
*
|
|
8
|
+
* @default false
|
|
9
|
+
*/
|
|
10
|
+
forceCreate?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Pull/merge request branch. Publish group PRs are created under `<branch>/`.
|
|
13
|
+
*
|
|
14
|
+
* @default "tegami/version-packages"
|
|
15
|
+
*/
|
|
16
|
+
branch?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Pull/merge request base branch.
|
|
19
|
+
*
|
|
20
|
+
* @default "main"
|
|
21
|
+
*/
|
|
22
|
+
base?: string;
|
|
23
|
+
/** Publish groups to split into separate version requests. */
|
|
24
|
+
groups?: (string | string[])[];
|
|
25
|
+
/** Override details of a version request at version-time. */
|
|
26
|
+
create?: (this: TegamiContext, opts: VersionRequestContext) => Awaitable<{
|
|
27
|
+
title?: string;
|
|
28
|
+
body?: string;
|
|
29
|
+
}>;
|
|
30
|
+
/** Override commit summary & message. */
|
|
31
|
+
commit?: (this: TegamiContext, opts: {
|
|
32
|
+
type: "version-packages";
|
|
33
|
+
} | {
|
|
34
|
+
type: "update-lock";
|
|
35
|
+
store: PublishGroupStore;
|
|
36
|
+
updatedLock: PublishLock;
|
|
37
|
+
}) => Awaitable<{
|
|
38
|
+
title?: string;
|
|
39
|
+
body?: string;
|
|
40
|
+
} | undefined>;
|
|
41
|
+
}
|
|
42
|
+
interface VersionRequestContext {
|
|
43
|
+
draft: Draft;
|
|
44
|
+
/** predicted publish plan (after preflight) */
|
|
45
|
+
plan: PublishPlan | undefined;
|
|
46
|
+
getPreviousVersion(packageId: string): string | undefined;
|
|
47
|
+
}
|
|
48
|
+
/** adapter over the version request API of a git provider */
|
|
49
|
+
interface PublishGroupStore {
|
|
50
|
+
/**
|
|
51
|
+
* - active: groups whose version request was merged, they stay listed until the lock is removed
|
|
52
|
+
* - pending: groups still waiting for their version request to be merged
|
|
53
|
+
*/
|
|
54
|
+
groups: Record<string, "pending" | "active">;
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { VersionRequestOptions as t };
|