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.
- package/README.md +39 -21
- package/dist/cli/index.js +22 -33
- package/dist/config/schema.d.ts +9 -0
- package/dist/config/schema.js +3 -0
- package/dist/{infra/git → git}/commits.d.ts +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.js +10 -10
- package/dist/release/artifact-rules.d.ts +3 -0
- package/dist/release/changelog.d.ts +32 -0
- package/dist/{domain/release → release}/changelog.js +66 -7
- package/dist/release/plan.d.ts +37 -0
- package/dist/{domain/release → release}/plan.js +54 -19
- package/dist/{app/release → release}/pr.d.ts +13 -5
- package/dist/{app/release → release}/pr.js +109 -91
- package/dist/{app/release → release}/recovery.d.ts +2 -1
- package/dist/{app/release → release}/release.d.ts +14 -5
- package/dist/{app/release → release}/release.js +80 -40
- package/dist/{domain/release → release}/semver.js +14 -3
- package/dist/{app/release → release}/state.js +1 -1
- package/dist/{verify → release}/verify-project.js +2 -2
- package/dist/scm/client.d.ts +2 -0
- package/dist/scm/client.js +7 -0
- package/dist/scm/github-plugin.d.ts +2 -1
- package/dist/scm/github-plugin.js +2 -0
- package/dist/scm/types.d.ts +37 -0
- package/dist/{domain/strategy → strategy}/node.js +13 -0
- package/dist/{domain/strategy → strategy}/package-context.d.ts +1 -1
- package/dist/{domain/strategy → strategy}/package-context.js +2 -2
- package/dist/{domain/strategy → strategy}/r.js +14 -0
- package/dist/{domain/strategy → strategy}/resolve.d.ts +2 -1
- package/dist/strategy/resolve.js +21 -0
- package/dist/{domain/strategy → strategy}/rust.js +42 -0
- package/dist/strategy/types.d.ts +21 -0
- package/dist/types/config.d.ts +4 -0
- package/dist/types/plugins.d.ts +7 -30
- package/package.json +1 -1
- package/dist/app/release/artifact-rules.d.ts +0 -3
- package/dist/app/release/verify.d.ts +0 -2
- package/dist/app/release/verify.js +0 -5
- package/dist/domain/release/changelog.d.ts +0 -19
- package/dist/domain/release/plan.d.ts +0 -21
- package/dist/domain/strategy/resolve.js +0 -19
- package/dist/domain/strategy/types.d.ts +0 -7
- package/dist/infra/scm/github/plugin.d.ts +0 -1
- package/dist/infra/scm/github/plugin.js +0 -5
- package/dist/infra/scm/runtime.d.ts +0 -2
- package/dist/infra/scm/runtime.js +0 -7
- package/dist/infra/scm/types.d.ts +0 -1
- package/dist/plugins/runtime.d.ts +0 -1
- package/dist/plugins/runtime.js +0 -5
- package/dist/strategies/node.d.ts +0 -1
- package/dist/strategies/node.js +0 -5
- package/dist/strategies/resolve.d.ts +0 -1
- package/dist/strategies/resolve.js +0 -5
- package/dist/strategies/simple.d.ts +0 -1
- package/dist/strategies/simple.js +0 -5
- package/dist/strategies/types.d.ts +0 -1
- package/dist/strategies/types.js +0 -2
- /package/dist/{infra/git → git}/commits.js +0 -0
- /package/dist/{infra/git → git}/repo-url.d.ts +0 -0
- /package/dist/{infra/git → git}/repo-url.js +0 -0
- /package/dist/{app/release → release}/artifact-rules.js +0 -0
- /package/dist/{app/release → release}/recovery.js +0 -0
- /package/dist/{domain/release → release}/semver.d.ts +0 -0
- /package/dist/{app/release → release}/state.d.ts +0 -0
- /package/dist/{verify → release}/verify-project.d.ts +0 -0
- /package/dist/{plugins → scm}/capabilities.d.ts +0 -0
- /package/dist/{plugins → scm}/capabilities.js +0 -0
- /package/dist/{domain/strategy → scm}/types.js +0 -0
- /package/dist/{domain/strategy → strategy}/node.d.ts +0 -0
- /package/dist/{domain/strategy → strategy}/r.d.ts +0 -0
- /package/dist/{domain/strategy → strategy}/rust.d.ts +0 -0
- /package/dist/{domain/strategy → strategy}/simple.d.ts +0 -0
- /package/dist/{domain/strategy → strategy}/simple.js +0 -0
- /package/dist/{infra/scm → strategy}/types.js +0 -0
|
@@ -3,68 +3,107 @@ 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");
|
|
10
13
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
11
14
|
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
-
const load_config_js_1 = require("
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
15
|
+
const load_config_js_1 = require("../config/load-config.js");
|
|
16
|
+
const client_js_1 = require("../scm/client.js");
|
|
17
|
+
const resolve_js_1 = require("../strategy/resolve.js");
|
|
18
|
+
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
|
-
const
|
|
27
|
+
const shortVersion = version.replace(/\.\d+$/u, "");
|
|
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));
|
|
34
39
|
if (start < 0) {
|
|
35
|
-
return
|
|
40
|
+
return "";
|
|
36
41
|
}
|
|
37
42
|
let end = lines.length;
|
|
38
43
|
for (let idx = start + 1; idx < lines.length; idx += 1) {
|
|
39
|
-
|
|
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("## ")) {
|
|
40
53
|
end = idx;
|
|
41
54
|
break;
|
|
42
55
|
}
|
|
43
56
|
}
|
|
44
|
-
|
|
57
|
+
return lines
|
|
45
58
|
.slice(start + 1, end)
|
|
46
59
|
.join("\n")
|
|
47
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);
|
|
48
76
|
return notes.length > 0 ? notes : `Automated release for v${version}`;
|
|
49
77
|
}
|
|
50
78
|
function resolveTargetChangelogFile(config, rootChangelogFile, targetPath) {
|
|
51
79
|
if (targetPath === ".") {
|
|
52
80
|
return rootChangelogFile;
|
|
53
81
|
}
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
+
});
|
|
58
88
|
return node_path_1.default.posix.join(targetPath, packageChangelogFile);
|
|
59
89
|
}
|
|
60
|
-
|
|
61
|
-
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 });
|
|
62
101
|
if (result.action === "release-skipped") {
|
|
63
102
|
return result.reason;
|
|
64
103
|
}
|
|
65
104
|
return result.message;
|
|
66
105
|
}
|
|
67
|
-
async function
|
|
106
|
+
async function runReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
68
107
|
const commitMessage = getHeadCommitMessage(cwd);
|
|
69
108
|
if (!(0, pr_js_1.isReleaseCommitMessage)(commitMessage)) {
|
|
70
109
|
return {
|
|
@@ -74,7 +113,7 @@ async function runSimpleReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
|
74
113
|
}
|
|
75
114
|
const loaded = (0, load_config_js_1.loadConfig)(cwd);
|
|
76
115
|
const strategy = (0, resolve_js_1.resolveVersionStrategy)(loaded.config);
|
|
77
|
-
const changelogFile = loaded.config
|
|
116
|
+
const { changelogFile } = (0, plan_js_1.getChangelogDefaults)(loaded.config);
|
|
78
117
|
const version = strategy.readVersion(cwd, loaded.config);
|
|
79
118
|
const defaultTag = `v${version}`;
|
|
80
119
|
const releaseTargets = (0, state_js_1.readReleaseTargets)(cwd);
|
|
@@ -98,25 +137,18 @@ async function runSimpleReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
|
98
137
|
message: `Dry run: would publish releases ${targetList.join(", ")}`,
|
|
99
138
|
};
|
|
100
139
|
}
|
|
101
|
-
const
|
|
102
|
-
const scmPlugins = (0, capabilities_js_1.findPluginsByCapability)(plugins, "scm.releaseMetadata");
|
|
103
|
-
if (scmPlugins.length === 0) {
|
|
104
|
-
throw new Error("No scm.releaseMetadata plugin is available.");
|
|
105
|
-
}
|
|
106
|
-
const plugin = scmPlugins[0];
|
|
107
|
-
if (!plugin?.createReleaseMetadata) {
|
|
108
|
-
throw new Error(`Plugin "${plugin?.name ?? "unknown"}" does not implement createReleaseMetadata.`);
|
|
109
|
-
}
|
|
110
|
-
const createReleaseMetadata = plugin.createReleaseMetadata;
|
|
140
|
+
const scmClient = (0, client_js_1.getScmClient)();
|
|
111
141
|
const releases = [];
|
|
112
142
|
for (const target of targets) {
|
|
113
143
|
const targetChangelogFile = resolveTargetChangelogFile(loaded.config, changelogFile, target.path);
|
|
144
|
+
const targetChangelogFormat = resolveTargetChangelogFormat(loaded.config, target.path);
|
|
114
145
|
const outcome = await (0, recovery_js_1.executeIdempotentReleaseTarget)(cwd, {
|
|
115
146
|
tag: target.tag,
|
|
116
147
|
version: target.version,
|
|
117
|
-
notes: readReleaseNotes(cwd, target.version, targetChangelogFile),
|
|
148
|
+
notes: readReleaseNotes(cwd, target.version, targetChangelogFile, targetChangelogFormat),
|
|
149
|
+
draft: loaded.config["release-draft"] ?? false,
|
|
118
150
|
}, {
|
|
119
|
-
createReleaseMetadata: (input) => createReleaseMetadata(input, {
|
|
151
|
+
createReleaseMetadata: (input) => scmClient.createReleaseMetadata(input, {
|
|
120
152
|
cwd,
|
|
121
153
|
logger: options.logger,
|
|
122
154
|
}),
|
|
@@ -136,3 +168,11 @@ async function runSimpleReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
|
136
168
|
message: `Published releases ${published.join(", ")}`,
|
|
137
169
|
};
|
|
138
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
|
+
}
|
|
@@ -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);
|
|
@@ -10,7 +10,7 @@ exports.writeBaselineSha = writeBaselineSha;
|
|
|
10
10
|
const node_child_process_1 = require("node:child_process");
|
|
11
11
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
12
12
|
const node_path_1 = __importDefault(require("node:path"));
|
|
13
|
-
const load_config_js_1 = require("
|
|
13
|
+
const load_config_js_1 = require("../config/load-config.js");
|
|
14
14
|
const MANIFEST_VERSION_KEY = "manifest-version";
|
|
15
15
|
const BASELINE_SHA_KEY = "baseline-sha";
|
|
16
16
|
const RELEASE_TARGETS_KEY = "release-targets";
|
|
@@ -7,8 +7,8 @@ exports.verifyProject = verifyProject;
|
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
9
|
const load_config_js_1 = require("../config/load-config.js");
|
|
10
|
-
const package_context_js_1 = require("../
|
|
11
|
-
const resolve_js_1 = require("../
|
|
10
|
+
const package_context_js_1 = require("../strategy/package-context.js");
|
|
11
|
+
const resolve_js_1 = require("../strategy/resolve.js");
|
|
12
12
|
function verifyProject(cwd = process.cwd()) {
|
|
13
13
|
const checks = [];
|
|
14
14
|
const config = (0, load_config_js_1.loadConfig)(cwd);
|
|
@@ -90,6 +90,7 @@ function createGitHubPlugin() {
|
|
|
90
90
|
return {
|
|
91
91
|
name: "github",
|
|
92
92
|
capabilities: ["scm.reviewRequest", "scm.releaseMetadata"],
|
|
93
|
+
provider: "github",
|
|
93
94
|
async createOrUpdateReviewRequest(input, _context) {
|
|
94
95
|
const repo = getRepoFromEnv();
|
|
95
96
|
const octokit = new rest_1.Octokit({ auth: getGitHubToken() });
|
|
@@ -194,6 +195,7 @@ function createGitHubPlugin() {
|
|
|
194
195
|
tag_name: input.tag,
|
|
195
196
|
name: input.tag,
|
|
196
197
|
body: input.notes,
|
|
198
|
+
draft: input.draft ?? false,
|
|
197
199
|
});
|
|
198
200
|
data = response.data;
|
|
199
201
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type ScmProvider = "github";
|
|
2
|
+
export interface ScmClientContext {
|
|
3
|
+
cwd: string;
|
|
4
|
+
logger?: {
|
|
5
|
+
info: (message: string) => void;
|
|
6
|
+
warn: (message: string) => void;
|
|
7
|
+
error: (message: string) => void;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export interface ScmReviewRequestInput {
|
|
11
|
+
baseBranch: string;
|
|
12
|
+
headBranch: string;
|
|
13
|
+
title: string;
|
|
14
|
+
body: string;
|
|
15
|
+
labels?: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface ScmReviewRequestResult {
|
|
18
|
+
id: string;
|
|
19
|
+
number?: number;
|
|
20
|
+
url: string;
|
|
21
|
+
state: "open" | "closed" | "merged";
|
|
22
|
+
}
|
|
23
|
+
export interface ScmReleaseMetadataInput {
|
|
24
|
+
tag: string;
|
|
25
|
+
version: string;
|
|
26
|
+
notes: string;
|
|
27
|
+
draft?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface ScmReleaseMetadataResult {
|
|
30
|
+
url: string;
|
|
31
|
+
status?: "created" | "exists";
|
|
32
|
+
}
|
|
33
|
+
export interface ScmClient {
|
|
34
|
+
provider: ScmProvider;
|
|
35
|
+
createOrUpdateReviewRequest: (input: ScmReviewRequestInput, context: ScmClientContext) => Promise<ScmReviewRequestResult>;
|
|
36
|
+
createReleaseMetadata: (input: ScmReleaseMetadataInput, context: ScmClientContext) => Promise<ScmReleaseMetadataResult>;
|
|
37
|
+
}
|
|
@@ -64,4 +64,17 @@ exports.nodeVersionStrategy = {
|
|
|
64
64
|
];
|
|
65
65
|
return updatedFiles;
|
|
66
66
|
},
|
|
67
|
+
readPackageName(cwd, config) {
|
|
68
|
+
const versionFile = this.getVersionFile(config);
|
|
69
|
+
const versionPath = node_path_1.default.join(cwd, versionFile);
|
|
70
|
+
if (!node_fs_1.default.existsSync(versionPath)) {
|
|
71
|
+
throw new Error(`Versionary requires ${versionFile} to exist.`);
|
|
72
|
+
}
|
|
73
|
+
const packageJson = readJsonFile(versionPath);
|
|
74
|
+
const name = packageJson.name;
|
|
75
|
+
if (typeof name !== "string" || name.trim().length === 0) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return name.trim();
|
|
79
|
+
},
|
|
67
80
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { VersionaryConfig, VersionaryPackage } from "
|
|
1
|
+
import type { VersionaryConfig, VersionaryPackage } from "../types/config.js";
|
|
2
2
|
import type { VersionStrategy } from "./types.js";
|
|
3
3
|
export declare function resolvePackageStrategyContext(rootConfig: VersionaryConfig, packagePath: string, packageConfig: VersionaryPackage): {
|
|
4
4
|
strategy: VersionStrategy;
|
|
@@ -34,7 +34,7 @@ function resolvePackageStrategyContext(rootConfig, packagePath, packageConfig) {
|
|
|
34
34
|
}));
|
|
35
35
|
const config = withVersionFile({
|
|
36
36
|
...baseConfig,
|
|
37
|
-
packages: undefined,
|
|
37
|
+
packages: packagePath === "." ? baseConfig.packages : undefined,
|
|
38
38
|
}, versionFile);
|
|
39
39
|
return {
|
|
40
40
|
strategy: baseStrategy,
|
|
@@ -50,7 +50,7 @@ function resolvePackageStrategyContext(rootConfig, packagePath, packageConfig) {
|
|
|
50
50
|
}));
|
|
51
51
|
const config = withVersionFile({
|
|
52
52
|
...baseConfig,
|
|
53
|
-
packages: undefined,
|
|
53
|
+
packages: packagePath === "." ? baseConfig.packages : undefined,
|
|
54
54
|
}, packageVersionFile);
|
|
55
55
|
const strategy = (0, resolve_js_1.resolveVersionStrategy)(config);
|
|
56
56
|
return {
|
|
@@ -43,4 +43,18 @@ exports.rVersionStrategy = {
|
|
|
43
43
|
node_fs_1.default.writeFileSync(versionPath, updated, "utf8");
|
|
44
44
|
return [versionFile];
|
|
45
45
|
},
|
|
46
|
+
readPackageName(cwd, config) {
|
|
47
|
+
const versionFile = this.getVersionFile(config);
|
|
48
|
+
const versionPath = node_path_1.default.join(cwd, versionFile);
|
|
49
|
+
if (!node_fs_1.default.existsSync(versionPath)) {
|
|
50
|
+
throw new Error(`Versionary requires ${versionFile} to exist.`);
|
|
51
|
+
}
|
|
52
|
+
const content = node_fs_1.default.readFileSync(versionPath, "utf8");
|
|
53
|
+
const match = content.match(/^Package:\s*(.+)\s*$/mu);
|
|
54
|
+
if (!match?.[1]) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
const name = match[1].trim();
|
|
58
|
+
return name.length > 0 ? name : null;
|
|
59
|
+
},
|
|
46
60
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import type { VersionaryConfig } from "
|
|
1
|
+
import type { VersionaryConfig } from "../types/config.js";
|
|
2
2
|
import type { VersionStrategy } from "./types.js";
|
|
3
|
+
export declare function listKnownReleaseTypes(): string[];
|
|
3
4
|
export declare function resolveVersionStrategy(config: VersionaryConfig): VersionStrategy;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listKnownReleaseTypes = listKnownReleaseTypes;
|
|
4
|
+
exports.resolveVersionStrategy = resolveVersionStrategy;
|
|
5
|
+
const node_js_1 = require("./node.js");
|
|
6
|
+
const r_js_1 = require("./r.js");
|
|
7
|
+
const rust_js_1 = require("./rust.js");
|
|
8
|
+
const simple_js_1 = require("./simple.js");
|
|
9
|
+
const strategyRegistry = {
|
|
10
|
+
simple: simple_js_1.simpleVersionStrategy,
|
|
11
|
+
node: node_js_1.nodeVersionStrategy,
|
|
12
|
+
rust: rust_js_1.rustVersionStrategy,
|
|
13
|
+
r: r_js_1.rVersionStrategy,
|
|
14
|
+
};
|
|
15
|
+
function listKnownReleaseTypes() {
|
|
16
|
+
return Object.keys(strategyRegistry).sort((a, b) => a.localeCompare(b));
|
|
17
|
+
}
|
|
18
|
+
function resolveVersionStrategy(config) {
|
|
19
|
+
const releaseType = config["release-type"] ?? "simple";
|
|
20
|
+
return strategyRegistry[releaseType] ?? simple_js_1.simpleVersionStrategy;
|
|
21
|
+
}
|
|
@@ -613,4 +613,46 @@ exports.rustVersionStrategy = {
|
|
|
613
613
|
}
|
|
614
614
|
return updatedFiles.sort((a, b) => a.localeCompare(b));
|
|
615
615
|
},
|
|
616
|
+
readPackageName(cwd, config) {
|
|
617
|
+
const versionFile = this.getVersionFile(config);
|
|
618
|
+
const manifests = collectRustTargetManifests(cwd, versionFile, !config.packages);
|
|
619
|
+
const selectedManifest = manifests[0];
|
|
620
|
+
if (!selectedManifest) {
|
|
621
|
+
throw new Error(`Configured rust target "${versionFile}" did not resolve to a Rust crate manifest.`);
|
|
622
|
+
}
|
|
623
|
+
const versionPath = node_path_1.default.join(cwd, selectedManifest);
|
|
624
|
+
if (!node_fs_1.default.existsSync(versionPath)) {
|
|
625
|
+
throw new Error(`Versionary requires ${selectedManifest} to exist.`);
|
|
626
|
+
}
|
|
627
|
+
const cargoTomlRaw = node_fs_1.default.readFileSync(versionPath, "utf8");
|
|
628
|
+
if (!isCrateManifest(selectedManifest, cargoTomlRaw)) {
|
|
629
|
+
return null;
|
|
630
|
+
}
|
|
631
|
+
return readCargoPackageName(cargoTomlRaw, selectedManifest);
|
|
632
|
+
},
|
|
633
|
+
propagateDependentPatchImpacts(cwd, packages) {
|
|
634
|
+
const manifestToVersion = {};
|
|
635
|
+
const candidateManifests = [];
|
|
636
|
+
const manifestToPath = new Map();
|
|
637
|
+
for (const pkg of packages) {
|
|
638
|
+
const manifest = pkg.versionFile;
|
|
639
|
+
candidateManifests.push(manifest);
|
|
640
|
+
manifestToPath.set(manifest, pkg.packagePath);
|
|
641
|
+
if (pkg.nextVersion) {
|
|
642
|
+
manifestToVersion[manifest] = pkg.nextVersion;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
const impactedManifests = detectRustDependencyImpact(cwd, manifestToVersion, candidateManifests);
|
|
646
|
+
return impactedManifests
|
|
647
|
+
.map((manifest) => manifestToPath.get(manifest))
|
|
648
|
+
.filter((pkgPath) => Boolean(pkgPath))
|
|
649
|
+
.sort((a, b) => a.localeCompare(b));
|
|
650
|
+
},
|
|
651
|
+
finalizeVersionWrites(cwd, writes) {
|
|
652
|
+
const manifestToVersion = {};
|
|
653
|
+
for (const write of writes) {
|
|
654
|
+
manifestToVersion[write.versionFile] = write.version;
|
|
655
|
+
}
|
|
656
|
+
return applyRustWorkspaceDependencyUpdates(cwd, manifestToVersion);
|
|
657
|
+
},
|
|
616
658
|
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { VersionaryConfig } from "../types/config.js";
|
|
2
|
+
export interface StrategyPackagePlanContext {
|
|
3
|
+
packagePath: string;
|
|
4
|
+
versionFile: string;
|
|
5
|
+
currentVersion: string;
|
|
6
|
+
nextVersion: string | null;
|
|
7
|
+
}
|
|
8
|
+
export interface StrategyVersionWriteContext {
|
|
9
|
+
packagePath: string;
|
|
10
|
+
versionFile: string;
|
|
11
|
+
version: string;
|
|
12
|
+
}
|
|
13
|
+
export interface VersionStrategy {
|
|
14
|
+
name: string;
|
|
15
|
+
getVersionFile(config: VersionaryConfig): string;
|
|
16
|
+
readVersion(cwd: string, config: VersionaryConfig): string;
|
|
17
|
+
writeVersion(cwd: string, config: VersionaryConfig, version: string): string[];
|
|
18
|
+
readPackageName?(cwd: string, config: VersionaryConfig): string | null;
|
|
19
|
+
propagateDependentPatchImpacts?(cwd: string, packages: StrategyPackagePlanContext[]): string[];
|
|
20
|
+
finalizeVersionWrites?(cwd: string, writes: StrategyVersionWriteContext[]): string[];
|
|
21
|
+
}
|
package/dist/types/config.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type ConfigFileFormat = "jsonc" | "json" | "toml" | "js";
|
|
2
|
+
export type VersionaryChangelogFormat = "markdown-changelog" | "r-news";
|
|
2
3
|
export interface VersionaryArtifactRule {
|
|
3
4
|
type: "json" | "toml" | "yaml" | "regex";
|
|
4
5
|
path: string;
|
|
@@ -10,6 +11,7 @@ export interface VersionaryPackage {
|
|
|
10
11
|
"release-type"?: string;
|
|
11
12
|
"package-name"?: string;
|
|
12
13
|
"changelog-file"?: string;
|
|
14
|
+
"changelog-format"?: VersionaryChangelogFormat;
|
|
13
15
|
"exclude-paths"?: string[];
|
|
14
16
|
"extra-files"?: VersionaryArtifactRule[];
|
|
15
17
|
}
|
|
@@ -18,6 +20,8 @@ export interface VersionaryConfig {
|
|
|
18
20
|
"review-mode"?: "direct" | "pr" | "review";
|
|
19
21
|
"version-file"?: string;
|
|
20
22
|
"changelog-file"?: string;
|
|
23
|
+
"changelog-format"?: VersionaryChangelogFormat;
|
|
24
|
+
"release-draft"?: boolean;
|
|
21
25
|
"release-branch"?: string;
|
|
22
26
|
"baseline-file"?: string;
|
|
23
27
|
"bootstrap-sha"?: string;
|
package/dist/types/plugins.d.ts
CHANGED
|
@@ -1,37 +1,14 @@
|
|
|
1
|
+
import type { ScmClientContext, ScmProvider, ScmReleaseMetadataInput, ScmReleaseMetadataResult, ScmReviewRequestInput, ScmReviewRequestResult } from "../scm/types.js";
|
|
1
2
|
export type VersionaryPluginCapability = "scm.reviewRequest" | "scm.releaseMetadata";
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
labels?: string[];
|
|
8
|
-
}
|
|
9
|
-
export interface VersionaryScmReviewRequestResult {
|
|
10
|
-
id: string;
|
|
11
|
-
number?: number;
|
|
12
|
-
url: string;
|
|
13
|
-
state: "open" | "closed" | "merged";
|
|
14
|
-
}
|
|
15
|
-
export interface VersionaryScmReleaseMetadataInput {
|
|
16
|
-
tag: string;
|
|
17
|
-
version: string;
|
|
18
|
-
notes: string;
|
|
19
|
-
}
|
|
20
|
-
export interface VersionaryScmReleaseMetadataResult {
|
|
21
|
-
url: string;
|
|
22
|
-
status?: "created" | "exists";
|
|
23
|
-
}
|
|
24
|
-
export interface VersionaryPluginContext {
|
|
25
|
-
cwd: string;
|
|
26
|
-
logger?: {
|
|
27
|
-
info: (message: string) => void;
|
|
28
|
-
warn: (message: string) => void;
|
|
29
|
-
error: (message: string) => void;
|
|
30
|
-
};
|
|
31
|
-
}
|
|
3
|
+
export type VersionaryScmReviewRequestInput = ScmReviewRequestInput;
|
|
4
|
+
export type VersionaryScmReviewRequestResult = ScmReviewRequestResult;
|
|
5
|
+
export type VersionaryScmReleaseMetadataInput = ScmReleaseMetadataInput;
|
|
6
|
+
export type VersionaryScmReleaseMetadataResult = ScmReleaseMetadataResult;
|
|
7
|
+
export type VersionaryPluginContext = ScmClientContext;
|
|
32
8
|
export interface VersionaryPluginRuntime {
|
|
33
9
|
name: string;
|
|
34
10
|
capabilities: VersionaryPluginCapability[];
|
|
11
|
+
provider?: ScmProvider;
|
|
35
12
|
createOrUpdateReviewRequest?: (input: VersionaryScmReviewRequestInput, context: VersionaryPluginContext) => Promise<VersionaryScmReviewRequestResult>;
|
|
36
13
|
createReleaseMetadata?: (input: VersionaryScmReleaseMetadataInput, context: VersionaryPluginContext) => Promise<VersionaryScmReleaseMetadataResult>;
|
|
37
14
|
}
|
package/package.json
CHANGED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.verifyProject = void 0;
|
|
4
|
-
var verify_project_js_1 = require("../../verify/verify-project.js");
|
|
5
|
-
Object.defineProperty(exports, "verifyProject", { enumerable: true, get: function () { return verify_project_js_1.verifyProject; } });
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { type ParsedCommit } from "../../infra/git/commits.js";
|
|
2
|
-
import type { SimplePlan } from "./plan.js";
|
|
3
|
-
export declare function renderSimpleReleaseNotes(input: {
|
|
4
|
-
currentVersion: string;
|
|
5
|
-
nextVersion: string;
|
|
6
|
-
commits: ParsedCommit[];
|
|
7
|
-
cwd?: string;
|
|
8
|
-
}, options?: {
|
|
9
|
-
includeFooter?: boolean;
|
|
10
|
-
}): string;
|
|
11
|
-
export declare function renderSimpleChangelog(plan: SimplePlan): string;
|
|
12
|
-
export declare function renderPackageChangelogSection(input: {
|
|
13
|
-
currentVersion: string;
|
|
14
|
-
nextVersion: string;
|
|
15
|
-
commits: ParsedCommit[];
|
|
16
|
-
tagPrefix: string;
|
|
17
|
-
cwd?: string;
|
|
18
|
-
}): string;
|
|
19
|
-
export declare function prependChangelog(cwd: string, changelogFile: string, section: string): void;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { type ParsedCommit } from "../../infra/git/commits.js";
|
|
2
|
-
import { type ReleaseType } from "./semver.js";
|
|
3
|
-
export interface SimplePlan {
|
|
4
|
-
mode: "simple";
|
|
5
|
-
releaseType: ReleaseType;
|
|
6
|
-
currentVersion: string;
|
|
7
|
-
nextVersion: string | null;
|
|
8
|
-
versionFile: string;
|
|
9
|
-
changelogFile: string;
|
|
10
|
-
releaseBranchPrefix: string;
|
|
11
|
-
baselineSha: string | null;
|
|
12
|
-
commits: ParsedCommit[];
|
|
13
|
-
packages?: Array<{
|
|
14
|
-
path: string;
|
|
15
|
-
releaseType: ReleaseType;
|
|
16
|
-
currentVersion: string;
|
|
17
|
-
nextVersion: string | null;
|
|
18
|
-
commits: ParsedCommit[];
|
|
19
|
-
}>;
|
|
20
|
-
}
|
|
21
|
-
export declare function createSimplePlan(cwd?: string): SimplePlan;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveVersionStrategy = resolveVersionStrategy;
|
|
4
|
-
const node_js_1 = require("./node.js");
|
|
5
|
-
const r_js_1 = require("./r.js");
|
|
6
|
-
const rust_js_1 = require("./rust.js");
|
|
7
|
-
const simple_js_1 = require("./simple.js");
|
|
8
|
-
function resolveVersionStrategy(config) {
|
|
9
|
-
if (config["release-type"] === "node") {
|
|
10
|
-
return node_js_1.nodeVersionStrategy;
|
|
11
|
-
}
|
|
12
|
-
if (config["release-type"] === "rust") {
|
|
13
|
-
return rust_js_1.rustVersionStrategy;
|
|
14
|
-
}
|
|
15
|
-
if (config["release-type"] === "r") {
|
|
16
|
-
return r_js_1.rVersionStrategy;
|
|
17
|
-
}
|
|
18
|
-
return simple_js_1.simpleVersionStrategy;
|
|
19
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { VersionaryConfig } from "../../types/config.js";
|
|
2
|
-
export interface VersionStrategy {
|
|
3
|
-
name: string;
|
|
4
|
-
getVersionFile(config: VersionaryConfig): string;
|
|
5
|
-
readVersion(cwd: string, config: VersionaryConfig): string;
|
|
6
|
-
writeVersion(cwd: string, config: VersionaryConfig, version: string): string[];
|
|
7
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { createGitHubPlugin } from "../../../scm/github-plugin.js";
|