versionary 0.12.0 → 0.13.0
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/README.md +4 -2
- package/dist/cli/index.js +15 -15
- package/dist/release/changelog.d.ts +3 -1
- package/dist/release/changelog.js +10 -4
- package/dist/release/plan.d.ts +6 -2
- package/dist/release/plan.js +6 -1
- package/dist/release/pr.d.ts +11 -3
- package/dist/release/pr.js +49 -25
- package/dist/release/release.d.ts +12 -3
- package/dist/release/release.js +71 -28
- package/dist/release/semver.js +14 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -86,8 +86,10 @@ Current ecosystem policy defaults:
|
|
|
86
86
|
|
|
87
87
|
- changelog source for publish:
|
|
88
88
|
- root target uses root `changelog-file`
|
|
89
|
-
- package target uses
|
|
90
|
-
|
|
89
|
+
- package target uses package changelog defaults:
|
|
90
|
+
- `packages.<path>.changelog-file` when configured
|
|
91
|
+
- otherwise `NEWS.md` for R targets or `CHANGELOG.md` for other targets at
|
|
92
|
+
`<package-path>/<default-file>`
|
|
91
93
|
- lockfiles:
|
|
92
94
|
- Node strategy updates root `package-lock.json`/`npm-shrinkwrap.json` when
|
|
93
95
|
present
|
package/dist/cli/index.js
CHANGED
|
@@ -52,7 +52,7 @@ async function main() {
|
|
|
52
52
|
}).trim();
|
|
53
53
|
if ((0, pr_js_1.isReleaseCommitMessage)(commitMessage)) {
|
|
54
54
|
if (flags["dry-run"] && !flags.json) {
|
|
55
|
-
const release = await (0, release_js_1.
|
|
55
|
+
const release = await (0, release_js_1.runReleaseDetailed)(process.cwd(), {
|
|
56
56
|
logger,
|
|
57
57
|
"dry-run": true,
|
|
58
58
|
});
|
|
@@ -62,7 +62,7 @@ async function main() {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
if (flags.json) {
|
|
65
|
-
const release = await (0, release_js_1.
|
|
65
|
+
const release = await (0, release_js_1.runReleaseDetailed)(process.cwd(), {
|
|
66
66
|
logger,
|
|
67
67
|
"dry-run": flags["dry-run"],
|
|
68
68
|
});
|
|
@@ -93,11 +93,11 @@ async function main() {
|
|
|
93
93
|
});
|
|
94
94
|
return 0;
|
|
95
95
|
}
|
|
96
|
-
const message = await (0, release_js_1.
|
|
96
|
+
const message = await (0, release_js_1.runRelease)(process.cwd());
|
|
97
97
|
console.log(message);
|
|
98
98
|
return 0;
|
|
99
99
|
}
|
|
100
|
-
const plan = (0, plan_js_1.
|
|
100
|
+
const plan = (0, plan_js_1.createReleasePlan)();
|
|
101
101
|
if (!plan.nextVersion) {
|
|
102
102
|
const message = "No releasable commits found. Nothing to do.";
|
|
103
103
|
if (flags.json) {
|
|
@@ -140,9 +140,9 @@ async function main() {
|
|
|
140
140
|
console.log(dryRunMessage);
|
|
141
141
|
return 0;
|
|
142
142
|
}
|
|
143
|
-
const pr = (0, pr_js_1.
|
|
143
|
+
const pr = (0, pr_js_1.prepareReleasePr)(process.cwd(), { logger });
|
|
144
144
|
(0, pr_js_1.pushReleaseBranch)(process.cwd(), pr.branch);
|
|
145
|
-
const reviewResult = await (0, pr_js_1.
|
|
145
|
+
const reviewResult = await (0, pr_js_1.openOrUpdateReviewRequest)(process.cwd(), pr.branch, pr.title, pr.version, pr.previousVersion, pr.commits, pr.plan, { logger });
|
|
146
146
|
const message = `Prepared release PR branch ${pr.branch}`;
|
|
147
147
|
if (flags.json) {
|
|
148
148
|
emitJson({
|
|
@@ -165,18 +165,18 @@ async function main() {
|
|
|
165
165
|
return printVerifyResult();
|
|
166
166
|
}
|
|
167
167
|
if (command === "plan") {
|
|
168
|
-
const plan = (0, plan_js_1.
|
|
168
|
+
const plan = (0, plan_js_1.createReleasePlan)();
|
|
169
169
|
console.log(JSON.stringify(plan, null, 2));
|
|
170
170
|
return 0;
|
|
171
171
|
}
|
|
172
172
|
if (command === "changelog") {
|
|
173
173
|
const write = args.includes("--write");
|
|
174
|
-
const plan = (0, plan_js_1.
|
|
174
|
+
const plan = (0, plan_js_1.createReleasePlan)();
|
|
175
175
|
if (!plan.nextVersion) {
|
|
176
176
|
console.log("No releasable commits found.");
|
|
177
177
|
return 0;
|
|
178
178
|
}
|
|
179
|
-
const section = (0, changelog_js_1.
|
|
179
|
+
const section = (0, changelog_js_1.renderReleasePlanChangelog)(plan);
|
|
180
180
|
if (!write) {
|
|
181
181
|
console.log(section);
|
|
182
182
|
return 0;
|
|
@@ -187,7 +187,7 @@ async function main() {
|
|
|
187
187
|
}
|
|
188
188
|
if (command === "pr") {
|
|
189
189
|
if (flags["dry-run"]) {
|
|
190
|
-
const plan = (0, plan_js_1.
|
|
190
|
+
const plan = (0, plan_js_1.createReleasePlan)();
|
|
191
191
|
if (!plan.nextVersion) {
|
|
192
192
|
console.log("No releasable commits found. Nothing to do.");
|
|
193
193
|
return 0;
|
|
@@ -195,9 +195,9 @@ async function main() {
|
|
|
195
195
|
console.log(`Dry run: would prepare release PR branch ${plan.releaseBranchPrefix} for ${plan.nextVersion}`);
|
|
196
196
|
return 0;
|
|
197
197
|
}
|
|
198
|
-
const pr = (0, pr_js_1.
|
|
198
|
+
const pr = (0, pr_js_1.prepareReleasePr)(process.cwd(), { logger: console });
|
|
199
199
|
(0, pr_js_1.pushReleaseBranch)(process.cwd(), pr.branch);
|
|
200
|
-
const reviewResult = await (0, pr_js_1.
|
|
200
|
+
const reviewResult = await (0, pr_js_1.openOrUpdateReviewRequest)(process.cwd(), pr.branch, pr.title, pr.version, pr.previousVersion, pr.commits, pr.plan);
|
|
201
201
|
console.log(`Prepared release PR branch ${pr.branch}`);
|
|
202
202
|
console.log(`Title: ${pr.title}`);
|
|
203
203
|
console.log(reviewResult);
|
|
@@ -205,7 +205,7 @@ async function main() {
|
|
|
205
205
|
}
|
|
206
206
|
if (command === "release") {
|
|
207
207
|
if (flags["dry-run"]) {
|
|
208
|
-
const result = await (0, release_js_1.
|
|
208
|
+
const result = await (0, release_js_1.runReleaseDetailed)(process.cwd(), {
|
|
209
209
|
logger,
|
|
210
210
|
"dry-run": true,
|
|
211
211
|
});
|
|
@@ -220,7 +220,7 @@ async function main() {
|
|
|
220
220
|
}
|
|
221
221
|
return 0;
|
|
222
222
|
}
|
|
223
|
-
const message = await (0, release_js_1.
|
|
223
|
+
const message = await (0, release_js_1.runRelease)(process.cwd());
|
|
224
224
|
console.log(message);
|
|
225
225
|
return 0;
|
|
226
226
|
}
|
|
@@ -228,7 +228,7 @@ async function main() {
|
|
|
228
228
|
console.log("Commands:");
|
|
229
229
|
console.log(" run [--json] [--dry-run] Auto-dispatch release PR/update or release publish by context");
|
|
230
230
|
console.log(" verify Validate config and basic repository shape");
|
|
231
|
-
console.log(" plan Print release plan
|
|
231
|
+
console.log(" plan Print release plan");
|
|
232
232
|
console.log(" changelog [--write] Print or write changelog section");
|
|
233
233
|
console.log(" pr [--dry-run] Prepare release PR commit and branch");
|
|
234
234
|
console.log(" release [--dry-run] Publish release metadata for release commit context");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ParsedCommit } from "../git/commits.js";
|
|
2
2
|
import type { VersionaryChangelogFormat } from "../types/config.js";
|
|
3
|
-
import type { SimplePlan } from "./plan.js";
|
|
3
|
+
import type { ReleasePlan, SimplePlan } from "./plan.js";
|
|
4
4
|
export declare function renderSimpleReleaseNotes(input: {
|
|
5
5
|
currentVersion: string;
|
|
6
6
|
nextVersion: string;
|
|
@@ -13,6 +13,8 @@ export declare function renderSimpleReleaseNotes(input: {
|
|
|
13
13
|
}, options?: {
|
|
14
14
|
includeFooter?: boolean;
|
|
15
15
|
}): string;
|
|
16
|
+
export declare function renderReleasePlanChangelog(plan: ReleasePlan): string;
|
|
17
|
+
/** @deprecated Use renderReleasePlanChangelog. */
|
|
16
18
|
export declare function renderSimpleChangelog(plan: SimplePlan): string;
|
|
17
19
|
export declare function renderPackageChangelogSection(input: {
|
|
18
20
|
currentVersion: string;
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.renderSimpleReleaseNotes = renderSimpleReleaseNotes;
|
|
7
|
+
exports.renderReleasePlanChangelog = renderReleasePlanChangelog;
|
|
7
8
|
exports.renderSimpleChangelog = renderSimpleChangelog;
|
|
8
9
|
exports.renderPackageChangelogSection = renderPackageChangelogSection;
|
|
9
10
|
exports.prependChangelog = prependChangelog;
|
|
@@ -112,7 +113,7 @@ function renderSimpleReleaseNotes(input, options = {}) {
|
|
|
112
113
|
}
|
|
113
114
|
return lines.join("\n");
|
|
114
115
|
}
|
|
115
|
-
function
|
|
116
|
+
function renderReleasePlanChangelog(plan) {
|
|
116
117
|
if (!plan.nextVersion) {
|
|
117
118
|
return "";
|
|
118
119
|
}
|
|
@@ -145,6 +146,10 @@ function renderSimpleChangelog(plan) {
|
|
|
145
146
|
dependencies,
|
|
146
147
|
});
|
|
147
148
|
}
|
|
149
|
+
/** @deprecated Use renderReleasePlanChangelog. */
|
|
150
|
+
function renderSimpleChangelog(plan) {
|
|
151
|
+
return renderReleasePlanChangelog(plan);
|
|
152
|
+
}
|
|
148
153
|
function renderPackageChangelogSection(input) {
|
|
149
154
|
const repoUrl = (0, repo_url_js_1.resolveRepositoryWebBaseUrl)(input.cwd ?? process.cwd());
|
|
150
155
|
const header = repoUrl
|
|
@@ -172,15 +177,16 @@ function prependChangelog(cwd, changelogFile, section, format = "markdown-change
|
|
|
172
177
|
? node_fs_1.default.readFileSync(changelogPath, "utf8")
|
|
173
178
|
: "";
|
|
174
179
|
if (format === "r-news") {
|
|
175
|
-
const
|
|
176
|
-
const
|
|
180
|
+
const bodyWithoutDevHeader = existing.replace(/^#\s+.+\s+\(development version\)\s*(?:\r?\n)*/u, "");
|
|
181
|
+
const separator = bodyWithoutDevHeader.length > 0 ? "\n\n" : "";
|
|
182
|
+
const next = `${`${section}${separator}${bodyWithoutDevHeader}`.trimEnd()}\n`;
|
|
177
183
|
node_fs_1.default.writeFileSync(changelogPath, next, "utf8");
|
|
178
184
|
return;
|
|
179
185
|
}
|
|
180
186
|
const heading = "# Changelog\n\n";
|
|
181
187
|
const bodyWithoutHeading = existing.replace(/^# Changelog\s*/u, "");
|
|
182
188
|
const separator = existing.length > 0 ? "\n" : "";
|
|
183
|
-
const next = `${heading}${section}${separator}${bodyWithoutHeading}`.trimEnd()
|
|
189
|
+
const next = `${`${heading}${section}${separator}${bodyWithoutHeading}`.trimEnd()}\n`;
|
|
184
190
|
node_fs_1.default.writeFileSync(changelogPath, next, "utf8");
|
|
185
191
|
}
|
|
186
192
|
function renderRNewsReleaseNotes(input) {
|
package/dist/release/plan.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ParsedCommit } from "../git/commits.js";
|
|
2
2
|
import type { VersionaryChangelogFormat, VersionaryConfig } from "../types/config.js";
|
|
3
3
|
import { type ReleaseType } from "./semver.js";
|
|
4
|
-
export interface
|
|
4
|
+
export interface ReleasePlan {
|
|
5
5
|
mode: "simple";
|
|
6
6
|
releaseType: ReleaseType;
|
|
7
7
|
currentVersion: string;
|
|
@@ -22,6 +22,8 @@ export interface SimplePlan {
|
|
|
22
22
|
commits: ParsedCommit[];
|
|
23
23
|
}>;
|
|
24
24
|
}
|
|
25
|
+
/** @deprecated Use ReleasePlan. */
|
|
26
|
+
export type SimplePlan = ReleasePlan;
|
|
25
27
|
export declare function getChangelogDefaults(config: {
|
|
26
28
|
"release-type"?: VersionaryConfig["release-type"];
|
|
27
29
|
"changelog-file"?: VersionaryConfig["changelog-file"];
|
|
@@ -30,4 +32,6 @@ export declare function getChangelogDefaults(config: {
|
|
|
30
32
|
changelogFile: string;
|
|
31
33
|
changelogFormat: VersionaryChangelogFormat;
|
|
32
34
|
};
|
|
33
|
-
export declare function
|
|
35
|
+
export declare function createReleasePlan(cwd?: string): ReleasePlan;
|
|
36
|
+
/** @deprecated Use createReleasePlan. */
|
|
37
|
+
export declare function createSimplePlan(cwd?: string): ReleasePlan;
|
package/dist/release/plan.js
CHANGED
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getChangelogDefaults = getChangelogDefaults;
|
|
7
|
+
exports.createReleasePlan = createReleasePlan;
|
|
7
8
|
exports.createSimplePlan = createSimplePlan;
|
|
8
9
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
10
|
const node_path_1 = __importDefault(require("node:path"));
|
|
@@ -23,7 +24,7 @@ function getChangelogDefaults(config) {
|
|
|
23
24
|
(changelogFormat === "r-news" ? "NEWS.md" : "CHANGELOG.md");
|
|
24
25
|
return { changelogFile, changelogFormat };
|
|
25
26
|
}
|
|
26
|
-
function
|
|
27
|
+
function createReleasePlan(cwd = process.cwd()) {
|
|
27
28
|
const loaded = (0, load_config_js_1.loadConfig)(cwd);
|
|
28
29
|
const strategy = (0, resolve_js_1.resolveVersionStrategy)(loaded.config);
|
|
29
30
|
const versionFile = strategy.getVersionFile(loaded.config);
|
|
@@ -189,3 +190,7 @@ function createSimplePlan(cwd = process.cwd()) {
|
|
|
189
190
|
packages: adjustedPackages,
|
|
190
191
|
};
|
|
191
192
|
}
|
|
193
|
+
/** @deprecated Use createReleasePlan. */
|
|
194
|
+
function createSimplePlan(cwd = process.cwd()) {
|
|
195
|
+
return createReleasePlan(cwd);
|
|
196
|
+
}
|
package/dist/release/pr.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ParsedCommit } from "../git/commits.js";
|
|
2
2
|
import type { VersionaryPluginContext } from "../types/plugins.js";
|
|
3
|
-
import { type SimplePlan } from "./plan.js";
|
|
3
|
+
import { type ReleasePlan, type SimplePlan } from "./plan.js";
|
|
4
4
|
export declare function splitSafeDirtyFiles(files: string[]): {
|
|
5
5
|
ignored: string[];
|
|
6
6
|
blocking: string[];
|
|
7
7
|
};
|
|
8
|
-
export declare function
|
|
8
|
+
export declare function prepareReleasePr(cwd?: string, options?: {
|
|
9
9
|
logger?: VersionaryPluginContext["logger"];
|
|
10
10
|
}): {
|
|
11
11
|
branch: string;
|
|
@@ -13,9 +13,17 @@ export declare function prepareSimpleReleasePr(cwd?: string, options?: {
|
|
|
13
13
|
version: string;
|
|
14
14
|
previousVersion: string;
|
|
15
15
|
commits: ParsedCommit[];
|
|
16
|
-
plan:
|
|
16
|
+
plan: ReleasePlan;
|
|
17
17
|
};
|
|
18
18
|
export declare function renderSimpleReviewRequestBody(version: string, previousVersion: string, commits: ParsedCommit[], plan?: SimplePlan | null, cwd?: string): string;
|
|
19
|
+
export declare function openOrUpdateReviewRequest(cwd: string, branch: string, title: string, version: string, previousVersion: string, commits: ParsedCommit[], plan?: SimplePlan | null, options?: {
|
|
20
|
+
logger?: VersionaryPluginContext["logger"];
|
|
21
|
+
}): Promise<string>;
|
|
22
|
+
/** @deprecated Use prepareReleasePr. */
|
|
23
|
+
export declare function prepareSimpleReleasePr(cwd?: string, options?: {
|
|
24
|
+
logger?: VersionaryPluginContext["logger"];
|
|
25
|
+
}): ReturnType<typeof prepareReleasePr>;
|
|
26
|
+
/** @deprecated Use openOrUpdateReviewRequest. */
|
|
19
27
|
export declare function openOrUpdateSimpleReviewRequest(cwd: string, branch: string, title: string, version: string, previousVersion: string, commits: ParsedCommit[], plan?: SimplePlan | null, options?: {
|
|
20
28
|
logger?: VersionaryPluginContext["logger"];
|
|
21
29
|
}): Promise<string>;
|
package/dist/release/pr.js
CHANGED
|
@@ -4,8 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.splitSafeDirtyFiles = splitSafeDirtyFiles;
|
|
7
|
-
exports.
|
|
7
|
+
exports.prepareReleasePr = prepareReleasePr;
|
|
8
8
|
exports.renderSimpleReviewRequestBody = renderSimpleReviewRequestBody;
|
|
9
|
+
exports.openOrUpdateReviewRequest = openOrUpdateReviewRequest;
|
|
10
|
+
exports.prepareSimpleReleasePr = prepareSimpleReleasePr;
|
|
9
11
|
exports.openOrUpdateSimpleReviewRequest = openOrUpdateSimpleReviewRequest;
|
|
10
12
|
exports.pushReleaseBranch = pushReleaseBranch;
|
|
11
13
|
exports.isReleaseCommitMessage = isReleaseCommitMessage;
|
|
@@ -202,8 +204,8 @@ function formatReleaseCommitTitle(releaseTargets) {
|
|
|
202
204
|
}
|
|
203
205
|
return `chore(release): ${tags[0]} (+${tags.length - 1} more)`;
|
|
204
206
|
}
|
|
205
|
-
function
|
|
206
|
-
const plan = (0, plan_js_1.
|
|
207
|
+
function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
208
|
+
const plan = (0, plan_js_1.createReleasePlan)(cwd);
|
|
207
209
|
const loaded = (0, load_config_js_1.loadConfig)(cwd);
|
|
208
210
|
const strategy = (0, resolve_js_1.resolveVersionStrategy)(loaded.config);
|
|
209
211
|
if (!plan.nextVersion) {
|
|
@@ -253,7 +255,7 @@ function prepareSimpleReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
253
255
|
const updatedArtifactFiles = (0, artifact_rules_js_1.applyConfiguredArtifactRules)(cwd, loaded.config, plan);
|
|
254
256
|
const updatedRustLockFiles = ensureCargoLockUpToDate(cwd);
|
|
255
257
|
const packageReleaseMetadata = buildPackageReleaseMetadata(cwd, plan, loaded.config);
|
|
256
|
-
const section = (0, changelog_js_1.
|
|
258
|
+
const section = (0, changelog_js_1.renderReleasePlanChangelog)(plan);
|
|
257
259
|
(0, changelog_js_1.prependChangelog)(cwd, plan.changelogFile, section, plan.changelogFormat);
|
|
258
260
|
const updatedChangelogFiles = [plan.changelogFile];
|
|
259
261
|
for (const packagePlan of plan.packages ?? []) {
|
|
@@ -261,10 +263,11 @@ function prepareSimpleReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
261
263
|
continue;
|
|
262
264
|
}
|
|
263
265
|
const packageConfig = loaded.config.packages?.[packagePlan.path] ?? {};
|
|
264
|
-
const packageChangelogFile =
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
266
|
+
const { changelogFile: packageChangelogFile } = (0, plan_js_1.getChangelogDefaults)({
|
|
267
|
+
"release-type": packageConfig["release-type"] ?? loaded.config["release-type"],
|
|
268
|
+
"changelog-file": packageConfig["changelog-file"] ?? loaded.config["changelog-file"],
|
|
269
|
+
"changelog-format": packageConfig["changelog-format"] ?? loaded.config["changelog-format"],
|
|
270
|
+
});
|
|
268
271
|
const packageMetadata = packageReleaseMetadata[packagePlan.path];
|
|
269
272
|
if (!packageMetadata) {
|
|
270
273
|
continue;
|
|
@@ -342,9 +345,28 @@ function renderSimpleReviewRequestBody(version, previousVersion, commits, plan =
|
|
|
342
345
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
343
346
|
return directSources;
|
|
344
347
|
};
|
|
348
|
+
const relabelSectionHeader = (notes, packageLabel, nextVersion) => {
|
|
349
|
+
const linkedHeader = notes.match(/^##\s+\[([^\]]+)\]\(([^)]+)\)\s+\(([^)]+)\)/u);
|
|
350
|
+
if (linkedHeader) {
|
|
351
|
+
const [, , compareUrl, date] = linkedHeader;
|
|
352
|
+
return notes.replace(/^##\s+\[[^\]]+\]\([^)]+\)\s+\([^)]+\)/u, `## [${packageLabel}: ${nextVersion}](${compareUrl}) (${date})`);
|
|
353
|
+
}
|
|
354
|
+
const plainHeader = notes.match(/^##\s+([^\s]+)\s+\(([^)]+)\)/u);
|
|
355
|
+
if (plainHeader) {
|
|
356
|
+
const [, , date] = plainHeader;
|
|
357
|
+
return notes.replace(/^##\s+[^\s]+\s+\([^)]+\)/u, `## ${packageLabel}: ${nextVersion} (${date})`);
|
|
358
|
+
}
|
|
359
|
+
return notes;
|
|
360
|
+
};
|
|
345
361
|
if (plan?.packages && plan.packages.length > 1) {
|
|
346
|
-
const sections =
|
|
347
|
-
|
|
362
|
+
const sections = [];
|
|
363
|
+
const rootPackage = plan.packages.find((pkg) => pkg.path === "." && pkg.nextVersion);
|
|
364
|
+
if (rootPackage?.nextVersion) {
|
|
365
|
+
const rootNotes = (0, changelog_js_1.renderReleasePlanChangelog)(plan);
|
|
366
|
+
sections.push(relabelSectionHeader(rootNotes, formatPackageLabel("."), rootPackage.nextVersion));
|
|
367
|
+
}
|
|
368
|
+
const packageSections = plan.packages
|
|
369
|
+
.filter((pkg) => pkg.path !== "." && pkg.nextVersion)
|
|
348
370
|
.map((pkg) => {
|
|
349
371
|
const packageLabel = formatPackageLabel(pkg.path);
|
|
350
372
|
const propagatedDependencies = findPropagatedDependencies(pkg.path, plan.packages ?? []);
|
|
@@ -355,20 +377,14 @@ function renderSimpleReviewRequestBody(version, previousVersion, commits, plan =
|
|
|
355
377
|
cwd,
|
|
356
378
|
dependencies: propagatedDependencies,
|
|
357
379
|
}, { includeFooter: false });
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
return notes.replace(/^##\s+[^\s]+\s+\([^)]+\)/u, `## ${packageLabel}: ${pkg.nextVersion ?? ""} (${date})`);
|
|
367
|
-
}
|
|
368
|
-
return notes;
|
|
369
|
-
})
|
|
370
|
-
.join("\n\n");
|
|
371
|
-
return `${sections}\n\nThis PR was generated by Versionary.`;
|
|
380
|
+
return relabelSectionHeader(notes, packageLabel, pkg.nextVersion ?? "");
|
|
381
|
+
});
|
|
382
|
+
sections.push(...packageSections);
|
|
383
|
+
const bodySections = sections.join("\n\n");
|
|
384
|
+
if (bodySections.length === 0) {
|
|
385
|
+
return "This PR was generated by Versionary.";
|
|
386
|
+
}
|
|
387
|
+
return `${bodySections}\n\nThis PR was generated by Versionary.`;
|
|
372
388
|
}
|
|
373
389
|
return (0, changelog_js_1.renderSimpleReleaseNotes)({
|
|
374
390
|
currentVersion: previousVersion,
|
|
@@ -377,7 +393,7 @@ function renderSimpleReviewRequestBody(version, previousVersion, commits, plan =
|
|
|
377
393
|
cwd,
|
|
378
394
|
}, { includeFooter: true });
|
|
379
395
|
}
|
|
380
|
-
async function
|
|
396
|
+
async function openOrUpdateReviewRequest(cwd, branch, title, version, previousVersion, commits, plan = null, options = {}) {
|
|
381
397
|
const loaded = (0, load_config_js_1.loadConfig)(cwd);
|
|
382
398
|
const releaseFlow = loaded.config["review-mode"] ?? "pr";
|
|
383
399
|
if (releaseFlow === "direct") {
|
|
@@ -396,6 +412,14 @@ async function openOrUpdateSimpleReviewRequest(cwd, branch, title, version, prev
|
|
|
396
412
|
});
|
|
397
413
|
return result.url;
|
|
398
414
|
}
|
|
415
|
+
/** @deprecated Use prepareReleasePr. */
|
|
416
|
+
function prepareSimpleReleasePr(cwd = process.cwd(), options = {}) {
|
|
417
|
+
return prepareReleasePr(cwd, options);
|
|
418
|
+
}
|
|
419
|
+
/** @deprecated Use openOrUpdateReviewRequest. */
|
|
420
|
+
async function openOrUpdateSimpleReviewRequest(cwd, branch, title, version, previousVersion, commits, plan = null, options = {}) {
|
|
421
|
+
return openOrUpdateReviewRequest(cwd, branch, title, version, previousVersion, commits, plan, options);
|
|
422
|
+
}
|
|
399
423
|
function pushReleaseBranch(cwd, branch) {
|
|
400
424
|
(0, node_child_process_1.execFileSync)("git", ["push", "--force-with-lease", "origin", branch], {
|
|
401
425
|
cwd,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { VersionaryConfig } from "../types/config.js";
|
|
2
2
|
import type { VersionaryPluginContext } from "../types/plugins.js";
|
|
3
|
+
export declare function extractReleaseNotes(content: string, version: string, changelogFormat: "markdown-changelog" | "r-news"): string;
|
|
3
4
|
export declare function resolveTargetChangelogFile(config: VersionaryConfig, rootChangelogFile: string, targetPath: string): string;
|
|
4
|
-
export declare function
|
|
5
|
-
export type
|
|
5
|
+
export declare function runRelease(cwd?: string): Promise<string>;
|
|
6
|
+
export type RunReleaseResult = {
|
|
6
7
|
action: "release-skipped";
|
|
7
8
|
reason: string;
|
|
8
9
|
} | {
|
|
@@ -22,8 +23,16 @@ export type SimpleRunReleaseResult = {
|
|
|
22
23
|
metadataStatus: "created" | "exists";
|
|
23
24
|
}[];
|
|
24
25
|
};
|
|
25
|
-
export interface
|
|
26
|
+
export interface RunReleaseOptions {
|
|
26
27
|
logger?: VersionaryPluginContext["logger"];
|
|
27
28
|
"dry-run"?: boolean;
|
|
28
29
|
}
|
|
30
|
+
export declare function runReleaseDetailed(cwd?: string, options?: RunReleaseOptions): Promise<RunReleaseResult>;
|
|
31
|
+
/** @deprecated Use RunReleaseResult. */
|
|
32
|
+
export type SimpleRunReleaseResult = RunReleaseResult;
|
|
33
|
+
/** @deprecated Use RunReleaseOptions. */
|
|
34
|
+
export type RunSimpleReleaseOptions = RunReleaseOptions;
|
|
35
|
+
/** @deprecated Use runRelease. */
|
|
36
|
+
export declare function runSimpleRelease(cwd?: string): Promise<string>;
|
|
37
|
+
/** @deprecated Use runReleaseDetailed. */
|
|
29
38
|
export declare function runSimpleReleaseDetailed(cwd?: string, options?: RunSimpleReleaseOptions): Promise<SimpleRunReleaseResult>;
|
package/dist/release/release.js
CHANGED
|
@@ -3,7 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.extractReleaseNotes = extractReleaseNotes;
|
|
6
7
|
exports.resolveTargetChangelogFile = resolveTargetChangelogFile;
|
|
8
|
+
exports.runRelease = runRelease;
|
|
9
|
+
exports.runReleaseDetailed = runReleaseDetailed;
|
|
7
10
|
exports.runSimpleRelease = runSimpleRelease;
|
|
8
11
|
exports.runSimpleReleaseDetailed = runSimpleReleaseDetailed;
|
|
9
12
|
const node_child_process_1 = require("node:child_process");
|
|
@@ -16,60 +19,91 @@ const plan_js_1 = require("./plan.js");
|
|
|
16
19
|
const pr_js_1 = require("./pr.js");
|
|
17
20
|
const recovery_js_1 = require("./recovery.js");
|
|
18
21
|
const state_js_1 = require("./state.js");
|
|
19
|
-
function
|
|
20
|
-
return
|
|
21
|
-
cwd,
|
|
22
|
-
encoding: "utf8",
|
|
23
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
24
|
-
}).trim();
|
|
22
|
+
function escapeRegExp(input) {
|
|
23
|
+
return input.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
25
24
|
}
|
|
26
|
-
function
|
|
27
|
-
const changelogPath = node_path_1.default.join(cwd, changelogFile);
|
|
28
|
-
if (!node_fs_1.default.existsSync(changelogPath)) {
|
|
29
|
-
return `Automated release for v${version}`;
|
|
30
|
-
}
|
|
31
|
-
const content = node_fs_1.default.readFileSync(changelogPath, "utf8");
|
|
25
|
+
function extractReleaseNotes(content, version, changelogFormat) {
|
|
32
26
|
const lines = content.split("\n");
|
|
33
27
|
const shortVersion = version.replace(/\.\d+$/u, "");
|
|
34
|
-
const start =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
const start = changelogFormat === "r-news"
|
|
29
|
+
? lines.findIndex((line) => {
|
|
30
|
+
const fullMatch = new RegExp(`^#\\s+.+\\s+${escapeRegExp(version)}\\s*$`, "u");
|
|
31
|
+
const shortMatch = new RegExp(`^#\\s+.+\\s+${escapeRegExp(shortVersion)}\\s*$`, "u");
|
|
32
|
+
return fullMatch.test(line) || shortMatch.test(line);
|
|
33
|
+
})
|
|
34
|
+
: lines.findIndex((line) => line.startsWith(`## ${version} -`) ||
|
|
35
|
+
line.startsWith(`## [${version}](`) ||
|
|
36
|
+
line.startsWith(`# ${shortVersion} -`) ||
|
|
37
|
+
line.startsWith(`# [${shortVersion}](`) ||
|
|
38
|
+
new RegExp(`^#\\s+.+\\s+${shortVersion}\\s*$`, "u").test(line));
|
|
39
39
|
if (start < 0) {
|
|
40
|
-
return
|
|
40
|
+
return "";
|
|
41
41
|
}
|
|
42
42
|
let end = lines.length;
|
|
43
43
|
for (let idx = start + 1; idx < lines.length; idx += 1) {
|
|
44
|
-
|
|
44
|
+
const line = lines[idx] ?? "";
|
|
45
|
+
if (changelogFormat === "r-news") {
|
|
46
|
+
if (/^#(?!#)\s+/u.test(line)) {
|
|
47
|
+
end = idx;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (line.startsWith("## ")) {
|
|
45
53
|
end = idx;
|
|
46
54
|
break;
|
|
47
55
|
}
|
|
48
56
|
}
|
|
49
|
-
|
|
57
|
+
return lines
|
|
50
58
|
.slice(start + 1, end)
|
|
51
59
|
.join("\n")
|
|
52
60
|
.trim();
|
|
61
|
+
}
|
|
62
|
+
function getHeadCommitMessage(cwd) {
|
|
63
|
+
return (0, node_child_process_1.execFileSync)("git", ["log", "-1", "--pretty=%B"], {
|
|
64
|
+
cwd,
|
|
65
|
+
encoding: "utf8",
|
|
66
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
67
|
+
}).trim();
|
|
68
|
+
}
|
|
69
|
+
function readReleaseNotes(cwd, version, changelogFile, changelogFormat) {
|
|
70
|
+
const changelogPath = node_path_1.default.join(cwd, changelogFile);
|
|
71
|
+
if (!node_fs_1.default.existsSync(changelogPath)) {
|
|
72
|
+
return `Automated release for v${version}`;
|
|
73
|
+
}
|
|
74
|
+
const content = node_fs_1.default.readFileSync(changelogPath, "utf8");
|
|
75
|
+
const notes = extractReleaseNotes(content, version, changelogFormat);
|
|
53
76
|
return notes.length > 0 ? notes : `Automated release for v${version}`;
|
|
54
77
|
}
|
|
55
78
|
function resolveTargetChangelogFile(config, rootChangelogFile, targetPath) {
|
|
56
79
|
if (targetPath === ".") {
|
|
57
80
|
return rootChangelogFile;
|
|
58
81
|
}
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
82
|
+
const packageConfig = config.packages?.[targetPath];
|
|
83
|
+
const { changelogFile: packageChangelogFile } = (0, plan_js_1.getChangelogDefaults)({
|
|
84
|
+
"release-type": packageConfig?.["release-type"] ?? config["release-type"],
|
|
85
|
+
"changelog-file": packageConfig?.["changelog-file"] ?? config["changelog-file"],
|
|
86
|
+
"changelog-format": packageConfig?.["changelog-format"] ?? config["changelog-format"],
|
|
87
|
+
});
|
|
63
88
|
return node_path_1.default.posix.join(targetPath, packageChangelogFile);
|
|
64
89
|
}
|
|
65
|
-
|
|
66
|
-
const
|
|
90
|
+
function resolveTargetChangelogFormat(config, targetPath) {
|
|
91
|
+
const packageConfig = targetPath === "." ? undefined : config.packages?.[targetPath];
|
|
92
|
+
const { changelogFormat } = (0, plan_js_1.getChangelogDefaults)({
|
|
93
|
+
"release-type": packageConfig?.["release-type"] ?? config["release-type"],
|
|
94
|
+
"changelog-file": packageConfig?.["changelog-file"] ?? config["changelog-file"],
|
|
95
|
+
"changelog-format": packageConfig?.["changelog-format"] ?? config["changelog-format"],
|
|
96
|
+
});
|
|
97
|
+
return changelogFormat;
|
|
98
|
+
}
|
|
99
|
+
async function runRelease(cwd = process.cwd()) {
|
|
100
|
+
const result = await runReleaseDetailed(cwd, { logger: console });
|
|
67
101
|
if (result.action === "release-skipped") {
|
|
68
102
|
return result.reason;
|
|
69
103
|
}
|
|
70
104
|
return result.message;
|
|
71
105
|
}
|
|
72
|
-
async function
|
|
106
|
+
async function runReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
73
107
|
const commitMessage = getHeadCommitMessage(cwd);
|
|
74
108
|
if (!(0, pr_js_1.isReleaseCommitMessage)(commitMessage)) {
|
|
75
109
|
return {
|
|
@@ -107,10 +141,11 @@ async function runSimpleReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
|
107
141
|
const releases = [];
|
|
108
142
|
for (const target of targets) {
|
|
109
143
|
const targetChangelogFile = resolveTargetChangelogFile(loaded.config, changelogFile, target.path);
|
|
144
|
+
const targetChangelogFormat = resolveTargetChangelogFormat(loaded.config, target.path);
|
|
110
145
|
const outcome = await (0, recovery_js_1.executeIdempotentReleaseTarget)(cwd, {
|
|
111
146
|
tag: target.tag,
|
|
112
147
|
version: target.version,
|
|
113
|
-
notes: readReleaseNotes(cwd, target.version, targetChangelogFile),
|
|
148
|
+
notes: readReleaseNotes(cwd, target.version, targetChangelogFile, targetChangelogFormat),
|
|
114
149
|
draft: loaded.config["release-draft"] ?? false,
|
|
115
150
|
}, {
|
|
116
151
|
createReleaseMetadata: (input) => scmClient.createReleaseMetadata(input, {
|
|
@@ -133,3 +168,11 @@ async function runSimpleReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
|
133
168
|
message: `Published releases ${published.join(", ")}`,
|
|
134
169
|
};
|
|
135
170
|
}
|
|
171
|
+
/** @deprecated Use runRelease. */
|
|
172
|
+
async function runSimpleRelease(cwd = process.cwd()) {
|
|
173
|
+
return runRelease(cwd);
|
|
174
|
+
}
|
|
175
|
+
/** @deprecated Use runReleaseDetailed. */
|
|
176
|
+
async function runSimpleReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
177
|
+
return runReleaseDetailed(cwd, options);
|
|
178
|
+
}
|
package/dist/release/semver.js
CHANGED
|
@@ -5,10 +5,21 @@ exports.isValidVersion = isValidVersion;
|
|
|
5
5
|
exports.compareVersions = compareVersions;
|
|
6
6
|
exports.bumpVersion = bumpVersion;
|
|
7
7
|
const SEMVER_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/u;
|
|
8
|
+
const COMPAT_DOTTED_PRERELEASE_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/u;
|
|
9
|
+
function normalizeVersionInput(version) {
|
|
10
|
+
const trimmed = version.trim();
|
|
11
|
+
const compatMatch = trimmed.match(COMPAT_DOTTED_PRERELEASE_PATTERN);
|
|
12
|
+
if (!compatMatch) {
|
|
13
|
+
return trimmed;
|
|
14
|
+
}
|
|
15
|
+
const [, major, minor, patch, prerelease] = compatMatch;
|
|
16
|
+
return `${major}.${minor}.${patch}-${prerelease}`;
|
|
17
|
+
}
|
|
8
18
|
function parseVersion(version) {
|
|
9
|
-
const
|
|
19
|
+
const normalized = normalizeVersionInput(version);
|
|
20
|
+
const match = normalized.match(SEMVER_PATTERN);
|
|
10
21
|
if (!match) {
|
|
11
|
-
throw new Error(`Invalid version in version file: "${version}". Expected SemVer 2.0.0 format.`);
|
|
22
|
+
throw new Error(`Invalid version in version file: "${version}". Expected SemVer 2.0.0 format (or compatibility form X.Y.Z.W).`);
|
|
12
23
|
}
|
|
13
24
|
return {
|
|
14
25
|
major: Number(match[1]),
|
|
@@ -19,7 +30,7 @@ function parseVersion(version) {
|
|
|
19
30
|
};
|
|
20
31
|
}
|
|
21
32
|
function isValidVersion(version) {
|
|
22
|
-
return SEMVER_PATTERN.test(version
|
|
33
|
+
return SEMVER_PATTERN.test(normalizeVersionInput(version));
|
|
23
34
|
}
|
|
24
35
|
function isNumericIdentifier(identifier) {
|
|
25
36
|
return /^(0|[1-9]\d*)$/u.test(identifier);
|