versionary 0.27.0 → 0.28.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/action/index.js +7 -9
- package/dist/cli/index.js +32 -34
- package/dist/config/load-config.js +16 -23
- package/dist/config/schema.js +45 -48
- package/dist/git/commits.js +23 -42
- package/dist/git/identity.js +7 -11
- package/dist/git/repo-url.js +3 -6
- package/dist/index.js +6 -16
- package/dist/release/artifact-rules.js +15 -21
- package/dist/release/changelog.js +24 -35
- package/dist/release/plan.js +34 -43
- package/dist/release/pr.js +72 -96
- package/dist/release/recovery.js +9 -12
- package/dist/release/release.d.ts +1 -0
- package/dist/release/release.js +60 -56
- package/dist/release/semver.js +5 -12
- package/dist/release/state.js +22 -31
- package/dist/release/verify-project.js +14 -20
- package/dist/scm/capabilities.js +2 -6
- package/dist/scm/client.js +3 -6
- package/dist/scm/github-plugin.js +46 -13
- package/dist/scm/types.d.ts +6 -1
- package/dist/scm/types.js +1 -2
- package/dist/strategy/composite.js +1 -4
- package/dist/strategy/latex.js +18 -24
- package/dist/strategy/node.js +13 -19
- package/dist/strategy/package-context.d.ts +1 -0
- package/dist/strategy/package-context.js +14 -13
- package/dist/strategy/python.js +35 -41
- package/dist/strategy/r.js +16 -22
- package/dist/strategy/resolve.js +16 -20
- package/dist/strategy/rust.js +80 -89
- package/dist/strategy/simple.js +8 -14
- package/dist/strategy/types.js +1 -2
- package/dist/types/config.js +1 -2
- package/dist/types/plugins.js +1 -2
- package/package.json +3 -3
package/dist/release/release.js
CHANGED
|
@@ -1,29 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
exports.runSimpleReleaseDetailed = runSimpleReleaseDetailed;
|
|
13
|
-
const node_child_process_1 = require("node:child_process");
|
|
14
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
15
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
16
|
-
const load_config_js_1 = require("../config/load-config.js");
|
|
17
|
-
const client_js_1 = require("../scm/client.js");
|
|
18
|
-
const resolve_js_1 = require("../strategy/resolve.js");
|
|
19
|
-
const plan_js_1 = require("./plan.js");
|
|
20
|
-
const pr_js_1 = require("./pr.js");
|
|
21
|
-
const recovery_js_1 = require("./recovery.js");
|
|
22
|
-
const state_js_1 = require("./state.js");
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { loadConfig } from "../config/load-config.js";
|
|
5
|
+
import { getScmClient } from "../scm/client.js";
|
|
6
|
+
import { resolvePackageStrategyContext, resolveReleaseName, } from "../strategy/package-context.js";
|
|
7
|
+
import { resolveVersionStrategy } from "../strategy/resolve.js";
|
|
8
|
+
import { getChangelogDefaults } from "./plan.js";
|
|
9
|
+
import { isReleaseCommitMessage } from "./pr.js";
|
|
10
|
+
import { executeIdempotentReleaseTarget } from "./recovery.js";
|
|
11
|
+
import { readReleaseTargets } from "./state.js";
|
|
23
12
|
function escapeRegExp(input) {
|
|
24
13
|
return input.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
25
14
|
}
|
|
26
|
-
function
|
|
15
|
+
export function resolveTargetPackageName(cwd, config, targetPath) {
|
|
16
|
+
const packageConfig = config.packages?.[targetPath] ?? {};
|
|
17
|
+
const { strategy, config: strategyConfig } = resolvePackageStrategyContext(config, targetPath, packageConfig);
|
|
18
|
+
const resolved = resolveReleaseName(cwd, targetPath, packageConfig, strategy, strategyConfig);
|
|
19
|
+
if (!resolved || resolved === targetPath) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
return resolved;
|
|
23
|
+
}
|
|
24
|
+
export function extractReleaseNotes(content, version, changelogFormat) {
|
|
27
25
|
const lines = content.split("\n");
|
|
28
26
|
const shortVersion = version.replace(/\.\d+$/u, "");
|
|
29
27
|
const start = changelogFormat === "r-news"
|
|
@@ -61,22 +59,22 @@ function extractReleaseNotes(content, version, changelogFormat) {
|
|
|
61
59
|
.trim();
|
|
62
60
|
}
|
|
63
61
|
function getHeadCommitMessage(cwd) {
|
|
64
|
-
return
|
|
62
|
+
return execFileSync("git", ["log", "-1", "--pretty=%B"], {
|
|
65
63
|
cwd,
|
|
66
64
|
encoding: "utf8",
|
|
67
65
|
stdio: ["ignore", "pipe", "ignore"],
|
|
68
66
|
}).trim();
|
|
69
67
|
}
|
|
70
68
|
function readReleaseNotes(cwd, version, changelogFile, changelogFormat) {
|
|
71
|
-
const changelogPath =
|
|
72
|
-
if (!
|
|
69
|
+
const changelogPath = path.join(cwd, changelogFile);
|
|
70
|
+
if (!fs.existsSync(changelogPath)) {
|
|
73
71
|
return `Automated release for v${version}`;
|
|
74
72
|
}
|
|
75
|
-
const content =
|
|
73
|
+
const content = fs.readFileSync(changelogPath, "utf8");
|
|
76
74
|
const notes = extractReleaseNotes(content, version, changelogFormat);
|
|
77
75
|
return notes.length > 0 ? notes : `Automated release for v${version}`;
|
|
78
76
|
}
|
|
79
|
-
function extractClosingReferencesFromNotes(notes) {
|
|
77
|
+
export function extractClosingReferencesFromNotes(notes) {
|
|
80
78
|
const refs = new Set();
|
|
81
79
|
const linkedPattern = /\b(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\b\s+\[#(\d+)\]\([^)]+\)/giu;
|
|
82
80
|
for (const match of notes.matchAll(linkedPattern)) {
|
|
@@ -94,30 +92,30 @@ function extractClosingReferencesFromNotes(notes) {
|
|
|
94
92
|
}
|
|
95
93
|
return [...refs].sort((a, b) => a - b);
|
|
96
94
|
}
|
|
97
|
-
function resolveTargetChangelogFile(config, rootChangelogFile, targetPath) {
|
|
95
|
+
export function resolveTargetChangelogFile(config, rootChangelogFile, targetPath) {
|
|
98
96
|
if (targetPath === ".") {
|
|
99
97
|
return rootChangelogFile;
|
|
100
98
|
}
|
|
101
99
|
const packageConfig = config.packages?.[targetPath];
|
|
102
|
-
const packageStrategy =
|
|
100
|
+
const packageStrategy = resolveVersionStrategy({
|
|
103
101
|
...config,
|
|
104
102
|
"release-type": packageConfig?.["release-type"] ?? config["release-type"],
|
|
105
103
|
});
|
|
106
|
-
const { changelogFile: packageChangelogFile } =
|
|
104
|
+
const { changelogFile: packageChangelogFile } = getChangelogDefaults({
|
|
107
105
|
"release-type": packageConfig?.["release-type"] ?? config["release-type"],
|
|
108
106
|
"changelog-file": packageConfig?.["changelog-file"] ?? config["changelog-file"],
|
|
109
107
|
"changelog-format": packageConfig?.["changelog-format"] ?? config["changelog-format"],
|
|
110
108
|
defaultChangelogFormat: packageStrategy.getDefaultChangelogFormat?.(),
|
|
111
109
|
});
|
|
112
|
-
return
|
|
110
|
+
return path.posix.join(targetPath, packageChangelogFile);
|
|
113
111
|
}
|
|
114
112
|
function resolveTargetChangelogFormat(config, targetPath) {
|
|
115
113
|
const packageConfig = config.packages?.[targetPath];
|
|
116
|
-
const packageStrategy =
|
|
114
|
+
const packageStrategy = resolveVersionStrategy({
|
|
117
115
|
...config,
|
|
118
116
|
"release-type": packageConfig?.["release-type"] ?? config["release-type"],
|
|
119
117
|
});
|
|
120
|
-
const { changelogFormat } =
|
|
118
|
+
const { changelogFormat } = getChangelogDefaults({
|
|
121
119
|
"release-type": packageConfig?.["release-type"] ?? config["release-type"],
|
|
122
120
|
"changelog-file": packageConfig?.["changelog-file"] ?? config["changelog-file"],
|
|
123
121
|
"changelog-format": packageConfig?.["changelog-format"] ?? config["changelog-format"],
|
|
@@ -125,31 +123,31 @@ function resolveTargetChangelogFormat(config, targetPath) {
|
|
|
125
123
|
});
|
|
126
124
|
return changelogFormat;
|
|
127
125
|
}
|
|
128
|
-
async function runRelease(cwd = process.cwd()) {
|
|
126
|
+
export async function runRelease(cwd = process.cwd()) {
|
|
129
127
|
const result = await runReleaseDetailed(cwd, { logger: console });
|
|
130
128
|
if (result.action === "release-skipped") {
|
|
131
129
|
return result.reason;
|
|
132
130
|
}
|
|
133
131
|
return result.message;
|
|
134
132
|
}
|
|
135
|
-
async function runReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
133
|
+
export async function runReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
136
134
|
const commitMessage = getHeadCommitMessage(cwd);
|
|
137
|
-
if (!
|
|
135
|
+
if (!isReleaseCommitMessage(commitMessage)) {
|
|
138
136
|
return {
|
|
139
137
|
action: "release-skipped",
|
|
140
138
|
reason: "No release commit context detected; skipping release stage.",
|
|
141
139
|
};
|
|
142
140
|
}
|
|
143
|
-
const loaded =
|
|
144
|
-
const strategy =
|
|
145
|
-
const { changelogFile } =
|
|
141
|
+
const loaded = loadConfig(cwd);
|
|
142
|
+
const strategy = resolveVersionStrategy(loaded.config);
|
|
143
|
+
const { changelogFile } = getChangelogDefaults({
|
|
146
144
|
...loaded.config,
|
|
147
145
|
defaultChangelogFormat: strategy.getDefaultChangelogFormat?.(),
|
|
148
146
|
});
|
|
149
147
|
const referenceCommentMode = loaded.config["release-reference-comments"] ?? "off";
|
|
150
148
|
const version = strategy.readVersion(cwd, loaded.config);
|
|
151
149
|
const defaultTag = `v${version}`;
|
|
152
|
-
const releaseTargets =
|
|
150
|
+
const releaseTargets = readReleaseTargets(cwd);
|
|
153
151
|
const targets = releaseTargets.length > 0
|
|
154
152
|
? releaseTargets
|
|
155
153
|
: [
|
|
@@ -170,15 +168,15 @@ async function runReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
|
170
168
|
message: `Dry run: would publish releases ${targetList.join(", ")}`,
|
|
171
169
|
};
|
|
172
170
|
}
|
|
173
|
-
const scmClient =
|
|
171
|
+
const scmClient = getScmClient();
|
|
174
172
|
const releases = [];
|
|
175
|
-
const
|
|
173
|
+
const referenceReleases = [];
|
|
176
174
|
for (const target of targets) {
|
|
177
175
|
const targetChangelogFile = resolveTargetChangelogFile(loaded.config, changelogFile, target.path);
|
|
178
176
|
const targetChangelogFormat = resolveTargetChangelogFormat(loaded.config, target.path);
|
|
179
177
|
const releaseNotes = readReleaseNotes(cwd, target.version, targetChangelogFile, targetChangelogFormat);
|
|
180
|
-
|
|
181
|
-
const outcome = await
|
|
178
|
+
const references = extractClosingReferencesFromNotes(releaseNotes);
|
|
179
|
+
const outcome = await executeIdempotentReleaseTarget(cwd, {
|
|
182
180
|
tag: target.tag,
|
|
183
181
|
version: target.version,
|
|
184
182
|
notes: releaseNotes,
|
|
@@ -197,21 +195,27 @@ async function runReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
|
197
195
|
tagStatus: outcome.tagStatus,
|
|
198
196
|
metadataStatus: outcome.metadataStatus,
|
|
199
197
|
});
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
await scmClient.createReleaseReferenceComments({
|
|
198
|
+
if (references.length > 0) {
|
|
199
|
+
referenceReleases.push({
|
|
200
|
+
name: resolveTargetPackageName(cwd, loaded.config, target.path),
|
|
201
|
+
tag: outcome.tag,
|
|
205
202
|
version: target.version,
|
|
206
203
|
releaseUrl: outcome.url,
|
|
207
204
|
references,
|
|
208
|
-
mode: referenceCommentMode,
|
|
209
|
-
}, {
|
|
210
|
-
cwd,
|
|
211
|
-
logger: options.logger,
|
|
212
205
|
});
|
|
213
206
|
}
|
|
214
207
|
}
|
|
208
|
+
if (referenceReleases.length > 0 &&
|
|
209
|
+
referenceCommentMode !== "off" &&
|
|
210
|
+
scmClient.createReleaseReferenceComments) {
|
|
211
|
+
await scmClient.createReleaseReferenceComments({
|
|
212
|
+
releases: referenceReleases,
|
|
213
|
+
mode: referenceCommentMode,
|
|
214
|
+
}, {
|
|
215
|
+
cwd,
|
|
216
|
+
logger: options.logger,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
215
219
|
const published = releases.map((outcome) => `${outcome.tag}: ${outcome.url} (tag=${outcome.tagStatus}, metadata=${outcome.metadataStatus})`);
|
|
216
220
|
return {
|
|
217
221
|
action: "release-published",
|
|
@@ -220,10 +224,10 @@ async function runReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
|
220
224
|
};
|
|
221
225
|
}
|
|
222
226
|
/** @deprecated Use runRelease. */
|
|
223
|
-
async function runSimpleRelease(cwd = process.cwd()) {
|
|
227
|
+
export async function runSimpleRelease(cwd = process.cwd()) {
|
|
224
228
|
return runRelease(cwd);
|
|
225
229
|
}
|
|
226
230
|
/** @deprecated Use runReleaseDetailed. */
|
|
227
|
-
async function runSimpleReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
231
|
+
export async function runSimpleReleaseDetailed(cwd = process.cwd(), options = {}) {
|
|
228
232
|
return runReleaseDetailed(cwd, options);
|
|
229
233
|
}
|
package/dist/release/semver.js
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.maxReleaseType = maxReleaseType;
|
|
4
|
-
exports.parseVersion = parseVersion;
|
|
5
|
-
exports.isValidVersion = isValidVersion;
|
|
6
|
-
exports.compareVersions = compareVersions;
|
|
7
|
-
exports.bumpVersion = bumpVersion;
|
|
8
|
-
function maxReleaseType(types) {
|
|
1
|
+
export function maxReleaseType(types) {
|
|
9
2
|
if (types.includes("major")) {
|
|
10
3
|
return "major";
|
|
11
4
|
}
|
|
@@ -28,7 +21,7 @@ function normalizeVersionInput(version) {
|
|
|
28
21
|
const [, major, minor, patch, prerelease] = compatMatch;
|
|
29
22
|
return `${major}.${minor}.${patch}-${prerelease}`;
|
|
30
23
|
}
|
|
31
|
-
function parseVersion(version) {
|
|
24
|
+
export function parseVersion(version) {
|
|
32
25
|
const normalized = normalizeVersionInput(version);
|
|
33
26
|
const match = normalized.match(SEMVER_PATTERN);
|
|
34
27
|
if (!match) {
|
|
@@ -42,7 +35,7 @@ function parseVersion(version) {
|
|
|
42
35
|
build: match[5] ? match[5].split(".") : [],
|
|
43
36
|
};
|
|
44
37
|
}
|
|
45
|
-
function isValidVersion(version) {
|
|
38
|
+
export function isValidVersion(version) {
|
|
46
39
|
return SEMVER_PATTERN.test(normalizeVersionInput(version));
|
|
47
40
|
}
|
|
48
41
|
function isNumericIdentifier(identifier) {
|
|
@@ -76,7 +69,7 @@ function comparePreReleaseIdentifiers(left, right) {
|
|
|
76
69
|
}
|
|
77
70
|
return 0;
|
|
78
71
|
}
|
|
79
|
-
function compareVersions(leftRaw, rightRaw) {
|
|
72
|
+
export function compareVersions(leftRaw, rightRaw) {
|
|
80
73
|
const left = parseVersion(leftRaw);
|
|
81
74
|
const right = parseVersion(rightRaw);
|
|
82
75
|
if (left.major !== right.major) {
|
|
@@ -116,7 +109,7 @@ function compareVersions(leftRaw, rightRaw) {
|
|
|
116
109
|
}
|
|
117
110
|
return 0;
|
|
118
111
|
}
|
|
119
|
-
function bumpVersion(current, releaseType, options = {}) {
|
|
112
|
+
export function bumpVersion(current, releaseType, options = {}) {
|
|
120
113
|
const parsed = parseVersion(current);
|
|
121
114
|
const allowStableMajor = options.allowStableMajor ?? false;
|
|
122
115
|
if (releaseType === "major") {
|
package/dist/release/state.js
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getBaselineStatePath = getBaselineStatePath;
|
|
7
|
-
exports.readBaselineSha = readBaselineSha;
|
|
8
|
-
exports.readReleaseTargets = readReleaseTargets;
|
|
9
|
-
exports.writeBaselineSha = writeBaselineSha;
|
|
10
|
-
const node_child_process_1 = require("node:child_process");
|
|
11
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
12
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
13
|
-
const load_config_js_1 = require("../config/load-config.js");
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { loadConfig } from "../config/load-config.js";
|
|
14
5
|
const MANIFEST_VERSION_KEY = "manifest-version";
|
|
15
6
|
const BASELINE_SHA_KEY = "baseline-sha";
|
|
16
7
|
const RELEASE_TARGETS_KEY = "release-targets";
|
|
@@ -47,48 +38,48 @@ function parseStateFile(raw, filePath) {
|
|
|
47
38
|
}
|
|
48
39
|
return manifest;
|
|
49
40
|
}
|
|
50
|
-
function getBaselineStatePath(cwd) {
|
|
51
|
-
const loaded =
|
|
41
|
+
export function getBaselineStatePath(cwd) {
|
|
42
|
+
const loaded = loadConfig(cwd);
|
|
52
43
|
const configured = loaded.config["baseline-file"];
|
|
53
44
|
if (configured) {
|
|
54
|
-
return
|
|
45
|
+
return path.join(cwd, configured);
|
|
55
46
|
}
|
|
56
|
-
const preferred =
|
|
57
|
-
if (
|
|
47
|
+
const preferred = path.join(cwd, ".versionary-manifest.json");
|
|
48
|
+
if (fs.existsSync(preferred)) {
|
|
58
49
|
return preferred;
|
|
59
50
|
}
|
|
60
|
-
const legacy =
|
|
61
|
-
if (
|
|
51
|
+
const legacy = path.join(cwd, "versionary.versions.json");
|
|
52
|
+
if (fs.existsSync(legacy)) {
|
|
62
53
|
return legacy;
|
|
63
54
|
}
|
|
64
55
|
return preferred;
|
|
65
56
|
}
|
|
66
|
-
function readBaselineSha(cwd = process.cwd()) {
|
|
57
|
+
export function readBaselineSha(cwd = process.cwd()) {
|
|
67
58
|
const filePath = getBaselineStatePath(cwd);
|
|
68
|
-
if (!
|
|
59
|
+
if (!fs.existsSync(filePath)) {
|
|
69
60
|
return null;
|
|
70
61
|
}
|
|
71
|
-
const parsed = parseStateFile(
|
|
62
|
+
const parsed = parseStateFile(fs.readFileSync(filePath, "utf8"), filePath);
|
|
72
63
|
return parsed[BASELINE_SHA_KEY] ?? null;
|
|
73
64
|
}
|
|
74
|
-
function readReleaseTargets(cwd = process.cwd()) {
|
|
65
|
+
export function readReleaseTargets(cwd = process.cwd()) {
|
|
75
66
|
const filePath = getBaselineStatePath(cwd);
|
|
76
|
-
if (!
|
|
67
|
+
if (!fs.existsSync(filePath)) {
|
|
77
68
|
return [];
|
|
78
69
|
}
|
|
79
|
-
const parsed = parseStateFile(
|
|
70
|
+
const parsed = parseStateFile(fs.readFileSync(filePath, "utf8"), filePath);
|
|
80
71
|
return parsed[RELEASE_TARGETS_KEY] ?? [];
|
|
81
72
|
}
|
|
82
|
-
function writeBaselineSha(cwd = process.cwd(), sha, releaseTargets) {
|
|
73
|
+
export function writeBaselineSha(cwd = process.cwd(), sha, releaseTargets) {
|
|
83
74
|
const baselineShaValue = sha ??
|
|
84
|
-
|
|
75
|
+
execFileSync("git", ["rev-parse", "HEAD"], {
|
|
85
76
|
cwd,
|
|
86
77
|
encoding: "utf8",
|
|
87
78
|
stdio: ["ignore", "pipe", "ignore"],
|
|
88
79
|
}).trim();
|
|
89
80
|
const filePath = getBaselineStatePath(cwd);
|
|
90
|
-
const existing =
|
|
91
|
-
? parseStateFile(
|
|
81
|
+
const existing = fs.existsSync(filePath)
|
|
82
|
+
? parseStateFile(fs.readFileSync(filePath, "utf8"), filePath)
|
|
92
83
|
: {};
|
|
93
84
|
const existingTargets = existing[RELEASE_TARGETS_KEY] ?? [];
|
|
94
85
|
const nextTargets = releaseTargets === undefined
|
|
@@ -104,5 +95,5 @@ function writeBaselineSha(cwd = process.cwd(), sha, releaseTargets) {
|
|
|
104
95
|
[BASELINE_SHA_KEY]: baselineShaValue,
|
|
105
96
|
[RELEASE_TARGETS_KEY]: nextTargets,
|
|
106
97
|
};
|
|
107
|
-
|
|
98
|
+
fs.writeFileSync(filePath, `${JSON.stringify(next, null, 2)}\n`, "utf8");
|
|
108
99
|
}
|
|
@@ -1,26 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
-
const load_config_js_1 = require("../config/load-config.js");
|
|
10
|
-
const package_context_js_1 = require("../strategy/package-context.js");
|
|
11
|
-
const resolve_js_1 = require("../strategy/resolve.js");
|
|
12
|
-
function verifyProject(cwd = process.cwd()) {
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { loadConfig } from "../config/load-config.js";
|
|
4
|
+
import { resolvePackageStrategyContext } from "../strategy/package-context.js";
|
|
5
|
+
import { resolveVersionStrategy } from "../strategy/resolve.js";
|
|
6
|
+
export function verifyProject(cwd = process.cwd()) {
|
|
13
7
|
const checks = [];
|
|
14
|
-
const config =
|
|
8
|
+
const config = loadConfig(cwd);
|
|
15
9
|
checks.push({
|
|
16
10
|
name: "config-load",
|
|
17
11
|
ok: true,
|
|
18
|
-
details: `Loaded ${
|
|
12
|
+
details: `Loaded ${path.basename(config.path)} (${config.format})`,
|
|
19
13
|
category: "config",
|
|
20
14
|
});
|
|
21
|
-
const strategy =
|
|
15
|
+
const strategy = resolveVersionStrategy(config.config);
|
|
22
16
|
const versionFile = strategy.getVersionFile(config.config);
|
|
23
|
-
const exists =
|
|
17
|
+
const exists = fs.existsSync(path.join(cwd, versionFile));
|
|
24
18
|
checks.push({
|
|
25
19
|
name: `version-file:${versionFile}`,
|
|
26
20
|
ok: exists,
|
|
@@ -44,8 +38,8 @@ function verifyProject(cwd = process.cwd()) {
|
|
|
44
38
|
}
|
|
45
39
|
if (config.config.packages) {
|
|
46
40
|
for (const [pkgPathRaw, packageConfig] of Object.entries(config.config.packages)) {
|
|
47
|
-
const pkgPath =
|
|
48
|
-
const exists =
|
|
41
|
+
const pkgPath = path.join(cwd, pkgPathRaw);
|
|
42
|
+
const exists = fs.existsSync(pkgPath);
|
|
49
43
|
checks.push({
|
|
50
44
|
name: `package-path:${pkgPathRaw}`,
|
|
51
45
|
ok: exists,
|
|
@@ -56,9 +50,9 @@ function verifyProject(cwd = process.cwd()) {
|
|
|
56
50
|
: `Create ${pkgPathRaw} or remove/rename this entry under "packages" in versionary config.`,
|
|
57
51
|
});
|
|
58
52
|
if (exists) {
|
|
59
|
-
const packageContext =
|
|
53
|
+
const packageContext = resolvePackageStrategyContext(config.config, pkgPathRaw, packageConfig);
|
|
60
54
|
const packageVersionFile = packageContext.versionFile;
|
|
61
|
-
const packageVersionExists =
|
|
55
|
+
const packageVersionExists = fs.existsSync(path.join(cwd, packageVersionFile));
|
|
62
56
|
checks.push({
|
|
63
57
|
name: `version-file:${packageVersionFile}`,
|
|
64
58
|
ok: packageVersionExists,
|
package/dist/scm/capabilities.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.pluginHasCapability = pluginHasCapability;
|
|
4
|
-
exports.findPluginsByCapability = findPluginsByCapability;
|
|
5
|
-
function pluginHasCapability(plugin, capability) {
|
|
1
|
+
export function pluginHasCapability(plugin, capability) {
|
|
6
2
|
return plugin.capabilities.includes(capability);
|
|
7
3
|
}
|
|
8
|
-
function findPluginsByCapability(plugins, capability) {
|
|
4
|
+
export function findPluginsByCapability(plugins, capability) {
|
|
9
5
|
return plugins.filter((plugin) => pluginHasCapability(plugin, capability));
|
|
10
6
|
}
|
package/dist/scm/client.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const github_plugin_js_1 = require("./github-plugin.js");
|
|
5
|
-
function getScmClient() {
|
|
6
|
-
return (0, github_plugin_js_1.createGitHubPlugin)();
|
|
1
|
+
import { createGitHubPlugin } from "./github-plugin.js";
|
|
2
|
+
export function getScmClient() {
|
|
3
|
+
return createGitHubPlugin();
|
|
7
4
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createGitHubPlugin = createGitHubPlugin;
|
|
4
|
-
const rest_1 = require("@octokit/rest");
|
|
1
|
+
import { Octokit } from "@octokit/rest";
|
|
5
2
|
function parseRepoSlug(input) {
|
|
6
3
|
const [owner, repo] = input.split("/");
|
|
7
4
|
if (!owner || !repo) {
|
|
@@ -86,7 +83,43 @@ async function ensureLabels(octokit, repo, pullNumber, labels, branchContext) {
|
|
|
86
83
|
throw new Error(`Failed applying labels to pull request #${pullNumber}: [${repoRef(repo)} base=${branchContext.baseBranch} head=${branchContext.headBranch}] ${message}`);
|
|
87
84
|
}
|
|
88
85
|
}
|
|
89
|
-
function
|
|
86
|
+
function groupReleasesByIssue(releases) {
|
|
87
|
+
const byIssue = new Map();
|
|
88
|
+
for (const release of releases) {
|
|
89
|
+
for (const reference of release.references) {
|
|
90
|
+
const bucket = byIssue.get(reference) ?? [];
|
|
91
|
+
if (!bucket.some((entry) => entry.tag === release.tag)) {
|
|
92
|
+
bucket.push(release);
|
|
93
|
+
}
|
|
94
|
+
byIssue.set(reference, bucket);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
for (const bucket of byIssue.values()) {
|
|
98
|
+
bucket.sort((a, b) => a.tag.localeCompare(b.tag));
|
|
99
|
+
}
|
|
100
|
+
return new Map([...byIssue.entries()].sort(([a], [b]) => a - b));
|
|
101
|
+
}
|
|
102
|
+
function renderReleaseLink(release) {
|
|
103
|
+
if (release.name) {
|
|
104
|
+
return `[\`${release.name}\` v${release.version}](${release.releaseUrl})`;
|
|
105
|
+
}
|
|
106
|
+
return `[version ${release.version}](${release.releaseUrl})`;
|
|
107
|
+
}
|
|
108
|
+
function renderReleaseReferenceCommentBody(releases) {
|
|
109
|
+
const footer = "Released by [Versionary](https://github.com/jolars/versionary).";
|
|
110
|
+
if (releases.length === 1) {
|
|
111
|
+
const release = releases[0];
|
|
112
|
+
if (!release) {
|
|
113
|
+
throw new Error("Expected at least one release for comment body.");
|
|
114
|
+
}
|
|
115
|
+
return `This is included in ${renderReleaseLink(release)}. :tada:\n\n${footer}`;
|
|
116
|
+
}
|
|
117
|
+
const bullets = releases
|
|
118
|
+
.map((release) => `- ${renderReleaseLink(release)}`)
|
|
119
|
+
.join("\n");
|
|
120
|
+
return `This is included in the following releases: :tada:\n\n${bullets}\n\n${footer}`;
|
|
121
|
+
}
|
|
122
|
+
export function createGitHubPlugin() {
|
|
90
123
|
return {
|
|
91
124
|
name: "github",
|
|
92
125
|
capabilities: [
|
|
@@ -97,7 +130,7 @@ function createGitHubPlugin() {
|
|
|
97
130
|
provider: "github",
|
|
98
131
|
async createOrUpdateReviewRequest(input, _context) {
|
|
99
132
|
const repo = getRepoFromEnv();
|
|
100
|
-
const octokit = new
|
|
133
|
+
const octokit = new Octokit({ auth: getGitHubToken() });
|
|
101
134
|
const listHead = resolveHeadForList(repo, input.headBranch);
|
|
102
135
|
let existing;
|
|
103
136
|
try {
|
|
@@ -176,7 +209,7 @@ function createGitHubPlugin() {
|
|
|
176
209
|
},
|
|
177
210
|
async closeReviewRequestIfExists(input, _context) {
|
|
178
211
|
const repo = getRepoFromEnv();
|
|
179
|
-
const octokit = new
|
|
212
|
+
const octokit = new Octokit({ auth: getGitHubToken() });
|
|
180
213
|
const listHead = resolveHeadForList(repo, input.headBranch);
|
|
181
214
|
let existing;
|
|
182
215
|
try {
|
|
@@ -238,7 +271,7 @@ function createGitHubPlugin() {
|
|
|
238
271
|
},
|
|
239
272
|
async createReleaseMetadata(input, _context) {
|
|
240
273
|
const repo = getRepoFromEnv();
|
|
241
|
-
const octokit = new
|
|
274
|
+
const octokit = new Octokit({ auth: getGitHubToken() });
|
|
242
275
|
try {
|
|
243
276
|
const existing = await octokit.repos.getReleaseByTag({
|
|
244
277
|
owner: repo.owner,
|
|
@@ -274,12 +307,12 @@ function createGitHubPlugin() {
|
|
|
274
307
|
},
|
|
275
308
|
async createReleaseReferenceComments(input, context) {
|
|
276
309
|
const repo = getRepoFromEnv();
|
|
277
|
-
const octokit = new
|
|
278
|
-
const uniqueReferences = [...new Set(input.references)].sort((a, b) => a - b);
|
|
279
|
-
const commented = [];
|
|
310
|
+
const octokit = new Octokit({ auth: getGitHubToken() });
|
|
280
311
|
const mode = input.mode ?? "best-effort";
|
|
281
|
-
|
|
282
|
-
|
|
312
|
+
const releasesByIssue = groupReleasesByIssue(input.releases);
|
|
313
|
+
const commented = [];
|
|
314
|
+
for (const [reference, releases] of releasesByIssue) {
|
|
315
|
+
const body = renderReleaseReferenceCommentBody(releases);
|
|
283
316
|
try {
|
|
284
317
|
await octokit.issues.createComment({
|
|
285
318
|
owner: repo.owner,
|
package/dist/scm/types.d.ts
CHANGED
|
@@ -41,10 +41,15 @@ export interface ScmReleaseMetadataResult {
|
|
|
41
41
|
url: string;
|
|
42
42
|
status?: "created" | "exists";
|
|
43
43
|
}
|
|
44
|
-
export interface
|
|
44
|
+
export interface ScmReleaseReferenceCommentsRelease {
|
|
45
|
+
name?: string;
|
|
46
|
+
tag: string;
|
|
45
47
|
version: string;
|
|
46
48
|
releaseUrl: string;
|
|
47
49
|
references: number[];
|
|
50
|
+
}
|
|
51
|
+
export interface ScmReleaseReferenceCommentsInput {
|
|
52
|
+
releases: ScmReleaseReferenceCommentsRelease[];
|
|
48
53
|
mode?: "best-effort" | "strict";
|
|
49
54
|
}
|
|
50
55
|
export interface ScmReleaseReferenceCommentsResult {
|
package/dist/scm/types.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.compositeVersionStrategy = compositeVersionStrategy;
|
|
4
1
|
function configForSecondary(config) {
|
|
5
2
|
if (config["version-file"] === undefined) {
|
|
6
3
|
return config;
|
|
@@ -11,7 +8,7 @@ function configForSecondary(config) {
|
|
|
11
8
|
function dedupedSorted(values) {
|
|
12
9
|
return [...new Set(values)].sort((a, b) => a.localeCompare(b));
|
|
13
10
|
}
|
|
14
|
-
function compositeVersionStrategy(strategies) {
|
|
11
|
+
export function compositeVersionStrategy(strategies) {
|
|
15
12
|
if (strategies.length === 0) {
|
|
16
13
|
throw new Error("compositeVersionStrategy requires at least one strategy.");
|
|
17
14
|
}
|