versionary 0.11.1 → 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.
Files changed (75) hide show
  1. package/README.md +39 -21
  2. package/dist/cli/index.js +22 -33
  3. package/dist/config/schema.d.ts +9 -0
  4. package/dist/config/schema.js +3 -0
  5. package/dist/{infra/git → git}/commits.d.ts +1 -1
  6. package/dist/index.d.ts +6 -5
  7. package/dist/index.js +10 -10
  8. package/dist/release/artifact-rules.d.ts +3 -0
  9. package/dist/release/changelog.d.ts +32 -0
  10. package/dist/{domain/release → release}/changelog.js +66 -7
  11. package/dist/release/plan.d.ts +37 -0
  12. package/dist/{domain/release → release}/plan.js +54 -19
  13. package/dist/{app/release → release}/pr.d.ts +13 -5
  14. package/dist/{app/release → release}/pr.js +109 -91
  15. package/dist/{app/release → release}/recovery.d.ts +2 -1
  16. package/dist/{app/release → release}/release.d.ts +14 -5
  17. package/dist/{app/release → release}/release.js +80 -40
  18. package/dist/{domain/release → release}/semver.js +14 -3
  19. package/dist/{app/release → release}/state.js +1 -1
  20. package/dist/{verify → release}/verify-project.js +2 -2
  21. package/dist/scm/client.d.ts +2 -0
  22. package/dist/scm/client.js +7 -0
  23. package/dist/scm/github-plugin.d.ts +2 -1
  24. package/dist/scm/github-plugin.js +2 -0
  25. package/dist/scm/types.d.ts +37 -0
  26. package/dist/{domain/strategy → strategy}/node.js +13 -0
  27. package/dist/{domain/strategy → strategy}/package-context.d.ts +1 -1
  28. package/dist/{domain/strategy → strategy}/package-context.js +2 -2
  29. package/dist/{domain/strategy → strategy}/r.js +14 -0
  30. package/dist/{domain/strategy → strategy}/resolve.d.ts +2 -1
  31. package/dist/strategy/resolve.js +21 -0
  32. package/dist/{domain/strategy → strategy}/rust.js +42 -0
  33. package/dist/strategy/types.d.ts +21 -0
  34. package/dist/types/config.d.ts +4 -0
  35. package/dist/types/plugins.d.ts +7 -30
  36. package/package.json +1 -1
  37. package/dist/app/release/artifact-rules.d.ts +0 -3
  38. package/dist/app/release/verify.d.ts +0 -2
  39. package/dist/app/release/verify.js +0 -5
  40. package/dist/domain/release/changelog.d.ts +0 -19
  41. package/dist/domain/release/plan.d.ts +0 -21
  42. package/dist/domain/strategy/resolve.js +0 -19
  43. package/dist/domain/strategy/types.d.ts +0 -7
  44. package/dist/infra/scm/github/plugin.d.ts +0 -1
  45. package/dist/infra/scm/github/plugin.js +0 -5
  46. package/dist/infra/scm/runtime.d.ts +0 -2
  47. package/dist/infra/scm/runtime.js +0 -7
  48. package/dist/infra/scm/types.d.ts +0 -1
  49. package/dist/plugins/runtime.d.ts +0 -1
  50. package/dist/plugins/runtime.js +0 -5
  51. package/dist/strategies/node.d.ts +0 -1
  52. package/dist/strategies/node.js +0 -5
  53. package/dist/strategies/resolve.d.ts +0 -1
  54. package/dist/strategies/resolve.js +0 -5
  55. package/dist/strategies/simple.d.ts +0 -1
  56. package/dist/strategies/simple.js +0 -5
  57. package/dist/strategies/types.d.ts +0 -1
  58. package/dist/strategies/types.js +0 -2
  59. /package/dist/{infra/git → git}/commits.js +0 -0
  60. /package/dist/{infra/git → git}/repo-url.d.ts +0 -0
  61. /package/dist/{infra/git → git}/repo-url.js +0 -0
  62. /package/dist/{app/release → release}/artifact-rules.js +0 -0
  63. /package/dist/{app/release → release}/recovery.js +0 -0
  64. /package/dist/{domain/release → release}/semver.d.ts +0 -0
  65. /package/dist/{app/release → release}/state.d.ts +0 -0
  66. /package/dist/{verify → release}/verify-project.d.ts +0 -0
  67. /package/dist/{plugins → scm}/capabilities.d.ts +0 -0
  68. /package/dist/{plugins → scm}/capabilities.js +0 -0
  69. /package/dist/{domain/strategy → scm}/types.js +0 -0
  70. /package/dist/{domain/strategy → strategy}/node.d.ts +0 -0
  71. /package/dist/{domain/strategy → strategy}/r.d.ts +0 -0
  72. /package/dist/{domain/strategy → strategy}/rust.d.ts +0 -0
  73. /package/dist/{domain/strategy → strategy}/simple.d.ts +0 -0
  74. /package/dist/{domain/strategy → strategy}/simple.js +0 -0
  75. /package/dist/{infra/scm → strategy}/types.js +0 -0
package/README.md CHANGED
@@ -52,7 +52,7 @@ Current implementation focuses on:
52
52
  - strategy-based version updates (`simple`, `node`, `rust`, `r`)
53
53
  - release planning and changelog generation
54
54
  - review-mode vs direct-mode release flow
55
- - built-in GitHub SCM plugin capabilities
55
+ - a static internal SCM client (`github` provider today)
56
56
 
57
57
  Planned/harder areas include deeper monorepo ergonomics, broader SCM coverage,
58
58
  and stronger failure recovery around release steps.
@@ -61,8 +61,8 @@ and stronger failure recovery around release steps.
61
61
 
62
62
  Versionary is set up so new language strategies can be added internally without
63
63
  changing release orchestration. A new strategy should implement the
64
- `VersionStrategy` contract in `src/domain/strategy/types.ts` and be wired in
65
- `src/domain/strategy/resolve.ts`.
64
+ `VersionStrategy` contract in `src/strategy/types.ts` and be wired in
65
+ `src/strategy/resolve.ts`.
66
66
 
67
67
  Checklist for new strategies (for example `python`):
68
68
 
@@ -71,8 +71,13 @@ Checklist for new strategies (for example `python`):
71
71
  - implement `readVersion(cwd, config)` with explicit malformed-file errors
72
72
  - implement `writeVersion(cwd, config, version)` returning deterministic updated
73
73
  file paths
74
- - add release-name extraction support if package tags should derive from
75
- language metadata (similar to Node/Rust/R)
74
+ - optionally implement `readPackageName(cwd, config)` so monorepo release tags
75
+ can derive from language metadata (similar to Node/Rust/R)
76
+ - optionally implement `propagateDependentPatchImpacts(cwd, packages)` if
77
+ dependency updates in this ecosystem should trigger dependent package patch
78
+ bumps
79
+ - optionally implement `finalizeVersionWrites(cwd, writes)` for ecosystem
80
+ post-processing after all target version files are written
76
81
  - add focused strategy tests for ecosystem-specific behavior and edge cases
77
82
  - add/extend strategy contract tests in `tests/strategy-contract.test.ts`
78
83
  - update schema/docs for new `release-type` behavior and defaults
@@ -81,8 +86,10 @@ Current ecosystem policy defaults:
81
86
 
82
87
  - changelog source for publish:
83
88
  - root target uses root `changelog-file`
84
- - package target uses `packages.<path>.changelog-file` when configured, else
85
- root `changelog-file`
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>`
86
93
  - lockfiles:
87
94
  - Node strategy updates root `package-lock.json`/`npm-shrinkwrap.json` when
88
95
  present
@@ -91,16 +98,19 @@ Current ecosystem policy defaults:
91
98
  - Rust supports `version.workspace = true` via `[workspace.package].version`
92
99
  - other strategies should document equivalent inheritance behavior explicitly
93
100
 
94
- ## Architecture layout (current migration)
101
+ ## Architecture layout (canonical)
95
102
 
96
- The repository is moving to explicit layered modules:
103
+ Current runtime code uses a flat `src/` layout with clear module boundaries:
97
104
 
98
- - `src/app/`: command-level application services and orchestration boundaries
99
- - `src/domain/`: release and strategy domain logic/contracts
100
- - `src/infra/`: platform integrations (SCM, git/runtime adapters)
101
-
102
- Legacy `src/simple/` has been removed. Remaining compatibility paths are
103
- `src/strategies` and `src/scm` while migration is finalized.
105
+ - `src/cli/`: command router (`run`, `verify`, `plan`, `changelog`, `pr`, `release`)
106
+ - `src/release/`: release orchestration (plan/changelog/PR/release/state/recovery)
107
+ - `src/strategy/`: strategy contracts, resolver, and built-in implementations
108
+ (`simple`, `node`, `rust`, `r`)
109
+ - `src/scm/`: SCM client contracts and provider implementation(s)
110
+ - `src/config/`: config loading and schema validation
111
+ - `src/git/`: git commit/range and repository URL helpers
112
+ - `src/verify/`: repository/config verification
113
+ - `src/types/`: shared config/plugin-facing types
104
114
 
105
115
  Configuration is loaded from `versionary.jsonc` by default (or
106
116
  `versionary.json`).
@@ -132,6 +142,8 @@ For a quick trial, use:
132
142
  auto-transition to `1.0.0` on a breaking release
133
143
  - review mode (`review-mode`): `pr` (PR/MR style) or `direct` (no review
134
144
  request)
145
+ - `release-draft` (default `false`) publishes GitHub releases as drafts when
146
+ enabled
135
147
  - optional monorepo planning with `monorepo-mode` and `packages`:
136
148
  - `independent` computes package bumps per path
137
149
  - `fixed` computes one shared bump across configured package paths
@@ -229,8 +241,8 @@ Commands:
229
241
  - `pnpm pr`
230
242
  - `pnpm release`
231
243
 
232
- `pnpm pr` prepares release commit + branch and opens/updates the review request
233
- via SCM plugin capability. `pnpm run` is the recommended CI entrypoint and
244
+ `pnpm pr` prepares release commit + branch and opens/updates a review request
245
+ through the SCM client. `pnpm run` is the recommended CI entrypoint and
234
246
  auto-dispatches between PR/update and release publish.
235
247
 
236
248
  For first-run bootstrapping, set `bootstrap-sha` (similar to release-please).
@@ -251,15 +263,21 @@ Versionary fails fast when recovery is unsafe (for example, local and remote
251
263
  tags with the same name point to different SHAs). In these cases, the error
252
264
  message includes remediation guidance so CI logs are actionable.
253
265
 
254
- ## Built-in plugins
266
+ ## SCM API model
267
+
268
+ Versionary currently uses a static internal SCM client model:
255
269
 
256
- Versionary ships with built-in SCM plugin support:
270
+ - `src/scm/types.ts` defines the `ScmClient` contract
271
+ - `src/scm/client.ts` returns the active provider client
272
+ - current provider is `github` via `src/scm/github-plugin.ts`
257
273
 
258
- - `github` (default): review request + release metadata
274
+ There is no runtime discovery/loading of external SCM providers in the release
275
+ flow. Adding another provider is an internal extension: implement `ScmClient`
276
+ and wire provider selection in `src/scm/client.ts`.
259
277
 
260
278
  ### GitHub integration: env, permissions, and flow
261
279
 
262
- Required environment for the built-in GitHub plugin:
280
+ Required environment for the GitHub SCM provider:
263
281
 
264
282
  - `GITHUB_REPOSITORY` (format: `owner/repo`)
265
283
  - one token env var: `VERSIONARY_PR_TOKEN` or `GH_TOKEN` or `GITHUB_TOKEN`
package/dist/cli/index.js CHANGED
@@ -1,19 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
3
  Object.defineProperty(exports, "__esModule", { value: true });
7
4
  const node_child_process_1 = require("node:child_process");
8
- const node_fs_1 = __importDefault(require("node:fs"));
9
- const node_path_1 = __importDefault(require("node:path"));
10
- const pr_js_1 = require("../app/release/pr.js");
11
- const release_js_1 = require("../app/release/release.js");
12
- const verify_js_1 = require("../app/release/verify.js");
13
- const changelog_js_1 = require("../domain/release/changelog.js");
14
- const plan_js_1 = require("../domain/release/plan.js");
5
+ const changelog_js_1 = require("../release/changelog.js");
6
+ const plan_js_1 = require("../release/plan.js");
7
+ const pr_js_1 = require("../release/pr.js");
8
+ const release_js_1 = require("../release/release.js");
9
+ const verify_project_js_1 = require("../release/verify-project.js");
15
10
  function printVerifyResult() {
16
- const result = (0, verify_js_1.verifyProject)();
11
+ const result = (0, verify_project_js_1.verifyProject)();
17
12
  const categories = [
18
13
  { key: "config", title: "Config" },
19
14
  { key: "paths", title: "Paths" },
@@ -57,7 +52,7 @@ async function main() {
57
52
  }).trim();
58
53
  if ((0, pr_js_1.isReleaseCommitMessage)(commitMessage)) {
59
54
  if (flags["dry-run"] && !flags.json) {
60
- const release = await (0, release_js_1.runSimpleReleaseDetailed)(process.cwd(), {
55
+ const release = await (0, release_js_1.runReleaseDetailed)(process.cwd(), {
61
56
  logger,
62
57
  "dry-run": true,
63
58
  });
@@ -67,7 +62,7 @@ async function main() {
67
62
  }
68
63
  }
69
64
  if (flags.json) {
70
- const release = await (0, release_js_1.runSimpleReleaseDetailed)(process.cwd(), {
65
+ const release = await (0, release_js_1.runReleaseDetailed)(process.cwd(), {
71
66
  logger,
72
67
  "dry-run": flags["dry-run"],
73
68
  });
@@ -98,11 +93,11 @@ async function main() {
98
93
  });
99
94
  return 0;
100
95
  }
101
- const message = await (0, release_js_1.runSimpleRelease)(process.cwd());
96
+ const message = await (0, release_js_1.runRelease)(process.cwd());
102
97
  console.log(message);
103
98
  return 0;
104
99
  }
105
- const plan = (0, plan_js_1.createSimplePlan)();
100
+ const plan = (0, plan_js_1.createReleasePlan)();
106
101
  if (!plan.nextVersion) {
107
102
  const message = "No releasable commits found. Nothing to do.";
108
103
  if (flags.json) {
@@ -145,9 +140,9 @@ async function main() {
145
140
  console.log(dryRunMessage);
146
141
  return 0;
147
142
  }
148
- const pr = (0, pr_js_1.prepareSimpleReleasePr)(process.cwd(), { logger });
143
+ const pr = (0, pr_js_1.prepareReleasePr)(process.cwd(), { logger });
149
144
  (0, pr_js_1.pushReleaseBranch)(process.cwd(), pr.branch);
150
- const reviewResult = await (0, pr_js_1.openOrUpdateSimpleReviewRequest)(process.cwd(), pr.branch, pr.title, pr.version, pr.previousVersion, pr.commits, pr.plan, { logger });
145
+ const reviewResult = await (0, pr_js_1.openOrUpdateReviewRequest)(process.cwd(), pr.branch, pr.title, pr.version, pr.previousVersion, pr.commits, pr.plan, { logger });
151
146
  const message = `Prepared release PR branch ${pr.branch}`;
152
147
  if (flags.json) {
153
148
  emitJson({
@@ -170,35 +165,29 @@ async function main() {
170
165
  return printVerifyResult();
171
166
  }
172
167
  if (command === "plan") {
173
- const plan = (0, plan_js_1.createSimplePlan)();
168
+ const plan = (0, plan_js_1.createReleasePlan)();
174
169
  console.log(JSON.stringify(plan, null, 2));
175
170
  return 0;
176
171
  }
177
172
  if (command === "changelog") {
178
173
  const write = args.includes("--write");
179
- const plan = (0, plan_js_1.createSimplePlan)();
174
+ const plan = (0, plan_js_1.createReleasePlan)();
180
175
  if (!plan.nextVersion) {
181
176
  console.log("No releasable commits found.");
182
177
  return 0;
183
178
  }
184
- const section = (0, changelog_js_1.renderSimpleChangelog)(plan);
179
+ const section = (0, changelog_js_1.renderReleasePlanChangelog)(plan);
185
180
  if (!write) {
186
181
  console.log(section);
187
182
  return 0;
188
183
  }
189
- const changelogPath = node_path_1.default.join(process.cwd(), plan.changelogFile);
190
- const existing = node_fs_1.default.existsSync(changelogPath)
191
- ? node_fs_1.default.readFileSync(changelogPath, "utf8")
192
- : "";
193
- const heading = "# Changelog\n\n";
194
- const body = existing.replace(/^# Changelog\s*/u, "");
195
- node_fs_1.default.writeFileSync(changelogPath, `${`${heading}${section}\n${body}`.trimEnd()}\n`, "utf8");
184
+ (0, changelog_js_1.prependChangelog)(process.cwd(), plan.changelogFile, section, plan.changelogFormat);
196
185
  console.log(`Updated ${plan.changelogFile}`);
197
186
  return 0;
198
187
  }
199
188
  if (command === "pr") {
200
189
  if (flags["dry-run"]) {
201
- const plan = (0, plan_js_1.createSimplePlan)();
190
+ const plan = (0, plan_js_1.createReleasePlan)();
202
191
  if (!plan.nextVersion) {
203
192
  console.log("No releasable commits found. Nothing to do.");
204
193
  return 0;
@@ -206,9 +195,9 @@ async function main() {
206
195
  console.log(`Dry run: would prepare release PR branch ${plan.releaseBranchPrefix} for ${plan.nextVersion}`);
207
196
  return 0;
208
197
  }
209
- const pr = (0, pr_js_1.prepareSimpleReleasePr)(process.cwd(), { logger: console });
198
+ const pr = (0, pr_js_1.prepareReleasePr)(process.cwd(), { logger: console });
210
199
  (0, pr_js_1.pushReleaseBranch)(process.cwd(), pr.branch);
211
- const reviewResult = await (0, pr_js_1.openOrUpdateSimpleReviewRequest)(process.cwd(), pr.branch, pr.title, pr.version, pr.previousVersion, pr.commits, pr.plan);
200
+ const reviewResult = await (0, pr_js_1.openOrUpdateReviewRequest)(process.cwd(), pr.branch, pr.title, pr.version, pr.previousVersion, pr.commits, pr.plan);
212
201
  console.log(`Prepared release PR branch ${pr.branch}`);
213
202
  console.log(`Title: ${pr.title}`);
214
203
  console.log(reviewResult);
@@ -216,7 +205,7 @@ async function main() {
216
205
  }
217
206
  if (command === "release") {
218
207
  if (flags["dry-run"]) {
219
- const result = await (0, release_js_1.runSimpleReleaseDetailed)(process.cwd(), {
208
+ const result = await (0, release_js_1.runReleaseDetailed)(process.cwd(), {
220
209
  logger,
221
210
  "dry-run": true,
222
211
  });
@@ -231,7 +220,7 @@ async function main() {
231
220
  }
232
221
  return 0;
233
222
  }
234
- const message = await (0, release_js_1.runSimpleRelease)(process.cwd());
223
+ const message = await (0, release_js_1.runRelease)(process.cwd());
235
224
  console.log(message);
236
225
  return 0;
237
226
  }
@@ -239,7 +228,7 @@ async function main() {
239
228
  console.log("Commands:");
240
229
  console.log(" run [--json] [--dry-run] Auto-dispatch release PR/update or release publish by context");
241
230
  console.log(" verify Validate config and basic repository shape");
242
- console.log(" plan Print release plan (simple mode)");
231
+ console.log(" plan Print release plan");
243
232
  console.log(" changelog [--write] Print or write changelog section");
244
233
  console.log(" pr [--dry-run] Prepare release PR commit and branch");
245
234
  console.log(" release [--dry-run] Publish release metadata for release commit context");
@@ -9,6 +9,11 @@ export declare const configSchema: z.ZodObject<{
9
9
  }>>;
10
10
  "version-file": z.ZodOptional<z.ZodString>;
11
11
  "changelog-file": z.ZodOptional<z.ZodString>;
12
+ "changelog-format": z.ZodOptional<z.ZodEnum<{
13
+ "markdown-changelog": "markdown-changelog";
14
+ "r-news": "r-news";
15
+ }>>;
16
+ "release-draft": z.ZodOptional<z.ZodBoolean>;
12
17
  "release-branch": z.ZodOptional<z.ZodString>;
13
18
  "baseline-file": z.ZodOptional<z.ZodString>;
14
19
  "bootstrap-sha": z.ZodOptional<z.ZodString>;
@@ -24,6 +29,10 @@ export declare const configSchema: z.ZodObject<{
24
29
  "release-type": z.ZodOptional<z.ZodString>;
25
30
  "package-name": z.ZodOptional<z.ZodString>;
26
31
  "changelog-file": z.ZodOptional<z.ZodString>;
32
+ "changelog-format": z.ZodOptional<z.ZodEnum<{
33
+ "markdown-changelog": "markdown-changelog";
34
+ "r-news": "r-news";
35
+ }>>;
27
36
  "exclude-paths": z.ZodOptional<z.ZodArray<z.ZodString>>;
28
37
  "extra-files": z.ZodOptional<z.ZodArray<z.ZodObject<{
29
38
  type: z.ZodEnum<{
@@ -54,6 +54,7 @@ const packageSchema = zod_1.z
54
54
  "release-type": zod_1.z.string().optional(),
55
55
  "package-name": zod_1.z.string().optional(),
56
56
  "changelog-file": zod_1.z.string().optional(),
57
+ "changelog-format": zod_1.z.enum(["markdown-changelog", "r-news"]).optional(),
57
58
  "exclude-paths": zod_1.z.array(zod_1.z.string()).optional(),
58
59
  "extra-files": zod_1.z.array(artifactRuleSchema).optional(),
59
60
  })
@@ -65,6 +66,8 @@ exports.configSchema = zod_1.z
65
66
  "review-mode": zod_1.z.enum(["direct", "pr", "review"]).optional(),
66
67
  "version-file": zod_1.z.string().optional(),
67
68
  "changelog-file": zod_1.z.string().optional(),
69
+ "changelog-format": zod_1.z.enum(["markdown-changelog", "r-news"]).optional(),
70
+ "release-draft": zod_1.z.boolean().optional(),
68
71
  "release-branch": zod_1.z.string().optional(),
69
72
  "baseline-file": zod_1.z.string().optional(),
70
73
  "bootstrap-sha": zod_1.z.string().optional(),
@@ -1,4 +1,4 @@
1
- import type { ReleaseType } from "../../domain/release/semver.js";
1
+ import type { ReleaseType } from "../release/semver.js";
2
2
  export interface CommitInfo {
3
3
  hash: string;
4
4
  subject: string;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  export { loadConfig } from "./config/load-config.js";
2
- export { resolveVersionStrategy } from "./domain/strategy/resolve.js";
3
- export { createGitHubPlugin } from "./infra/scm/github/plugin.js";
4
- export { findPluginsByCapability, pluginHasCapability, } from "./plugins/capabilities.js";
5
- export { loadRuntimePlugins } from "./plugins/runtime.js";
2
+ export { verifyProject } from "./release/verify-project.js";
3
+ export { findPluginsByCapability, pluginHasCapability, } from "./scm/capabilities.js";
4
+ export { getScmClient } from "./scm/client.js";
5
+ export { createGitHubPlugin } from "./scm/github-plugin.js";
6
+ export type { ScmClient, ScmClientContext, ScmProvider, ScmReleaseMetadataInput, ScmReleaseMetadataResult, ScmReviewRequestInput, ScmReviewRequestResult, } from "./scm/types.js";
7
+ export { resolveVersionStrategy } from "./strategy/resolve.js";
6
8
  export type { VersionaryArtifactRule, VersionaryConfig, VersionaryPackage, } from "./types/config.js";
7
9
  export type { VersionaryPluginCapability, VersionaryPluginContext, VersionaryPluginRuntime, VersionaryScmReleaseMetadataInput, VersionaryScmReleaseMetadataResult, VersionaryScmReviewRequestInput, VersionaryScmReviewRequestResult, } from "./types/plugins.js";
8
- export { verifyProject } from "./verify/verify-project.js";
package/dist/index.js CHANGED
@@ -1,16 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.verifyProject = exports.loadRuntimePlugins = exports.pluginHasCapability = exports.findPluginsByCapability = exports.createGitHubPlugin = exports.resolveVersionStrategy = exports.loadConfig = void 0;
3
+ exports.resolveVersionStrategy = exports.createGitHubPlugin = exports.getScmClient = exports.pluginHasCapability = exports.findPluginsByCapability = exports.verifyProject = exports.loadConfig = void 0;
4
4
  var load_config_js_1 = require("./config/load-config.js");
5
5
  Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return load_config_js_1.loadConfig; } });
6
- var resolve_js_1 = require("./domain/strategy/resolve.js");
7
- Object.defineProperty(exports, "resolveVersionStrategy", { enumerable: true, get: function () { return resolve_js_1.resolveVersionStrategy; } });
8
- var plugin_js_1 = require("./infra/scm/github/plugin.js");
9
- Object.defineProperty(exports, "createGitHubPlugin", { enumerable: true, get: function () { return plugin_js_1.createGitHubPlugin; } });
10
- var capabilities_js_1 = require("./plugins/capabilities.js");
6
+ var verify_project_js_1 = require("./release/verify-project.js");
7
+ Object.defineProperty(exports, "verifyProject", { enumerable: true, get: function () { return verify_project_js_1.verifyProject; } });
8
+ var capabilities_js_1 = require("./scm/capabilities.js");
11
9
  Object.defineProperty(exports, "findPluginsByCapability", { enumerable: true, get: function () { return capabilities_js_1.findPluginsByCapability; } });
12
10
  Object.defineProperty(exports, "pluginHasCapability", { enumerable: true, get: function () { return capabilities_js_1.pluginHasCapability; } });
13
- var runtime_js_1 = require("./plugins/runtime.js");
14
- Object.defineProperty(exports, "loadRuntimePlugins", { enumerable: true, get: function () { return runtime_js_1.loadRuntimePlugins; } });
15
- var verify_project_js_1 = require("./verify/verify-project.js");
16
- Object.defineProperty(exports, "verifyProject", { enumerable: true, get: function () { return verify_project_js_1.verifyProject; } });
11
+ var client_js_1 = require("./scm/client.js");
12
+ Object.defineProperty(exports, "getScmClient", { enumerable: true, get: function () { return client_js_1.getScmClient; } });
13
+ var github_plugin_js_1 = require("./scm/github-plugin.js");
14
+ Object.defineProperty(exports, "createGitHubPlugin", { enumerable: true, get: function () { return github_plugin_js_1.createGitHubPlugin; } });
15
+ var resolve_js_1 = require("./strategy/resolve.js");
16
+ Object.defineProperty(exports, "resolveVersionStrategy", { enumerable: true, get: function () { return resolve_js_1.resolveVersionStrategy; } });
@@ -0,0 +1,3 @@
1
+ import type { VersionaryConfig } from "../types/config.js";
2
+ import type { SimplePlan } from "./plan.js";
3
+ export declare function applyConfiguredArtifactRules(cwd: string, config: VersionaryConfig, plan: SimplePlan): string[];
@@ -0,0 +1,32 @@
1
+ import { type ParsedCommit } from "../git/commits.js";
2
+ import type { VersionaryChangelogFormat } from "../types/config.js";
3
+ import type { ReleasePlan, SimplePlan } from "./plan.js";
4
+ export declare function renderSimpleReleaseNotes(input: {
5
+ currentVersion: string;
6
+ nextVersion: string;
7
+ commits: ParsedCommit[];
8
+ cwd?: string;
9
+ dependencies?: Array<{
10
+ name: string;
11
+ version: string;
12
+ }>;
13
+ }, options?: {
14
+ includeFooter?: boolean;
15
+ }): string;
16
+ export declare function renderReleasePlanChangelog(plan: ReleasePlan): string;
17
+ /** @deprecated Use renderReleasePlanChangelog. */
18
+ export declare function renderSimpleChangelog(plan: SimplePlan): string;
19
+ export declare function renderPackageChangelogSection(input: {
20
+ currentVersion: string;
21
+ nextVersion: string;
22
+ commits: ParsedCommit[];
23
+ tagPrefix: string;
24
+ cwd?: string;
25
+ }): string;
26
+ export declare function prependChangelog(cwd: string, changelogFile: string, section: string, format?: VersionaryChangelogFormat): void;
27
+ export declare function renderRNewsReleaseNotes(input: {
28
+ packageName: string;
29
+ nextVersion: string;
30
+ commits: ParsedCommit[];
31
+ cwd?: string;
32
+ }): string;
@@ -4,13 +4,15 @@ 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;
11
+ exports.renderRNewsReleaseNotes = renderRNewsReleaseNotes;
10
12
  const node_fs_1 = __importDefault(require("node:fs"));
11
13
  const node_path_1 = __importDefault(require("node:path"));
12
- const commits_js_1 = require("../../infra/git/commits.js");
13
- const repo_url_js_1 = require("../../infra/git/repo-url.js");
14
+ const commits_js_1 = require("../git/commits.js");
15
+ const repo_url_js_1 = require("../git/repo-url.js");
14
16
  function formatDate() {
15
17
  return new Date().toISOString().slice(0, 10);
16
18
  }
@@ -102,23 +104,52 @@ function renderSimpleReleaseNotes(input, options = {}) {
102
104
  if (grouped.reverts.length > 0) {
103
105
  sections.push("### Reverts", ...grouped.reverts, "");
104
106
  }
107
+ if (input.dependencies && input.dependencies.length > 0) {
108
+ sections.push("### Dependencies", ...input.dependencies.map((dependency) => `- updated ${dependency.name} to v${dependency.version}`), "");
109
+ }
105
110
  const lines = [header, "", ...sections];
106
111
  if (options.includeFooter) {
107
112
  lines.push("\n---\n\nThis PR was generated by [Versionary](https://github.com/jolars/versionary).");
108
113
  }
109
114
  return lines.join("\n");
110
115
  }
111
- function renderSimpleChangelog(plan) {
116
+ function renderReleasePlanChangelog(plan) {
112
117
  if (!plan.nextVersion) {
113
118
  return "";
114
119
  }
120
+ const propagatedRootPackage = plan.packages?.find((pkg) => pkg.path === "." && pkg.bumpReason === "dependency-propagation");
121
+ const isDirectBump = (pkg) => pkg.bumpReason === "direct" ||
122
+ (pkg.bumpReason === undefined &&
123
+ Boolean(pkg.nextVersion) &&
124
+ pkg.commits.length > 0);
125
+ const dependencies = propagatedRootPackage && plan.packages
126
+ ? plan.packages
127
+ .filter((pkg) => pkg.path !== "." && isDirectBump(pkg) && pkg.nextVersion)
128
+ .map((pkg) => ({
129
+ name: pkg.path,
130
+ version: pkg.nextVersion,
131
+ }))
132
+ : [];
133
+ if (plan.changelogFormat === "r-news") {
134
+ return renderRNewsReleaseNotes({
135
+ packageName: plan.packageName,
136
+ nextVersion: plan.nextVersion,
137
+ commits: plan.commits,
138
+ cwd: process.cwd(),
139
+ });
140
+ }
115
141
  return renderSimpleReleaseNotes({
116
142
  currentVersion: plan.currentVersion,
117
143
  nextVersion: plan.nextVersion,
118
144
  commits: plan.commits,
119
145
  cwd: process.cwd(),
146
+ dependencies,
120
147
  });
121
148
  }
149
+ /** @deprecated Use renderReleasePlanChangelog. */
150
+ function renderSimpleChangelog(plan) {
151
+ return renderReleasePlanChangelog(plan);
152
+ }
122
153
  function renderPackageChangelogSection(input) {
123
154
  const repoUrl = (0, repo_url_js_1.resolveRepositoryWebBaseUrl)(input.cwd ?? process.cwd());
124
155
  const header = repoUrl
@@ -140,14 +171,42 @@ function renderPackageChangelogSection(input) {
140
171
  }
141
172
  return [header, "", ...sections].join("\n");
142
173
  }
143
- function prependChangelog(cwd, changelogFile, section) {
174
+ function prependChangelog(cwd, changelogFile, section, format = "markdown-changelog") {
144
175
  const changelogPath = node_path_1.default.join(cwd, changelogFile);
145
176
  const existing = node_fs_1.default.existsSync(changelogPath)
146
177
  ? node_fs_1.default.readFileSync(changelogPath, "utf8")
147
178
  : "";
148
- const heading = existing.startsWith("# Changelog") ? "" : "# Changelog\n\n";
179
+ if (format === "r-news") {
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`;
183
+ node_fs_1.default.writeFileSync(changelogPath, next, "utf8");
184
+ return;
185
+ }
186
+ const heading = "# Changelog\n\n";
187
+ const bodyWithoutHeading = existing.replace(/^# Changelog\s*/u, "");
149
188
  const separator = existing.length > 0 ? "\n" : "";
150
- const next = `${heading}${section}${separator}${existing.replace(/^# Changelog\s*/u, "")}`.trimEnd() +
151
- "\n";
189
+ const next = `${`${heading}${section}${separator}${bodyWithoutHeading}`.trimEnd()}\n`;
152
190
  node_fs_1.default.writeFileSync(changelogPath, next, "utf8");
153
191
  }
192
+ function renderRNewsReleaseNotes(input) {
193
+ const repoUrl = (0, repo_url_js_1.resolveRepositoryWebBaseUrl)(input.cwd ?? process.cwd());
194
+ const grouped = groupCommitLines(input.commits, repoUrl);
195
+ const normalizedVersion = input.nextVersion.replace(/\.\d+$/u, "");
196
+ const sections = [];
197
+ if (grouped.breaking.length > 0) {
198
+ sections.push("## Breaking changes", "", ...grouped.breaking, "");
199
+ }
200
+ if (grouped.features.length > 0) {
201
+ sections.push("## Features", "", ...grouped.features, "");
202
+ }
203
+ if (grouped.fixes.length > 0) {
204
+ sections.push("## Bug fixes", "", ...grouped.fixes, "");
205
+ }
206
+ if (grouped.reverts.length > 0) {
207
+ sections.push("## Reverts", "", ...grouped.reverts, "");
208
+ }
209
+ return [`# ${input.packageName} ${normalizedVersion}`, "", ...sections]
210
+ .join("\n")
211
+ .trimEnd();
212
+ }
@@ -0,0 +1,37 @@
1
+ import { type ParsedCommit } from "../git/commits.js";
2
+ import type { VersionaryChangelogFormat, VersionaryConfig } from "../types/config.js";
3
+ import { type ReleaseType } from "./semver.js";
4
+ export interface ReleasePlan {
5
+ mode: "simple";
6
+ releaseType: ReleaseType;
7
+ currentVersion: string;
8
+ nextVersion: string | null;
9
+ packageName: string;
10
+ versionFile: string;
11
+ changelogFile: string;
12
+ changelogFormat: VersionaryChangelogFormat;
13
+ releaseBranchPrefix: string;
14
+ baselineSha: string | null;
15
+ commits: ParsedCommit[];
16
+ packages?: Array<{
17
+ path: string;
18
+ releaseType: ReleaseType;
19
+ currentVersion: string;
20
+ nextVersion: string | null;
21
+ bumpReason?: "direct" | "dependency-propagation";
22
+ commits: ParsedCommit[];
23
+ }>;
24
+ }
25
+ /** @deprecated Use ReleasePlan. */
26
+ export type SimplePlan = ReleasePlan;
27
+ export declare function getChangelogDefaults(config: {
28
+ "release-type"?: VersionaryConfig["release-type"];
29
+ "changelog-file"?: VersionaryConfig["changelog-file"];
30
+ "changelog-format"?: VersionaryConfig["changelog-format"];
31
+ }): {
32
+ changelogFile: string;
33
+ changelogFormat: VersionaryChangelogFormat;
34
+ };
35
+ export declare function createReleasePlan(cwd?: string): ReleasePlan;
36
+ /** @deprecated Use createReleasePlan. */
37
+ export declare function createSimplePlan(cwd?: string): ReleasePlan;