@ucdjs/release-scripts 0.1.0-beta.32 ā 0.1.0-beta.34
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/index.mjs +321 -199
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,21 +1,98 @@
|
|
|
1
1
|
import { t as Eta } from "./eta-BV8TCRDW.mjs";
|
|
2
2
|
import { Console, Context, Data, Effect, Layer, Schema } from "effect";
|
|
3
|
+
import process from "node:process";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { Command, CommandExecutor } from "@effect/platform";
|
|
5
6
|
import { NodeCommandExecutor, NodeFileSystem } from "@effect/platform-node";
|
|
6
7
|
import * as CommitParser from "commit-parser";
|
|
7
|
-
import process from "node:process";
|
|
8
8
|
import semver from "semver";
|
|
9
9
|
import fs from "node:fs/promises";
|
|
10
10
|
import prompts from "prompts";
|
|
11
11
|
|
|
12
|
+
//#region src/options.ts
|
|
13
|
+
const DEFAULT_PR_BODY_TEMPLATE = `## Summary\n\nThis PR contains the following changes:\n\n- Updated package versions\n- Updated changelogs\n\n## Packages\n\nThe following packages will be released:\n\n{{packages}}`;
|
|
14
|
+
const DEFAULT_CHANGELOG_TEMPLATE = `# Changelog\n\n{{releases}}`;
|
|
15
|
+
const DEFAULT_TYPES = {
|
|
16
|
+
feat: {
|
|
17
|
+
title: "š Features",
|
|
18
|
+
color: "green"
|
|
19
|
+
},
|
|
20
|
+
fix: {
|
|
21
|
+
title: "š Bug Fixes",
|
|
22
|
+
color: "red"
|
|
23
|
+
},
|
|
24
|
+
refactor: {
|
|
25
|
+
title: "š§ Code Refactoring",
|
|
26
|
+
color: "blue"
|
|
27
|
+
},
|
|
28
|
+
perf: {
|
|
29
|
+
title: "š Performance",
|
|
30
|
+
color: "orange"
|
|
31
|
+
},
|
|
32
|
+
docs: {
|
|
33
|
+
title: "š Documentation",
|
|
34
|
+
color: "purple"
|
|
35
|
+
},
|
|
36
|
+
style: {
|
|
37
|
+
title: "šØ Styles",
|
|
38
|
+
color: "pink"
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
function normalizeReleaseScriptsOptions(options) {
|
|
42
|
+
const { workspaceRoot = process.cwd(), githubToken = "", repo: fullRepo, packages = true, branch = {}, globalCommitMode = "dependencies", pullRequest = {}, changelog = {}, types = {}, dryRun = false, npm = {}, prompts = {} } = options;
|
|
43
|
+
const token = githubToken.trim();
|
|
44
|
+
if (!token) throw new Error("GitHub token is required. Pass it in via options.");
|
|
45
|
+
if (!fullRepo || !fullRepo.trim() || !fullRepo.includes("/")) throw new Error("Repository (repo) is required. Specify in 'owner/repo' format (e.g., 'octocat/hello-world').");
|
|
46
|
+
const [owner, repo] = fullRepo.split("/");
|
|
47
|
+
if (!owner || !repo) throw new Error(`Invalid repo format: "${fullRepo}". Expected format: "owner/repo" (e.g., "octocat/hello-world").`);
|
|
48
|
+
const normalizedPackages = typeof packages === "object" && !Array.isArray(packages) ? {
|
|
49
|
+
exclude: packages.exclude ?? [],
|
|
50
|
+
include: packages.include ?? [],
|
|
51
|
+
excludePrivate: packages.excludePrivate ?? false
|
|
52
|
+
} : packages;
|
|
53
|
+
const isCI = process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true";
|
|
54
|
+
return {
|
|
55
|
+
dryRun,
|
|
56
|
+
workspaceRoot,
|
|
57
|
+
githubToken: token,
|
|
58
|
+
owner,
|
|
59
|
+
repo,
|
|
60
|
+
packages: normalizedPackages,
|
|
61
|
+
branch: {
|
|
62
|
+
release: branch.release ?? "release/next",
|
|
63
|
+
default: branch.default ?? "main"
|
|
64
|
+
},
|
|
65
|
+
globalCommitMode,
|
|
66
|
+
pullRequest: {
|
|
67
|
+
title: pullRequest.title ?? "chore: release new version",
|
|
68
|
+
body: pullRequest.body ?? DEFAULT_PR_BODY_TEMPLATE
|
|
69
|
+
},
|
|
70
|
+
changelog: {
|
|
71
|
+
enabled: changelog.enabled ?? true,
|
|
72
|
+
template: changelog.template ?? DEFAULT_CHANGELOG_TEMPLATE,
|
|
73
|
+
emojis: changelog.emojis ?? true
|
|
74
|
+
},
|
|
75
|
+
types: options.types ? {
|
|
76
|
+
...DEFAULT_TYPES,
|
|
77
|
+
...types
|
|
78
|
+
} : DEFAULT_TYPES,
|
|
79
|
+
npm: {
|
|
80
|
+
otp: npm.otp,
|
|
81
|
+
provenance: npm.provenance ?? true
|
|
82
|
+
},
|
|
83
|
+
prompts: { versions: prompts.versions ?? !isCI }
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
var ReleaseScriptsOptions = class extends Context.Tag("@ucdjs/release-scripts/ReleaseScriptsOptions")() {};
|
|
87
|
+
|
|
88
|
+
//#endregion
|
|
12
89
|
//#region src/utils/changelog-formatters.ts
|
|
13
90
|
const eta$1 = new Eta();
|
|
14
91
|
/**
|
|
15
92
|
* Pure function to parse commits into changelog entries
|
|
16
93
|
*/
|
|
17
94
|
function parseCommits(commits) {
|
|
18
|
-
return commits.filter((commit) => commit.isConventional).map((commit) => ({
|
|
95
|
+
return commits.filter((commit) => commit.isConventional).filter((commit) => commit.type !== "chore").map((commit) => ({
|
|
19
96
|
type: commit.type || "other",
|
|
20
97
|
scope: commit.scope,
|
|
21
98
|
description: commit.description,
|
|
@@ -25,6 +102,11 @@ function parseCommits(commits) {
|
|
|
25
102
|
references: commit.references.map((ref) => ({
|
|
26
103
|
type: ref.type,
|
|
27
104
|
value: ref.value
|
|
105
|
+
})),
|
|
106
|
+
authors: commit.authors.map((author) => ({
|
|
107
|
+
name: author.name,
|
|
108
|
+
email: author.email,
|
|
109
|
+
profile: author.profile
|
|
28
110
|
}))
|
|
29
111
|
}));
|
|
30
112
|
}
|
|
@@ -43,10 +125,7 @@ function groupByType(entries) {
|
|
|
43
125
|
/**
|
|
44
126
|
* Changelog template for Eta rendering
|
|
45
127
|
*/
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
**Previous version**: \`<%= it.previousVersion %>\`
|
|
49
|
-
**New version**: \`<%= it.version %>\`
|
|
128
|
+
const CHANGELOG_ENTRY_TEMPLATE = `## <%= it.version %>
|
|
50
129
|
|
|
51
130
|
<% if (it.entries.length === 0) { %>
|
|
52
131
|
*No conventional commits found.*
|
|
@@ -55,25 +134,58 @@ const CHANGELOG_TEMPLATE = `# <%= it.packageName %> v<%= it.version %>
|
|
|
55
134
|
<% const typeOrder = ["breaking", "feat", "fix", "perf", "docs", "style", "refactor", "test", "build", "ci", "chore"]; %>
|
|
56
135
|
<% const typeLabels = {
|
|
57
136
|
breaking: "š„ Breaking Changes",
|
|
58
|
-
feat: "
|
|
59
|
-
fix: "
|
|
137
|
+
feat: "š Features",
|
|
138
|
+
fix: "š Bug Fixes",
|
|
60
139
|
perf: "ā” Performance",
|
|
61
|
-
docs: "
|
|
62
|
-
style: "
|
|
63
|
-
refactor: "
|
|
64
|
-
test: "
|
|
65
|
-
build: "
|
|
66
|
-
ci: "
|
|
67
|
-
chore: "
|
|
140
|
+
docs: "Documentation",
|
|
141
|
+
style: "Styling",
|
|
142
|
+
refactor: "Refactoring",
|
|
143
|
+
test: "Tests",
|
|
144
|
+
build: "Build",
|
|
145
|
+
ci: "CI",
|
|
146
|
+
chore: "Chores"
|
|
147
|
+
}; %>
|
|
148
|
+
|
|
149
|
+
<% const formatAuthor = (entry) => {
|
|
150
|
+
const author = entry.authors && entry.authors.length > 0 ? entry.authors[0] : null;
|
|
151
|
+
if (!author) return "unknown";
|
|
152
|
+
if (author.profile && author.profile.includes("github.com/")) {
|
|
153
|
+
const username = author.profile.split("github.com/")[1];
|
|
154
|
+
return "@" + username;
|
|
155
|
+
}
|
|
156
|
+
return author.name || "unknown";
|
|
157
|
+
}; %>
|
|
158
|
+
|
|
159
|
+
<% const commitUrl = (hash) => it.repo ? "https://github.com/" + it.repo + "/commit/" + hash : ""; %>
|
|
160
|
+
|
|
161
|
+
<% const formatLine = (entry) => {
|
|
162
|
+
const authorText = formatAuthor(entry);
|
|
163
|
+
const commitLink = commitUrl(entry.hash);
|
|
164
|
+
const hashPart = commitLink
|
|
165
|
+
? " [<samp>(" + entry.shortHash + ")</samp>](" + commitLink + ")"
|
|
166
|
+
: " <samp>(" + entry.shortHash + ")</samp>";
|
|
167
|
+
return entry.description + " - by " + authorText + hashPart;
|
|
68
168
|
}; %>
|
|
69
169
|
|
|
70
170
|
<% for (const type of typeOrder) { %>
|
|
71
171
|
<% const entries = groups.get(type); %>
|
|
72
172
|
<% if (entries && entries.length > 0) { %>
|
|
73
|
-
|
|
173
|
+
### <%= typeLabels[type] || type.charAt(0).toUpperCase() + type.slice(1) %>
|
|
74
174
|
|
|
75
|
-
<%
|
|
76
|
-
|
|
175
|
+
<% const unscoped = entries.filter(e => !e.scope); %>
|
|
176
|
+
<% const scoped = entries.filter(e => e.scope); %>
|
|
177
|
+
|
|
178
|
+
<% for (const entry of unscoped) { %>
|
|
179
|
+
- <%= formatLine(entry) %>
|
|
180
|
+
<% } %>
|
|
181
|
+
|
|
182
|
+
<% const scopes = [...new Set(scoped.map(e => e.scope))]; %>
|
|
183
|
+
<% for (const scope of scopes) { %>
|
|
184
|
+
- **<%= scope %>**:
|
|
185
|
+
<% const scopeEntries = scoped.filter(e => e.scope === scope); %>
|
|
186
|
+
<% for (const entry of scopeEntries) { %>
|
|
187
|
+
- <%= formatLine(entry) %>
|
|
188
|
+
<% } %>
|
|
77
189
|
<% } %>
|
|
78
190
|
|
|
79
191
|
<% } %>
|
|
@@ -81,37 +193,56 @@ const CHANGELOG_TEMPLATE = `# <%= it.packageName %> v<%= it.version %>
|
|
|
81
193
|
|
|
82
194
|
<% for (const [type, entries] of groups) { %>
|
|
83
195
|
<% if (!typeOrder.includes(type)) { %>
|
|
84
|
-
|
|
196
|
+
### <%= type.charAt(0).toUpperCase() + type.slice(1) %>
|
|
85
197
|
|
|
86
198
|
<% for (const entry of entries) { %>
|
|
87
|
-
-
|
|
199
|
+
- <%= formatLine(entry) %>
|
|
88
200
|
<% } %>
|
|
89
201
|
|
|
90
202
|
<% } %>
|
|
91
203
|
<% } %>
|
|
204
|
+
|
|
205
|
+
<% if (it.repo) { %>
|
|
206
|
+
##### [View changes on GitHub](https://github.com/<%= it.repo %>/compare/v<%= it.previousVersion %>...v<%= it.version %>)
|
|
207
|
+
<% } %>
|
|
92
208
|
<% } %>`;
|
|
93
209
|
/**
|
|
94
210
|
* Pure function to format changelog as markdown
|
|
95
211
|
*/
|
|
96
|
-
function
|
|
212
|
+
function formatChangelogEntryMarkdown(changelog) {
|
|
97
213
|
const groups = groupByType(changelog.entries);
|
|
98
|
-
return eta$1.renderString(
|
|
214
|
+
return eta$1.renderString(CHANGELOG_ENTRY_TEMPLATE, {
|
|
99
215
|
packageName: changelog.packageName,
|
|
100
216
|
version: changelog.version,
|
|
101
217
|
previousVersion: changelog.previousVersion,
|
|
102
218
|
entries: changelog.entries,
|
|
103
|
-
groupedEntries: groups
|
|
219
|
+
groupedEntries: groups,
|
|
220
|
+
repo: changelog.repo
|
|
104
221
|
});
|
|
105
222
|
}
|
|
223
|
+
function appendChangelogEntry(existingContent, changelogEntry, packageName) {
|
|
224
|
+
const entry = changelogEntry.trim();
|
|
225
|
+
if (!entry) return existingContent ?? `# ${packageName}\n`;
|
|
226
|
+
if (!existingContent || existingContent.trim() === "") return `# ${packageName}\n\n${entry}\n`;
|
|
227
|
+
const lines = existingContent.split("\n");
|
|
228
|
+
const firstLine = lines[0]?.trim() ?? "";
|
|
229
|
+
if (!firstLine.startsWith("# ")) return `# ${packageName}\n\n${entry}\n\n${existingContent.trim()}\n`;
|
|
230
|
+
let insertIndex = 1;
|
|
231
|
+
while (insertIndex < lines.length && lines[insertIndex]?.trim() === "") insertIndex++;
|
|
232
|
+
const rest = lines.slice(insertIndex).join("\n").trim();
|
|
233
|
+
if (rest) return `${firstLine}\n\n${entry}\n\n${rest}\n`;
|
|
234
|
+
return `${firstLine}\n\n${entry}\n`;
|
|
235
|
+
}
|
|
106
236
|
/**
|
|
107
237
|
* Pure function to create a changelog object
|
|
108
238
|
*/
|
|
109
|
-
function createChangelog(packageName, version, previousVersion, commits) {
|
|
239
|
+
function createChangelog(packageName, version, previousVersion, commits, repo) {
|
|
110
240
|
return {
|
|
111
241
|
packageName,
|
|
112
242
|
version,
|
|
113
243
|
previousVersion,
|
|
114
|
-
entries: parseCommits(commits)
|
|
244
|
+
entries: parseCommits(commits),
|
|
245
|
+
repo
|
|
115
246
|
};
|
|
116
247
|
}
|
|
117
248
|
|
|
@@ -119,12 +250,19 @@ function createChangelog(packageName, version, previousVersion, commits) {
|
|
|
119
250
|
//#region src/services/changelog.service.ts
|
|
120
251
|
var ChangelogService = class extends Effect.Service()("@ucdjs/release-scripts/ChangelogService", {
|
|
121
252
|
effect: Effect.gen(function* () {
|
|
253
|
+
const config = yield* ReleaseScriptsOptions;
|
|
122
254
|
function generateChangelog(pkg, newVersion, commits) {
|
|
123
255
|
return Effect.gen(function* () {
|
|
124
|
-
const changelog = createChangelog(pkg.name, newVersion, pkg.version, commits);
|
|
256
|
+
const changelog = createChangelog(pkg.name, newVersion, pkg.version, commits, `${config.owner}/${config.repo}`);
|
|
257
|
+
const entryMarkdown = formatChangelogEntryMarkdown(changelog);
|
|
125
258
|
return {
|
|
126
259
|
changelog,
|
|
127
|
-
markdown:
|
|
260
|
+
markdown: appendChangelogEntry(yield* Effect.tryPromise({
|
|
261
|
+
try: async () => {
|
|
262
|
+
return await (await import("node:fs/promises")).readFile(`${pkg.path}/CHANGELOG.md`, "utf-8");
|
|
263
|
+
},
|
|
264
|
+
catch: (err) => err
|
|
265
|
+
}).pipe(Effect.catchAll(() => Effect.succeed(""))), entryMarkdown, pkg.name),
|
|
128
266
|
filePath: `${pkg.path}/CHANGELOG.md`
|
|
129
267
|
};
|
|
130
268
|
});
|
|
@@ -213,83 +351,6 @@ var NPMError = class extends Data.TaggedError("NPMError") {};
|
|
|
213
351
|
var PublishError = class extends Data.TaggedError("PublishError") {};
|
|
214
352
|
var TagError = class extends Data.TaggedError("TagError") {};
|
|
215
353
|
|
|
216
|
-
//#endregion
|
|
217
|
-
//#region src/options.ts
|
|
218
|
-
const DEFAULT_PR_BODY_TEMPLATE = `## Summary\n\nThis PR contains the following changes:\n\n- Updated package versions\n- Updated changelogs\n\n## Packages\n\nThe following packages will be released:\n\n{{packages}}`;
|
|
219
|
-
const DEFAULT_CHANGELOG_TEMPLATE = `# Changelog\n\n{{releases}}`;
|
|
220
|
-
const DEFAULT_TYPES = {
|
|
221
|
-
feat: {
|
|
222
|
-
title: "š Features",
|
|
223
|
-
color: "green"
|
|
224
|
-
},
|
|
225
|
-
fix: {
|
|
226
|
-
title: "š Bug Fixes",
|
|
227
|
-
color: "red"
|
|
228
|
-
},
|
|
229
|
-
refactor: {
|
|
230
|
-
title: "š§ Code Refactoring",
|
|
231
|
-
color: "blue"
|
|
232
|
-
},
|
|
233
|
-
perf: {
|
|
234
|
-
title: "š Performance",
|
|
235
|
-
color: "orange"
|
|
236
|
-
},
|
|
237
|
-
docs: {
|
|
238
|
-
title: "š Documentation",
|
|
239
|
-
color: "purple"
|
|
240
|
-
},
|
|
241
|
-
style: {
|
|
242
|
-
title: "šØ Styles",
|
|
243
|
-
color: "pink"
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
function normalizeReleaseScriptsOptions(options) {
|
|
247
|
-
const { workspaceRoot = process.cwd(), githubToken = "", repo: fullRepo, packages = true, branch = {}, globalCommitMode = "dependencies", pullRequest = {}, changelog = {}, types = {}, dryRun = false, npm = {}, prompts = {} } = options;
|
|
248
|
-
const token = githubToken.trim();
|
|
249
|
-
if (!token) throw new Error("GitHub token is required. Pass it in via options.");
|
|
250
|
-
if (!fullRepo || !fullRepo.trim() || !fullRepo.includes("/")) throw new Error("Repository (repo) is required. Specify in 'owner/repo' format (e.g., 'octocat/hello-world').");
|
|
251
|
-
const [owner, repo] = fullRepo.split("/");
|
|
252
|
-
if (!owner || !repo) throw new Error(`Invalid repo format: "${fullRepo}". Expected format: "owner/repo" (e.g., "octocat/hello-world").`);
|
|
253
|
-
const normalizedPackages = typeof packages === "object" && !Array.isArray(packages) ? {
|
|
254
|
-
exclude: packages.exclude ?? [],
|
|
255
|
-
include: packages.include ?? [],
|
|
256
|
-
excludePrivate: packages.excludePrivate ?? false
|
|
257
|
-
} : packages;
|
|
258
|
-
const isCI = process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true";
|
|
259
|
-
return {
|
|
260
|
-
dryRun,
|
|
261
|
-
workspaceRoot,
|
|
262
|
-
githubToken: token,
|
|
263
|
-
owner,
|
|
264
|
-
repo,
|
|
265
|
-
packages: normalizedPackages,
|
|
266
|
-
branch: {
|
|
267
|
-
release: branch.release ?? "release/next",
|
|
268
|
-
default: branch.default ?? "main"
|
|
269
|
-
},
|
|
270
|
-
globalCommitMode,
|
|
271
|
-
pullRequest: {
|
|
272
|
-
title: pullRequest.title ?? "chore: release new version",
|
|
273
|
-
body: pullRequest.body ?? DEFAULT_PR_BODY_TEMPLATE
|
|
274
|
-
},
|
|
275
|
-
changelog: {
|
|
276
|
-
enabled: changelog.enabled ?? true,
|
|
277
|
-
template: changelog.template ?? DEFAULT_CHANGELOG_TEMPLATE,
|
|
278
|
-
emojis: changelog.emojis ?? true
|
|
279
|
-
},
|
|
280
|
-
types: options.types ? {
|
|
281
|
-
...DEFAULT_TYPES,
|
|
282
|
-
...types
|
|
283
|
-
} : DEFAULT_TYPES,
|
|
284
|
-
npm: {
|
|
285
|
-
otp: npm.otp,
|
|
286
|
-
provenance: npm.provenance ?? true
|
|
287
|
-
},
|
|
288
|
-
prompts: { versions: prompts.versions ?? !isCI }
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
var ReleaseScriptsOptions = class extends Context.Tag("@ucdjs/release-scripts/ReleaseScriptsOptions")() {};
|
|
292
|
-
|
|
293
354
|
//#endregion
|
|
294
355
|
//#region src/services/git.service.ts
|
|
295
356
|
var GitService = class extends Effect.Service()("@ucdjs/release-scripts/GitService", {
|
|
@@ -784,6 +845,9 @@ var WorkspaceService = class extends Effect.Service()("@ucdjs/release-scripts/Wo
|
|
|
784
845
|
message: `Invalid package.json for ${pkgPath}`,
|
|
785
846
|
cause: e,
|
|
786
847
|
operation: "readPackageJson"
|
|
848
|
+
})), Effect.map((validated) => ({
|
|
849
|
+
...json,
|
|
850
|
+
...validated
|
|
787
851
|
})))));
|
|
788
852
|
}
|
|
789
853
|
function writePackageJson(pkgPath, json) {
|
|
@@ -1009,32 +1073,32 @@ var VersionCalculatorService = class extends Effect.Service()("@ucdjs/release-sc
|
|
|
1009
1073
|
|
|
1010
1074
|
//#endregion
|
|
1011
1075
|
//#region src/services/version-prompt.service.ts
|
|
1076
|
+
const GREY = "\x1B[90m";
|
|
1077
|
+
const RESET = "\x1B[0m";
|
|
1078
|
+
const NON_VERSIONING_TYPES = new Set([
|
|
1079
|
+
"chore",
|
|
1080
|
+
"docs",
|
|
1081
|
+
"style",
|
|
1082
|
+
"test",
|
|
1083
|
+
"ci",
|
|
1084
|
+
"build",
|
|
1085
|
+
"refactor"
|
|
1086
|
+
]);
|
|
1087
|
+
function isVersioningCommit(commit) {
|
|
1088
|
+
return !NON_VERSIONING_TYPES.has(commit.type) || commit.isBreaking;
|
|
1089
|
+
}
|
|
1012
1090
|
function formatCommit(commit) {
|
|
1013
|
-
const
|
|
1091
|
+
const isGreyed = !isVersioningCommit(commit);
|
|
1014
1092
|
const scope = commit.scope ? `(${commit.scope})` : "";
|
|
1015
|
-
const
|
|
1016
|
-
const
|
|
1017
|
-
|
|
1018
|
-
return refs ? `${header} (${refs})` : header;
|
|
1019
|
-
}
|
|
1020
|
-
function getTypeEmoji(type) {
|
|
1021
|
-
return {
|
|
1022
|
-
feat: "āØ",
|
|
1023
|
-
fix: "š",
|
|
1024
|
-
docs: "š",
|
|
1025
|
-
style: "š",
|
|
1026
|
-
refactor: "š§",
|
|
1027
|
-
perf: "šļø",
|
|
1028
|
-
test: "š§Ŗ",
|
|
1029
|
-
build: "š¦",
|
|
1030
|
-
ci: "š·",
|
|
1031
|
-
chore: "š§",
|
|
1032
|
-
revert: "āŖ"
|
|
1033
|
-
}[type] || "š";
|
|
1093
|
+
const description = commit.isConventional ? commit.description : commit.message.split("\n")[0] ?? commit.message;
|
|
1094
|
+
const line = `${commit.shortHash} ${commit.type.padEnd(12)}${scope.padEnd(10)}: ${description}`;
|
|
1095
|
+
return isGreyed ? `${GREY}${line}${RESET}` : line;
|
|
1034
1096
|
}
|
|
1035
1097
|
function formatCommits(commits) {
|
|
1036
1098
|
if (commits.length === 0) return " No commits since the last version";
|
|
1037
|
-
|
|
1099
|
+
const lines = commits.slice(0, 10).map((c) => ` ${formatCommit(c)}`);
|
|
1100
|
+
if (commits.length > 10) lines.push(` ${GREY}... and ${commits.length - 10} more${RESET}`);
|
|
1101
|
+
return lines.join("\n");
|
|
1038
1102
|
}
|
|
1039
1103
|
function getPrereleaseInfo(version) {
|
|
1040
1104
|
const parsed = semver.parse(version);
|
|
@@ -1081,8 +1145,8 @@ function generateVersionOptions(currentVersion, conventionalBump, prereleaseInfo
|
|
|
1081
1145
|
}
|
|
1082
1146
|
});
|
|
1083
1147
|
}
|
|
1084
|
-
const conventionalVersion = conventionalBump !== "none" ? semver.inc(currentVersion, conventionalBump) :
|
|
1085
|
-
if (conventionalVersion
|
|
1148
|
+
const conventionalVersion = conventionalBump !== "none" ? semver.inc(currentVersion, conventionalBump) : null;
|
|
1149
|
+
if (conventionalVersion) options.push({
|
|
1086
1150
|
title: `conventional ${conventionalVersion}`,
|
|
1087
1151
|
value: {
|
|
1088
1152
|
version: conventionalVersion,
|
|
@@ -1156,6 +1220,11 @@ function generateVersionOptions(currentVersion, conventionalBump, prereleaseInfo
|
|
|
1156
1220
|
});
|
|
1157
1221
|
return options;
|
|
1158
1222
|
}
|
|
1223
|
+
function findDefaultIndex(options, conventionalBump) {
|
|
1224
|
+
if (conventionalBump === "none") return 0;
|
|
1225
|
+
const conventionalIndex = options.findIndex((o) => o.title.startsWith("conventional"));
|
|
1226
|
+
return conventionalIndex >= 0 ? conventionalIndex : 0;
|
|
1227
|
+
}
|
|
1159
1228
|
async function promptForCustomVersion(currentVersion) {
|
|
1160
1229
|
return (await prompts({
|
|
1161
1230
|
type: "text",
|
|
@@ -1171,27 +1240,37 @@ var VersionPromptService = class extends Effect.Service()("@ucdjs/release-script
|
|
|
1171
1240
|
effect: Effect.gen(function* () {
|
|
1172
1241
|
const config = yield* ReleaseScriptsOptions;
|
|
1173
1242
|
let applyToAllRemainingChoice = null;
|
|
1243
|
+
let isCancelled = false;
|
|
1174
1244
|
function promptForVersion(pkg, conventionalBump, remainingCount) {
|
|
1175
1245
|
return Effect.async((resume) => {
|
|
1246
|
+
if (isCancelled) {
|
|
1247
|
+
resume(Effect.succeed({
|
|
1248
|
+
newVersion: pkg.version,
|
|
1249
|
+
bumpType: "none",
|
|
1250
|
+
applyToAllRemaining: false,
|
|
1251
|
+
cancelled: true
|
|
1252
|
+
}));
|
|
1253
|
+
return;
|
|
1254
|
+
}
|
|
1176
1255
|
const allCommits = [...pkg.commits, ...pkg.globalCommits];
|
|
1177
1256
|
const prereleaseInfo = getPrereleaseInfo(pkg.version);
|
|
1257
|
+
const commitCount = allCommits.length;
|
|
1178
1258
|
console.log("");
|
|
1179
|
-
console.log(
|
|
1180
|
-
console.log(`Current version: ${pkg.version}`);
|
|
1181
|
-
console.log("");
|
|
1182
|
-
console.log("Commits:");
|
|
1259
|
+
console.log(`${commitCount} commit${commitCount === 1 ? "" : "s"} since the last version:`);
|
|
1183
1260
|
console.log(formatCommits(allCommits));
|
|
1184
1261
|
console.log("");
|
|
1185
1262
|
if (applyToAllRemainingChoice) {
|
|
1186
1263
|
const result = {
|
|
1187
1264
|
newVersion: applyToAllRemainingChoice.version === "custom" ? pkg.version : applyToAllRemainingChoice.version,
|
|
1188
1265
|
bumpType: applyToAllRemainingChoice.bumpType,
|
|
1189
|
-
applyToAllRemaining: false
|
|
1266
|
+
applyToAllRemaining: false,
|
|
1267
|
+
cancelled: false
|
|
1190
1268
|
};
|
|
1191
1269
|
resume(Effect.succeed(result));
|
|
1192
1270
|
return;
|
|
1193
1271
|
}
|
|
1194
1272
|
const options = generateVersionOptions(pkg.version, conventionalBump, prereleaseInfo);
|
|
1273
|
+
const defaultIndex = findDefaultIndex(options, conventionalBump);
|
|
1195
1274
|
if (remainingCount > 1) options.push({
|
|
1196
1275
|
title: "apply-to-all āŗ",
|
|
1197
1276
|
value: {
|
|
@@ -1202,18 +1281,21 @@ var VersionPromptService = class extends Effect.Service()("@ucdjs/release-script
|
|
|
1202
1281
|
prompts({
|
|
1203
1282
|
type: "select",
|
|
1204
1283
|
name: "choice",
|
|
1205
|
-
message: `
|
|
1284
|
+
message: `Current version ${pkg.version}`,
|
|
1206
1285
|
choices: options.map((o) => ({
|
|
1207
1286
|
title: o.title,
|
|
1208
1287
|
value: o.value
|
|
1209
1288
|
})),
|
|
1289
|
+
initial: defaultIndex,
|
|
1210
1290
|
hint: "Use arrow keys to navigate, enter to select"
|
|
1211
1291
|
}).then(async (response) => {
|
|
1212
1292
|
if (!response.choice) {
|
|
1293
|
+
isCancelled = true;
|
|
1213
1294
|
const result = {
|
|
1214
1295
|
newVersion: pkg.version,
|
|
1215
1296
|
bumpType: "none",
|
|
1216
|
-
applyToAllRemaining: false
|
|
1297
|
+
applyToAllRemaining: false,
|
|
1298
|
+
cancelled: true
|
|
1217
1299
|
};
|
|
1218
1300
|
resume(Effect.succeed(result));
|
|
1219
1301
|
return;
|
|
@@ -1227,39 +1309,66 @@ var VersionPromptService = class extends Effect.Service()("@ucdjs/release-script
|
|
|
1227
1309
|
choices: applyOptions.map((o) => ({
|
|
1228
1310
|
title: o.title,
|
|
1229
1311
|
value: o.value
|
|
1230
|
-
}))
|
|
1312
|
+
})),
|
|
1313
|
+
initial: findDefaultIndex(applyOptions, conventionalBump)
|
|
1231
1314
|
});
|
|
1232
|
-
if (applyResponse.choice) {
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1315
|
+
if (!applyResponse.choice) {
|
|
1316
|
+
isCancelled = true;
|
|
1317
|
+
resume(Effect.succeed({
|
|
1318
|
+
newVersion: pkg.version,
|
|
1319
|
+
bumpType: "none",
|
|
1320
|
+
applyToAllRemaining: false,
|
|
1321
|
+
cancelled: true
|
|
1322
|
+
}));
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1325
|
+
if (applyResponse.choice.version === "custom") {
|
|
1326
|
+
const customVersion = await promptForCustomVersion(pkg.version);
|
|
1327
|
+
if (!customVersion) {
|
|
1328
|
+
isCancelled = true;
|
|
1329
|
+
resume(Effect.succeed({
|
|
1330
|
+
newVersion: pkg.version,
|
|
1331
|
+
bumpType: "none",
|
|
1332
|
+
applyToAllRemaining: false,
|
|
1333
|
+
cancelled: true
|
|
1334
|
+
}));
|
|
1335
|
+
return;
|
|
1336
|
+
}
|
|
1337
|
+
applyToAllRemainingChoice = {
|
|
1338
|
+
version: customVersion,
|
|
1339
|
+
bumpType: applyResponse.choice.bumpType
|
|
1244
1340
|
};
|
|
1245
|
-
|
|
1246
|
-
|
|
1341
|
+
} else applyToAllRemainingChoice = applyResponse.choice;
|
|
1342
|
+
const result = {
|
|
1343
|
+
newVersion: applyToAllRemainingChoice?.version || pkg.version,
|
|
1344
|
+
bumpType: applyToAllRemainingChoice?.bumpType || "none",
|
|
1345
|
+
applyToAllRemaining: true,
|
|
1346
|
+
cancelled: false
|
|
1347
|
+
};
|
|
1348
|
+
resume(Effect.succeed(result));
|
|
1247
1349
|
return;
|
|
1248
1350
|
}
|
|
1249
1351
|
let selectedVersion = response.choice.version;
|
|
1250
|
-
|
|
1352
|
+
const selectedBumpType = response.choice.bumpType;
|
|
1251
1353
|
if (selectedVersion === "custom") {
|
|
1252
1354
|
const customVersion = await promptForCustomVersion(pkg.version);
|
|
1253
|
-
if (customVersion)
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1355
|
+
if (!customVersion) {
|
|
1356
|
+
isCancelled = true;
|
|
1357
|
+
resume(Effect.succeed({
|
|
1358
|
+
newVersion: pkg.version,
|
|
1359
|
+
bumpType: "none",
|
|
1360
|
+
applyToAllRemaining: false,
|
|
1361
|
+
cancelled: true
|
|
1362
|
+
}));
|
|
1363
|
+
return;
|
|
1257
1364
|
}
|
|
1365
|
+
selectedVersion = customVersion;
|
|
1258
1366
|
}
|
|
1259
1367
|
const result = {
|
|
1260
1368
|
newVersion: selectedVersion,
|
|
1261
1369
|
bumpType: selectedBumpType,
|
|
1262
|
-
applyToAllRemaining: false
|
|
1370
|
+
applyToAllRemaining: false,
|
|
1371
|
+
cancelled: false
|
|
1263
1372
|
};
|
|
1264
1373
|
resume(Effect.succeed(result));
|
|
1265
1374
|
});
|
|
@@ -1270,6 +1379,7 @@ var VersionPromptService = class extends Effect.Service()("@ucdjs/release-script
|
|
|
1270
1379
|
isEnabled: config.prompts.versions,
|
|
1271
1380
|
resetApplyToAll: () => {
|
|
1272
1381
|
applyToAllRemainingChoice = null;
|
|
1382
|
+
isCancelled = false;
|
|
1273
1383
|
}
|
|
1274
1384
|
};
|
|
1275
1385
|
}),
|
|
@@ -1473,36 +1583,38 @@ function constructPrepareProgram(config) {
|
|
|
1473
1583
|
const versionPrompt = yield* VersionPromptService;
|
|
1474
1584
|
const workspace = yield* WorkspaceService;
|
|
1475
1585
|
yield* git.workspace.assertWorkspaceReady;
|
|
1586
|
+
const startingBranch = yield* git.branches.get;
|
|
1587
|
+
if (startingBranch !== config.branch.default) return yield* Effect.fail(/* @__PURE__ */ new Error(`Prepare must be run on the default branch "${config.branch.default}". Current branch: "${startingBranch}"`));
|
|
1476
1588
|
let releasePullRequest = yield* github.getPullRequestByBranch(config.branch.release);
|
|
1477
1589
|
const isNewRelease = !releasePullRequest;
|
|
1478
1590
|
const branchExists = yield* git.branches.exists(config.branch.release);
|
|
1479
1591
|
if (!branchExists) {
|
|
1480
|
-
yield* Console.log(
|
|
1592
|
+
yield* Console.log(`Creating release branch "${config.branch.release}" from "${config.branch.default}"...`);
|
|
1481
1593
|
yield* git.branches.create(config.branch.release, config.branch.default);
|
|
1482
|
-
yield* Console.log(
|
|
1594
|
+
yield* Console.log(`Release branch created.`);
|
|
1483
1595
|
}
|
|
1484
1596
|
if ((yield* git.branches.get) !== config.branch.release) {
|
|
1485
1597
|
yield* git.branches.checkout(config.branch.release);
|
|
1486
|
-
yield* Console.log(
|
|
1598
|
+
yield* Console.log(`Checked out to release branch "${config.branch.release}".`);
|
|
1487
1599
|
}
|
|
1488
1600
|
if (!isNewRelease || branchExists) {
|
|
1489
|
-
yield* Console.log(
|
|
1601
|
+
yield* Console.log(`Rebasing "${config.branch.release}" onto "${config.branch.default}"...`);
|
|
1490
1602
|
yield* git.branches.rebase(config.branch.default);
|
|
1491
|
-
yield* Console.log(
|
|
1603
|
+
yield* Console.log(`Rebase complete.`);
|
|
1492
1604
|
}
|
|
1493
1605
|
const overrides = yield* loadOverrides({
|
|
1494
1606
|
sha: config.branch.default,
|
|
1495
1607
|
overridesPath: ".github/ucdjs-release.overrides.json"
|
|
1496
1608
|
});
|
|
1497
|
-
if (Object.keys(overrides).length > 0) yield* Console.log("
|
|
1609
|
+
if (Object.keys(overrides).length > 0) yield* Console.log("Loaded version overrides:", overrides);
|
|
1498
1610
|
const originalBranch = yield* git.branches.get;
|
|
1499
1611
|
yield* git.branches.checkout(config.branch.default);
|
|
1500
1612
|
const packages = yield* workspace.discoverWorkspacePackages.pipe(Effect.flatMap(mergePackageCommitsIntoPackages), Effect.flatMap((pkgs) => mergeCommitsAffectingGloballyIntoPackage(pkgs, config.globalCommitMode)));
|
|
1501
|
-
yield* Console.log(
|
|
1613
|
+
yield* Console.log(`Discovered ${packages.length} packages with commits.`);
|
|
1502
1614
|
yield* dependencyGraph.topologicalOrder(packages);
|
|
1503
1615
|
const releases = [];
|
|
1504
1616
|
if (versionPrompt.isEnabled) {
|
|
1505
|
-
yield* Console.log("\
|
|
1617
|
+
yield* Console.log("\nInteractive version selection enabled.\n");
|
|
1506
1618
|
versionPrompt.resetApplyToAll();
|
|
1507
1619
|
for (let i = 0; i < packages.length; i++) {
|
|
1508
1620
|
const pkg = packages[i];
|
|
@@ -1528,6 +1640,14 @@ function constructPrepareProgram(config) {
|
|
|
1528
1640
|
continue;
|
|
1529
1641
|
}
|
|
1530
1642
|
const result = yield* versionPrompt.promptForVersion(pkg, conventionalBump, remainingCount);
|
|
1643
|
+
if (result.cancelled) {
|
|
1644
|
+
yield* Console.log("\nCancelled by user.");
|
|
1645
|
+
if (startingBranch !== (yield* git.branches.get)) {
|
|
1646
|
+
yield* git.branches.checkout(startingBranch);
|
|
1647
|
+
yield* Console.log(`Switched back to "${startingBranch}".`);
|
|
1648
|
+
}
|
|
1649
|
+
return yield* Effect.fail(/* @__PURE__ */ new Error("Release preparation cancelled."));
|
|
1650
|
+
}
|
|
1531
1651
|
releases.push({
|
|
1532
1652
|
package: {
|
|
1533
1653
|
name: pkg.name,
|
|
@@ -1548,12 +1668,12 @@ function constructPrepareProgram(config) {
|
|
|
1548
1668
|
releases.push(...calculatedReleases);
|
|
1549
1669
|
}
|
|
1550
1670
|
const releasesCount = releases.length;
|
|
1551
|
-
yield* Console.log(`\n
|
|
1671
|
+
yield* Console.log(`\n${releasesCount} package${releasesCount === 1 ? "" : "s"} will be released.`);
|
|
1552
1672
|
yield* git.branches.checkout(originalBranch);
|
|
1553
|
-
yield* Console.log("
|
|
1673
|
+
yield* Console.log("Updating package.json files...");
|
|
1554
1674
|
yield* packageUpdater.applyReleases(packages, releases);
|
|
1555
|
-
yield* Console.log("
|
|
1556
|
-
yield* Console.log("
|
|
1675
|
+
yield* Console.log("package.json files updated.");
|
|
1676
|
+
yield* Console.log("Generating changelogs...");
|
|
1557
1677
|
const changelogFiles = [];
|
|
1558
1678
|
for (const release of releases) {
|
|
1559
1679
|
const pkg = packages.find((p) => p.name === release.package.name);
|
|
@@ -1567,28 +1687,28 @@ function constructPrepareProgram(config) {
|
|
|
1567
1687
|
});
|
|
1568
1688
|
changelogFiles.push(result.filePath);
|
|
1569
1689
|
}
|
|
1570
|
-
yield* Console.log(
|
|
1690
|
+
yield* Console.log(`Generated ${changelogFiles.length} changelog file${changelogFiles.length === 1 ? "" : "s"}.`);
|
|
1571
1691
|
const filesToStage = [...releases.map((r) => `${r.package.path}/package.json`), ...changelogFiles];
|
|
1572
|
-
yield* Console.log(
|
|
1692
|
+
yield* Console.log(`Staging ${filesToStage.length} file${filesToStage.length === 1 ? "" : "s"}...`);
|
|
1573
1693
|
yield* git.commits.stage(filesToStage);
|
|
1574
1694
|
const commitMessage = `chore(release): prepare release
|
|
1575
1695
|
|
|
1576
1696
|
${releasesCount} package${releasesCount === 1 ? "" : "s"} updated:
|
|
1577
1697
|
${releases.map((r) => ` - ${r.package.name}@${r.newVersion}`).join("\n")}`;
|
|
1578
|
-
yield* Console.log("
|
|
1698
|
+
yield* Console.log("Creating commit...");
|
|
1579
1699
|
yield* git.commits.write(commitMessage);
|
|
1580
|
-
yield* Console.log("
|
|
1581
|
-
yield* Console.log(
|
|
1700
|
+
yield* Console.log("Commit created.");
|
|
1701
|
+
yield* Console.log(`Pushing to "${config.branch.release}"...`);
|
|
1582
1702
|
if (isNewRelease && !branchExists) yield* git.commits.push(config.branch.release);
|
|
1583
1703
|
else yield* git.commits.forcePush(config.branch.release);
|
|
1584
|
-
yield* Console.log(
|
|
1704
|
+
yield* Console.log(`Push complete.`);
|
|
1585
1705
|
const prBody = yield* github.generateReleasePRBody(releases.map((r) => ({
|
|
1586
1706
|
packageName: r.package.name,
|
|
1587
1707
|
version: r.newVersion,
|
|
1588
1708
|
previousVersion: r.package.version
|
|
1589
1709
|
})));
|
|
1590
1710
|
if (isNewRelease) {
|
|
1591
|
-
yield* Console.log("
|
|
1711
|
+
yield* Console.log("Creating release pull request...");
|
|
1592
1712
|
releasePullRequest = yield* github.createPullRequest({
|
|
1593
1713
|
title: config.pullRequest.title,
|
|
1594
1714
|
body: prBody,
|
|
@@ -1596,15 +1716,17 @@ ${releases.map((r) => ` - ${r.package.name}@${r.newVersion}`).join("\n")}`;
|
|
|
1596
1716
|
base: config.branch.default,
|
|
1597
1717
|
draft: true
|
|
1598
1718
|
});
|
|
1599
|
-
yield* Console.log(
|
|
1719
|
+
yield* Console.log(`Release pull request #${releasePullRequest.number} created.`);
|
|
1600
1720
|
} else {
|
|
1601
|
-
yield* Console.log("
|
|
1721
|
+
yield* Console.log("Updating pull request...");
|
|
1602
1722
|
yield* github.updatePullRequest(releasePullRequest.number, { body: prBody });
|
|
1603
|
-
yield* Console.log("
|
|
1723
|
+
yield* Console.log("Pull request updated.");
|
|
1724
|
+
}
|
|
1725
|
+
yield* Console.log(`\nRelease preparation complete! View PR: #${releasePullRequest.number}`);
|
|
1726
|
+
if (startingBranch !== (yield* git.branches.get)) {
|
|
1727
|
+
yield* git.branches.checkout(startingBranch);
|
|
1728
|
+
yield* Console.log(`Switched back to "${startingBranch}".`);
|
|
1604
1729
|
}
|
|
1605
|
-
yield* Console.log(`\nš Release preparation complete! View PR: #${releasePullRequest.number}`);
|
|
1606
|
-
yield* git.branches.checkout(config.branch.default);
|
|
1607
|
-
yield* Console.log(`ā
Switched back to "${config.branch.default}".`);
|
|
1608
1730
|
});
|
|
1609
1731
|
}
|
|
1610
1732
|
|
|
@@ -1633,9 +1755,9 @@ function constructPublishProgram(config) {
|
|
|
1633
1755
|
yield* git.workspace.assertWorkspaceReady;
|
|
1634
1756
|
const currentBranch = yield* git.branches.get;
|
|
1635
1757
|
if (currentBranch !== config.branch.default) return yield* Effect.fail(/* @__PURE__ */ new Error(`Publish must be run on the default branch "${config.branch.default}". Current branch: "${currentBranch}"`));
|
|
1636
|
-
yield* Console.log(
|
|
1758
|
+
yield* Console.log(`On default branch "${config.branch.default}".`);
|
|
1637
1759
|
const publicPackages = (yield* workspace.discoverWorkspacePackages).filter((pkg) => !pkg.packageJson.private);
|
|
1638
|
-
yield* Console.log(
|
|
1760
|
+
yield* Console.log(`Found ${publicPackages.length} public package${publicPackages.length === 1 ? "" : "s"} to check.`);
|
|
1639
1761
|
const orderedPackages = yield* dependencyGraph.topologicalOrder(publicPackages);
|
|
1640
1762
|
const results = [];
|
|
1641
1763
|
for (const updateOrder of orderedPackages) {
|
|
@@ -1643,7 +1765,7 @@ function constructPublishProgram(config) {
|
|
|
1643
1765
|
const version = pkg.version;
|
|
1644
1766
|
const tagName = `${pkg.name}@${version}`;
|
|
1645
1767
|
if (yield* npm.versionExists(pkg.name, version)) {
|
|
1646
|
-
yield* Console.log(
|
|
1768
|
+
yield* Console.log(`Skipping ${pkg.name}@${version} - already published.`);
|
|
1647
1769
|
results.push({
|
|
1648
1770
|
packageName: pkg.name,
|
|
1649
1771
|
version,
|
|
@@ -1652,11 +1774,11 @@ function constructPublishProgram(config) {
|
|
|
1652
1774
|
});
|
|
1653
1775
|
continue;
|
|
1654
1776
|
}
|
|
1655
|
-
yield* Console.log(
|
|
1777
|
+
yield* Console.log(`Building ${pkg.name}...`);
|
|
1656
1778
|
yield* buildPackage(pkg.path);
|
|
1657
|
-
yield* Console.log(
|
|
1779
|
+
yield* Console.log(`Build complete for ${pkg.name}.`);
|
|
1658
1780
|
const distTag = getDistTag(version);
|
|
1659
|
-
yield* Console.log(
|
|
1781
|
+
yield* Console.log(`Publishing ${pkg.name}@${version} with tag "${distTag}"...`);
|
|
1660
1782
|
const publishResult = yield* npm.publish({
|
|
1661
1783
|
packagePath: pkg.path,
|
|
1662
1784
|
tagName: distTag,
|
|
@@ -1668,13 +1790,13 @@ function constructPublishProgram(config) {
|
|
|
1668
1790
|
error: err
|
|
1669
1791
|
})));
|
|
1670
1792
|
if (publishResult.success) {
|
|
1671
|
-
yield* Console.log(
|
|
1793
|
+
yield* Console.log(`Published ${pkg.name}@${version}.`);
|
|
1672
1794
|
if (!config.dryRun) {
|
|
1673
|
-
yield* Console.log(
|
|
1795
|
+
yield* Console.log(`Creating tag ${tagName}...`);
|
|
1674
1796
|
yield* git.tags.create(tagName, `Release ${tagName}`);
|
|
1675
1797
|
yield* git.tags.push(tagName);
|
|
1676
|
-
yield* Console.log(
|
|
1677
|
-
} else yield* Console.log(
|
|
1798
|
+
yield* Console.log(`Tag ${tagName} created and pushed.`);
|
|
1799
|
+
} else yield* Console.log(`[Dry Run] Would create and push tag ${tagName}.`);
|
|
1678
1800
|
results.push({
|
|
1679
1801
|
packageName: pkg.name,
|
|
1680
1802
|
version,
|
|
@@ -1682,7 +1804,7 @@ function constructPublishProgram(config) {
|
|
|
1682
1804
|
});
|
|
1683
1805
|
} else {
|
|
1684
1806
|
const error = publishResult.error;
|
|
1685
|
-
yield* Console.log(
|
|
1807
|
+
yield* Console.log(`Failed to publish ${pkg.name}@${version}: ${error.message}`);
|
|
1686
1808
|
results.push({
|
|
1687
1809
|
packageName: pkg.name,
|
|
1688
1810
|
version,
|
|
@@ -1694,17 +1816,17 @@ function constructPublishProgram(config) {
|
|
|
1694
1816
|
const published = results.filter((r) => r.status === "published");
|
|
1695
1817
|
const skipped = results.filter((r) => r.status === "skipped");
|
|
1696
1818
|
const failed = results.filter((r) => r.status === "failed");
|
|
1697
|
-
yield* Console.log("\
|
|
1819
|
+
yield* Console.log("\nPublish Summary:");
|
|
1698
1820
|
yield* Console.log(` Published: ${published.length}`);
|
|
1699
1821
|
yield* Console.log(` Skipped: ${skipped.length}`);
|
|
1700
1822
|
yield* Console.log(` Failed: ${failed.length}`);
|
|
1701
1823
|
if (failed.length > 0) {
|
|
1702
|
-
yield* Console.log("\
|
|
1824
|
+
yield* Console.log("\nFailed packages:");
|
|
1703
1825
|
for (const f of failed) yield* Console.log(` - ${f.packageName}@${f.version}: ${f.reason}`);
|
|
1704
1826
|
return yield* Effect.fail(/* @__PURE__ */ new Error("Some packages failed to publish."));
|
|
1705
1827
|
}
|
|
1706
|
-
if (published.length === 0 && skipped.length > 0) yield* Console.log("\
|
|
1707
|
-
else if (published.length > 0) yield* Console.log("\
|
|
1828
|
+
if (published.length === 0 && skipped.length > 0) yield* Console.log("\nAll packages were already published.");
|
|
1829
|
+
else if (published.length > 0) yield* Console.log("\nPublish complete!");
|
|
1708
1830
|
});
|
|
1709
1831
|
}
|
|
1710
1832
|
|
|
@@ -1790,10 +1912,10 @@ function constructVerifyProgram(config) {
|
|
|
1790
1912
|
yield* git.workspace.assertWorkspaceReady;
|
|
1791
1913
|
const releasePullRequest = yield* github.getPullRequestByBranch(config.branch.release);
|
|
1792
1914
|
if (!releasePullRequest || !releasePullRequest.head) return yield* Effect.fail(/* @__PURE__ */ new Error(`Release pull request for branch "${config.branch.release}" does not exist.`));
|
|
1793
|
-
yield* Console.log(
|
|
1915
|
+
yield* Console.log(`Release pull request #${releasePullRequest.number} exists.`);
|
|
1794
1916
|
if ((yield* git.branches.get) !== config.branch.default) {
|
|
1795
1917
|
yield* git.branches.checkout(config.branch.default);
|
|
1796
|
-
yield* Console.log(
|
|
1918
|
+
yield* Console.log(`Checked out to default branch "${config.branch.default}".`);
|
|
1797
1919
|
}
|
|
1798
1920
|
const overrides = yield* loadOverrides({
|
|
1799
1921
|
sha: releasePullRequest.head.sha,
|
|
@@ -1813,8 +1935,8 @@ function constructVerifyProgram(config) {
|
|
|
1813
1935
|
branchSnapshots.set(pkg.name, snapshot);
|
|
1814
1936
|
}
|
|
1815
1937
|
const drift = findDrift(packages, releases, branchSnapshots);
|
|
1816
|
-
if (drift.length === 0) yield* Console.log("
|
|
1817
|
-
else yield* Console.log("
|
|
1938
|
+
if (drift.length === 0) yield* Console.log("Release branch is in sync with expected releases.");
|
|
1939
|
+
else yield* Console.log("Release branch is out of sync:", drift);
|
|
1818
1940
|
const status = drift.length === 0 ? {
|
|
1819
1941
|
state: "success",
|
|
1820
1942
|
description: "Release artifacts in sync",
|