versionary 0.16.0 → 0.17.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.
@@ -8,6 +8,7 @@ exports.loadConfig = loadConfig;
8
8
  const node_fs_1 = __importDefault(require("node:fs"));
9
9
  const node_path_1 = __importDefault(require("node:path"));
10
10
  const jsonc_parser_1 = require("jsonc-parser");
11
+ const resolve_js_1 = require("../strategy/resolve.js");
11
12
  const schema_js_1 = require("./schema.js");
12
13
  const SUPPORTED_FILES = [
13
14
  { file: "versionary.jsonc", format: "jsonc" },
@@ -22,6 +23,34 @@ function parseConfig(raw, format) {
22
23
  function isRecord(value) {
23
24
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
24
25
  }
26
+ function validateReleaseTypes(config) {
27
+ try {
28
+ (0, resolve_js_1.resolveVersionStrategy)(config);
29
+ }
30
+ catch (error) {
31
+ if (error instanceof Error) {
32
+ throw error;
33
+ }
34
+ const known = (0, resolve_js_1.listKnownReleaseTypes)().join(", ");
35
+ throw new Error(`Unsupported release-type. Supported release types: ${known}.`);
36
+ }
37
+ for (const [packagePath, packageConfig] of Object.entries(config.packages ?? {})) {
38
+ const packageReleaseType = packageConfig["release-type"];
39
+ if (!packageReleaseType) {
40
+ continue;
41
+ }
42
+ try {
43
+ (0, resolve_js_1.resolveVersionStrategy)({ ...config, "release-type": packageReleaseType });
44
+ }
45
+ catch (error) {
46
+ if (error instanceof Error) {
47
+ throw new Error(`${error.message} (in packages["${packagePath}"])`);
48
+ }
49
+ const known = (0, resolve_js_1.listKnownReleaseTypes)().join(", ");
50
+ throw new Error(`Unsupported release-type in packages["${packagePath}"]. Supported release types: ${known}.`);
51
+ }
52
+ }
53
+ }
25
54
  function findConfigFile(cwd) {
26
55
  for (const candidate of SUPPORTED_FILES) {
27
56
  const candidatePath = node_path_1.default.join(cwd, candidate.file);
@@ -45,6 +74,7 @@ function loadConfig(cwd = process.cwd()) {
45
74
  throw new Error('The "plugins" config key is no longer supported. Versionary uses built-in integrations only.');
46
75
  }
47
76
  const validated = schema_js_1.configSchema.parse(parsed);
77
+ validateReleaseTypes(validated);
48
78
  return {
49
79
  path: found.path,
50
80
  format: found.format,
@@ -12,8 +12,14 @@ export declare function renderSimpleReleaseNotes(input: {
12
12
  }>;
13
13
  }, options?: {
14
14
  includeFooter?: boolean;
15
+ headerLabel?: string;
16
+ }): string;
17
+ export declare function renderReviewRequestFooter(): string;
18
+ export declare function renderReleasePlanChangelog(plan: ReleasePlan, options?: {
19
+ headerLabel?: string;
20
+ includeFooter?: boolean;
21
+ cwd?: string;
15
22
  }): string;
16
- export declare function renderReleasePlanChangelog(plan: ReleasePlan): string;
17
23
  /** @deprecated Use renderReleasePlanChangelog. */
18
24
  export declare function renderSimpleChangelog(plan: SimplePlan): string;
19
25
  export declare function renderPackageChangelogSection(input: {
@@ -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.renderReviewRequestFooter = renderReviewRequestFooter;
7
8
  exports.renderReleasePlanChangelog = renderReleasePlanChangelog;
8
9
  exports.renderSimpleChangelog = renderSimpleChangelog;
9
10
  exports.renderPackageChangelogSection = renderPackageChangelogSection;
@@ -13,6 +14,7 @@ const node_fs_1 = __importDefault(require("node:fs"));
13
14
  const node_path_1 = __importDefault(require("node:path"));
14
15
  const commits_js_1 = require("../git/commits.js");
15
16
  const repo_url_js_1 = require("../git/repo-url.js");
17
+ const REVIEW_REQUEST_FOOTER = "---\n\nThis PR was generated by [Versionary](https://github.com/jolars/versionary).";
16
18
  function formatDate() {
17
19
  return new Date().toISOString().slice(0, 10);
18
20
  }
@@ -136,9 +138,10 @@ function groupCommitLines(commits, repoUrl) {
136
138
  }
137
139
  function renderSimpleReleaseNotes(input, options = {}) {
138
140
  const repoUrl = (0, repo_url_js_1.resolveRepositoryWebBaseUrl)(input.cwd ?? process.cwd());
141
+ const headerLabel = options.headerLabel ?? input.nextVersion;
139
142
  const header = repoUrl
140
- ? `## [${input.nextVersion}](${repoUrl}/compare/v${input.currentVersion}...v${input.nextVersion}) (${formatDate()})`
141
- : `## ${input.nextVersion} (${formatDate()})`;
143
+ ? `## [${headerLabel}](${repoUrl}/compare/v${input.currentVersion}...v${input.nextVersion}) (${formatDate()})`
144
+ : `## ${headerLabel} (${formatDate()})`;
142
145
  const grouped = groupCommitLines(input.commits, repoUrl);
143
146
  const sections = [];
144
147
  if (grouped.breaking.length > 0) {
@@ -156,13 +159,16 @@ function renderSimpleReleaseNotes(input, options = {}) {
156
159
  if (input.dependencies && input.dependencies.length > 0) {
157
160
  sections.push("### Dependencies", ...input.dependencies.map((dependency) => `- updated ${dependency.name} to v${dependency.version}`), "");
158
161
  }
159
- const lines = [header, "", ...sections];
162
+ const body = [header, "", ...sections].join("\n").trimEnd();
160
163
  if (options.includeFooter) {
161
- lines.push("\n---\n\nThis PR was generated by [Versionary](https://github.com/jolars/versionary).");
164
+ return `${body}\n\n${renderReviewRequestFooter()}`;
162
165
  }
163
- return lines.join("\n");
166
+ return body;
167
+ }
168
+ function renderReviewRequestFooter() {
169
+ return REVIEW_REQUEST_FOOTER;
164
170
  }
165
- function renderReleasePlanChangelog(plan) {
171
+ function renderReleasePlanChangelog(plan, options = {}) {
166
172
  if (!plan.nextVersion) {
167
173
  return "";
168
174
  }
@@ -194,8 +200,11 @@ function renderReleasePlanChangelog(plan) {
194
200
  currentVersion: plan.currentVersion,
195
201
  nextVersion: plan.nextVersion,
196
202
  commits: dedupedCommits,
197
- cwd: process.cwd(),
203
+ cwd: options.cwd ?? process.cwd(),
198
204
  dependencies,
205
+ }, {
206
+ includeFooter: options.includeFooter,
207
+ headerLabel: options.headerLabel,
199
208
  });
200
209
  }
201
210
  /** @deprecated Use renderReleasePlanChangelog. */
@@ -348,25 +348,15 @@ function renderSimpleReviewRequestBody(version, previousVersion, commits, plan =
348
348
  .sort((a, b) => a.name.localeCompare(b.name));
349
349
  return directSources;
350
350
  };
351
- const relabelSectionHeader = (notes, packageLabel, nextVersion) => {
352
- const linkedHeader = notes.match(/^##\s+\[([^\]]+)\]\(([^)]+)\)\s+\(([^)]+)\)/u);
353
- if (linkedHeader) {
354
- const [, , compareUrl, date] = linkedHeader;
355
- return notes.replace(/^##\s+\[[^\]]+\]\([^)]+\)\s+\([^)]+\)/u, `## [${packageLabel}: ${nextVersion}](${compareUrl}) (${date})`);
356
- }
357
- const plainHeader = notes.match(/^##\s+([^\s]+)\s+\(([^)]+)\)/u);
358
- if (plainHeader) {
359
- const [, , date] = plainHeader;
360
- return notes.replace(/^##\s+[^\s]+\s+\([^)]+\)/u, `## ${packageLabel}: ${nextVersion} (${date})`);
361
- }
362
- return notes;
363
- };
364
351
  if (plan?.packages && plan.packages.length > 1) {
365
352
  const sections = [];
366
353
  const rootPackage = plan.packages.find((pkg) => pkg.path === "." && pkg.nextVersion);
367
354
  if (rootPackage?.nextVersion) {
368
- const rootNotes = (0, changelog_js_1.renderReleasePlanChangelog)(plan);
369
- sections.push(relabelSectionHeader(rootNotes, formatPackageLabel("."), rootPackage.nextVersion));
355
+ const rootNotes = (0, changelog_js_1.renderReleasePlanChangelog)(plan, {
356
+ headerLabel: `${formatPackageLabel(".")}: ${rootPackage.nextVersion}`,
357
+ cwd,
358
+ });
359
+ sections.push(rootNotes);
370
360
  }
371
361
  const packageSections = plan.packages
372
362
  .filter((pkg) => pkg.path !== "." && pkg.nextVersion)
@@ -379,15 +369,18 @@ function renderSimpleReviewRequestBody(version, previousVersion, commits, plan =
379
369
  commits: pkg.commits,
380
370
  cwd,
381
371
  dependencies: propagatedDependencies,
382
- }, { includeFooter: false });
383
- return relabelSectionHeader(notes, packageLabel, pkg.nextVersion ?? "");
372
+ }, {
373
+ includeFooter: false,
374
+ headerLabel: `${packageLabel}: ${pkg.nextVersion ?? ""}`,
375
+ });
376
+ return notes;
384
377
  });
385
378
  sections.push(...packageSections);
386
379
  const bodySections = sections.join("\n\n");
387
380
  if (bodySections.length === 0) {
388
- return "This PR was generated by Versionary.";
381
+ return (0, changelog_js_1.renderReviewRequestFooter)();
389
382
  }
390
- return `${bodySections}\n\nThis PR was generated by Versionary.`;
383
+ return `${bodySections}\n\n${(0, changelog_js_1.renderReviewRequestFooter)()}`;
391
384
  }
392
385
  return (0, changelog_js_1.renderSimpleReleaseNotes)({
393
386
  currentVersion: previousVersion,
@@ -5,6 +5,7 @@ export interface ReleaseTargetInput {
5
5
  version: string;
6
6
  notes: string;
7
7
  draft?: boolean;
8
+ makeLatest?: "true" | "false" | "legacy";
8
9
  }
9
10
  export interface ReleaseExecutionContext {
10
11
  createReleaseMetadata: (input: ReleaseTargetInput) => Promise<VersionaryScmReleaseMetadataResult>;
@@ -183,6 +183,7 @@ async function runReleaseDetailed(cwd = process.cwd(), options = {}) {
183
183
  version: target.version,
184
184
  notes: releaseNotes,
185
185
  draft: loaded.config["release-draft"] ?? false,
186
+ makeLatest: target.path === "." ? "true" : "false",
186
187
  }, {
187
188
  createReleaseMetadata: (input) => scmClient.createReleaseMetadata(input, {
188
189
  cwd,
@@ -200,6 +200,7 @@ function createGitHubPlugin() {
200
200
  name: input.tag,
201
201
  body: input.notes,
202
202
  draft: input.draft ?? false,
203
+ make_latest: input.makeLatest,
203
204
  });
204
205
  data = response.data;
205
206
  }
@@ -25,6 +25,7 @@ export interface ScmReleaseMetadataInput {
25
25
  version: string;
26
26
  notes: string;
27
27
  draft?: boolean;
28
+ makeLatest?: "true" | "false" | "legacy";
28
29
  }
29
30
  export interface ScmReleaseMetadataResult {
30
31
  url: string;
@@ -19,5 +19,10 @@ function listKnownReleaseTypes() {
19
19
  }
20
20
  function resolveVersionStrategy(config) {
21
21
  const releaseType = config["release-type"] ?? "simple";
22
- return strategyRegistry[releaseType] ?? simple_js_1.simpleVersionStrategy;
22
+ const strategy = strategyRegistry[releaseType];
23
+ if (!strategy) {
24
+ const known = listKnownReleaseTypes().join(", ");
25
+ throw new Error(`Unsupported release-type "${releaseType}". Supported release types: ${known}.`);
26
+ }
27
+ return strategy;
23
28
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "versionary",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "Automatic release framework based on conventional commits and semantic versioning",
5
5
  "keywords": [
6
6
  "releasing",