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/pr.js
CHANGED
|
@@ -1,31 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
exports.openOrUpdateReviewRequest = openOrUpdateReviewRequest;
|
|
13
|
-
exports.closeStaleReviewRequestIfExists = closeStaleReviewRequestIfExists;
|
|
14
|
-
exports.prepareSimpleReleasePr = prepareSimpleReleasePr;
|
|
15
|
-
exports.openOrUpdateSimpleReviewRequest = openOrUpdateSimpleReviewRequest;
|
|
16
|
-
exports.pushReleaseBranch = pushReleaseBranch;
|
|
17
|
-
exports.isReleaseCommitMessage = isReleaseCommitMessage;
|
|
18
|
-
const node_child_process_1 = require("node:child_process");
|
|
19
|
-
const node_fs_1 = __importDefault(require("node:fs"));
|
|
20
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
21
|
-
const load_config_js_1 = require("../config/load-config.js");
|
|
22
|
-
const identity_js_1 = require("../git/identity.js");
|
|
23
|
-
const client_js_1 = require("../scm/client.js");
|
|
24
|
-
const package_context_js_1 = require("../strategy/package-context.js");
|
|
25
|
-
const artifact_rules_js_1 = require("./artifact-rules.js");
|
|
26
|
-
const changelog_js_1 = require("./changelog.js");
|
|
27
|
-
const plan_js_1 = require("./plan.js");
|
|
28
|
-
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 { ensureGitIdentity } from "../git/identity.js";
|
|
6
|
+
import { getScmClient } from "../scm/client.js";
|
|
7
|
+
import { resolvePackageStrategyContext, resolveReleaseName, } from "../strategy/package-context.js";
|
|
8
|
+
import { applyConfiguredArtifactRules } from "./artifact-rules.js";
|
|
9
|
+
import { prependChangelog, renderReleaseNotesSection, renderReleasePlanChangelog, renderReviewRequestFooter, } from "./changelog.js";
|
|
10
|
+
import { createReleasePlan, getChangelogDefaults, resolvePackageDependencies, } from "./plan.js";
|
|
11
|
+
import { getBaselineStatePath, writeBaselineSha, } from "./state.js";
|
|
29
12
|
const SAFE_DIRTY_FILES = new Set([
|
|
30
13
|
"pnpm-lock.yaml",
|
|
31
14
|
"package-lock.json",
|
|
@@ -34,21 +17,21 @@ const SAFE_DIRTY_FILES = new Set([
|
|
|
34
17
|
"npm-shrinkwrap.json",
|
|
35
18
|
]);
|
|
36
19
|
const VERSIONARY_RELEASE_TRAILER = "Versionary-Release: true";
|
|
37
|
-
function getNextReleaseFile(config) {
|
|
20
|
+
export function getNextReleaseFile(config) {
|
|
38
21
|
return config["next-release-file"] ?? "NEXT_RELEASE.md";
|
|
39
22
|
}
|
|
40
|
-
function readNextReleaseHighlights(cwd, config) {
|
|
23
|
+
export function readNextReleaseHighlights(cwd, config) {
|
|
41
24
|
const filePath = getNextReleaseFile(config);
|
|
42
|
-
const fullPath =
|
|
43
|
-
if (!
|
|
25
|
+
const fullPath = path.join(cwd, filePath);
|
|
26
|
+
if (!fs.existsSync(fullPath)) {
|
|
44
27
|
return null;
|
|
45
28
|
}
|
|
46
|
-
const content =
|
|
29
|
+
const content = fs.readFileSync(fullPath, "utf8").trim();
|
|
47
30
|
return { content, filePath };
|
|
48
31
|
}
|
|
49
32
|
function isTrackedFile(cwd, filePath) {
|
|
50
33
|
try {
|
|
51
|
-
|
|
34
|
+
execFileSync("git", ["ls-files", "--error-unmatch", "--", filePath], {
|
|
52
35
|
cwd,
|
|
53
36
|
stdio: ["ignore", "pipe", "ignore"],
|
|
54
37
|
});
|
|
@@ -58,16 +41,16 @@ function isTrackedFile(cwd, filePath) {
|
|
|
58
41
|
return false;
|
|
59
42
|
}
|
|
60
43
|
}
|
|
61
|
-
function consumeNextReleaseFile(cwd, filePath) {
|
|
44
|
+
export function consumeNextReleaseFile(cwd, filePath) {
|
|
62
45
|
const tracked = isTrackedFile(cwd, filePath);
|
|
63
|
-
const fullPath =
|
|
64
|
-
if (
|
|
65
|
-
|
|
46
|
+
const fullPath = path.join(cwd, filePath);
|
|
47
|
+
if (fs.existsSync(fullPath)) {
|
|
48
|
+
fs.rmSync(fullPath);
|
|
66
49
|
}
|
|
67
50
|
return { tracked };
|
|
68
51
|
}
|
|
69
52
|
function listTrackedDirtyFiles(cwd) {
|
|
70
|
-
const status =
|
|
53
|
+
const status = execFileSync("git", ["status", "--porcelain", "--untracked-files=no"], {
|
|
71
54
|
cwd,
|
|
72
55
|
encoding: "utf8",
|
|
73
56
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -83,11 +66,11 @@ function listTrackedDirtyFiles(cwd) {
|
|
|
83
66
|
.map((filePath) => filePath.trim())
|
|
84
67
|
.filter((filePath) => filePath.length > 0);
|
|
85
68
|
}
|
|
86
|
-
function splitSafeDirtyFiles(files) {
|
|
69
|
+
export function splitSafeDirtyFiles(files) {
|
|
87
70
|
const ignored = [];
|
|
88
71
|
const blocking = [];
|
|
89
72
|
for (const file of files) {
|
|
90
|
-
const basename =
|
|
73
|
+
const basename = path.basename(file);
|
|
91
74
|
if (SAFE_DIRTY_FILES.has(basename)) {
|
|
92
75
|
ignored.push(file);
|
|
93
76
|
continue;
|
|
@@ -114,21 +97,21 @@ function normalizeReleaseNameForTag(releaseName) {
|
|
|
114
97
|
.replace(/\s+/gu, "-");
|
|
115
98
|
}
|
|
116
99
|
function getCommitTreeSha(cwd, revision) {
|
|
117
|
-
return
|
|
100
|
+
return execFileSync("git", ["rev-parse", `${revision}^{tree}`], {
|
|
118
101
|
cwd,
|
|
119
102
|
encoding: "utf8",
|
|
120
103
|
stdio: ["ignore", "pipe", "ignore"],
|
|
121
104
|
}).trim();
|
|
122
105
|
}
|
|
123
106
|
function resolveCommitDate(cwd, revision) {
|
|
124
|
-
return
|
|
107
|
+
return execFileSync("git", ["show", "-s", "--format=%cs", revision], {
|
|
125
108
|
cwd,
|
|
126
109
|
encoding: "utf8",
|
|
127
110
|
stdio: ["ignore", "pipe", "ignore"],
|
|
128
111
|
}).trim();
|
|
129
112
|
}
|
|
130
113
|
function hasOriginRemote(cwd) {
|
|
131
|
-
const remotes =
|
|
114
|
+
const remotes = execFileSync("git", ["remote"], {
|
|
132
115
|
cwd,
|
|
133
116
|
encoding: "utf8",
|
|
134
117
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -142,7 +125,7 @@ function remoteReleaseBranchExists(cwd, branch) {
|
|
|
142
125
|
if (!hasOriginRemote(cwd)) {
|
|
143
126
|
return false;
|
|
144
127
|
}
|
|
145
|
-
const output =
|
|
128
|
+
const output = execFileSync("git", ["ls-remote", "--heads", "origin", branch], {
|
|
146
129
|
cwd,
|
|
147
130
|
encoding: "utf8",
|
|
148
131
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -151,19 +134,12 @@ function remoteReleaseBranchExists(cwd, branch) {
|
|
|
151
134
|
}
|
|
152
135
|
function fetchRemoteReleaseBranch(cwd, branch) {
|
|
153
136
|
const remoteRef = `refs/remotes/origin/${branch}`;
|
|
154
|
-
|
|
137
|
+
execFileSync("git", ["fetch", "--no-tags", "origin", `refs/heads/${branch}:${remoteRef}`], {
|
|
155
138
|
cwd,
|
|
156
139
|
stdio: ["ignore", "pipe", "ignore"],
|
|
157
140
|
});
|
|
158
141
|
return remoteRef;
|
|
159
142
|
}
|
|
160
|
-
function resolveReleaseName(cwd, packagePath, packageConfig, strategy, strategyConfig) {
|
|
161
|
-
const configuredName = packageConfig["package-name"]?.trim();
|
|
162
|
-
if (configuredName) {
|
|
163
|
-
return configuredName;
|
|
164
|
-
}
|
|
165
|
-
return strategy.readPackageName?.(cwd, strategyConfig) ?? packagePath;
|
|
166
|
-
}
|
|
167
143
|
function buildReleaseTargets(cwd, plan, loadedConfig) {
|
|
168
144
|
const releaseTargets = plan.packages
|
|
169
145
|
? plan.packages
|
|
@@ -177,7 +153,7 @@ function buildReleaseTargets(cwd, plan, loadedConfig) {
|
|
|
177
153
|
};
|
|
178
154
|
}
|
|
179
155
|
const packageConfig = loadedConfig.packages?.[pkg.path] ?? {};
|
|
180
|
-
const packageContext =
|
|
156
|
+
const packageContext = resolvePackageStrategyContext(loadedConfig, pkg.path, packageConfig);
|
|
181
157
|
const releaseName = resolveReleaseName(cwd, pkg.path, packageConfig, packageContext.strategy, packageContext.config);
|
|
182
158
|
const tagPrefix = normalizeReleaseNameForTag(releaseName);
|
|
183
159
|
return {
|
|
@@ -210,7 +186,7 @@ function buildPackageReleaseMetadata(cwd, plan, loadedConfig) {
|
|
|
210
186
|
continue;
|
|
211
187
|
}
|
|
212
188
|
const packageConfig = loadedConfig.packages?.[pkg.path] ?? {};
|
|
213
|
-
const packageContext =
|
|
189
|
+
const packageContext = resolvePackageStrategyContext(loadedConfig, pkg.path, packageConfig);
|
|
214
190
|
const releaseName = resolveReleaseName(cwd, pkg.path, packageConfig, packageContext.strategy, packageContext.config);
|
|
215
191
|
metadataByPath[pkg.path] = {
|
|
216
192
|
releaseName,
|
|
@@ -229,14 +205,14 @@ function formatReleaseCommitTitle(releaseTargets) {
|
|
|
229
205
|
}
|
|
230
206
|
return `chore(release): ${tags[0]} (+${tags.length - 1} more)`;
|
|
231
207
|
}
|
|
232
|
-
function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
233
|
-
const plan =
|
|
234
|
-
const loaded =
|
|
208
|
+
export function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
209
|
+
const plan = createReleasePlan(cwd);
|
|
210
|
+
const loaded = loadConfig(cwd);
|
|
235
211
|
if (!plan.nextVersion) {
|
|
236
212
|
throw new Error("No releasable commits found. Nothing to open a release PR for.");
|
|
237
213
|
}
|
|
238
214
|
ensureCleanWorktree(cwd, options.logger);
|
|
239
|
-
const releaseBaselineSha =
|
|
215
|
+
const releaseBaselineSha = execFileSync("git", ["rev-parse", "HEAD"], {
|
|
240
216
|
cwd,
|
|
241
217
|
encoding: "utf8",
|
|
242
218
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -274,7 +250,7 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
274
250
|
continue;
|
|
275
251
|
}
|
|
276
252
|
const packageConfig = loaded.config.packages?.[packagePlan.path] ?? {};
|
|
277
|
-
const packageContext =
|
|
253
|
+
const packageContext = resolvePackageStrategyContext(loaded.config, packagePlan.path, packageConfig);
|
|
278
254
|
const packageUpdated = packageContext.strategy.writeVersion(cwd, packageContext.config, packagePlan.nextVersion);
|
|
279
255
|
updatedVersionFiles.push(...packageUpdated);
|
|
280
256
|
addStrategyWrite(packageContext.strategy, {
|
|
@@ -286,12 +262,12 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
286
262
|
for (const strategyGroup of writesByStrategy.values()) {
|
|
287
263
|
updatedVersionFiles.push(...(strategyGroup.strategy.finalizeVersionWrites?.(cwd, strategyGroup.writes, finalizeContext) ?? []));
|
|
288
264
|
}
|
|
289
|
-
const updatedArtifactFiles =
|
|
265
|
+
const updatedArtifactFiles = applyConfiguredArtifactRules(cwd, loaded.config, plan);
|
|
290
266
|
const packageReleaseMetadata = buildPackageReleaseMetadata(cwd, plan, loaded.config);
|
|
291
267
|
const nextReleaseRead = readNextReleaseHighlights(cwd, loaded.config);
|
|
292
268
|
const highlights = nextReleaseRead?.content ?? "";
|
|
293
|
-
const section =
|
|
294
|
-
|
|
269
|
+
const section = renderReleasePlanChangelog(plan, { highlights, cwd });
|
|
270
|
+
prependChangelog(cwd, plan.changelogFile, section, plan.changelogFormat);
|
|
295
271
|
const updatedChangelogFiles = [plan.changelogFile];
|
|
296
272
|
let consumedHighlightsPath = null;
|
|
297
273
|
if (nextReleaseRead) {
|
|
@@ -305,8 +281,8 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
305
281
|
continue;
|
|
306
282
|
}
|
|
307
283
|
const packageConfig = loaded.config.packages?.[packagePlan.path] ?? {};
|
|
308
|
-
const packageContext =
|
|
309
|
-
const { changelogFile: packageChangelogFile } =
|
|
284
|
+
const packageContext = resolvePackageStrategyContext(loaded.config, packagePlan.path, packageConfig);
|
|
285
|
+
const { changelogFile: packageChangelogFile } = getChangelogDefaults({
|
|
310
286
|
"release-type": packageConfig["release-type"] ?? loaded.config["release-type"],
|
|
311
287
|
"changelog-file": packageConfig["changelog-file"] ?? loaded.config["changelog-file"],
|
|
312
288
|
"changelog-format": packageConfig["changelog-format"] ?? loaded.config["changelog-format"],
|
|
@@ -316,16 +292,16 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
316
292
|
if (!packageMetadata) {
|
|
317
293
|
continue;
|
|
318
294
|
}
|
|
319
|
-
const packageSection =
|
|
295
|
+
const packageSection = renderReleaseNotesSection({
|
|
320
296
|
currentVersion: packagePlan.currentVersion,
|
|
321
297
|
nextVersion: packagePlan.nextVersion,
|
|
322
298
|
commits: packagePlan.commits,
|
|
323
299
|
tagPrefix: packageMetadata.tagPrefix,
|
|
324
300
|
cwd,
|
|
325
|
-
dependencies:
|
|
301
|
+
dependencies: resolvePackageDependencies(plan, packagePlan.path),
|
|
326
302
|
});
|
|
327
|
-
|
|
328
|
-
updatedChangelogFiles.push(
|
|
303
|
+
prependChangelog(cwd, path.posix.join(packagePlan.path, packageChangelogFile), packageSection, "markdown-changelog");
|
|
304
|
+
updatedChangelogFiles.push(path.posix.join(packagePlan.path, packageChangelogFile));
|
|
329
305
|
}
|
|
330
306
|
const releaseTargets = buildReleaseTargets(cwd, plan, loaded.config);
|
|
331
307
|
const branch = plan.releaseBranchPrefix;
|
|
@@ -334,7 +310,7 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
334
310
|
const remoteReleaseRef = hasRemoteReleaseBranch
|
|
335
311
|
? fetchRemoteReleaseBranch(cwd, branch)
|
|
336
312
|
: null;
|
|
337
|
-
|
|
313
|
+
execFileSync("git", ["checkout", "-B", branch], {
|
|
338
314
|
cwd,
|
|
339
315
|
stdio: ["ignore", "pipe", "ignore"],
|
|
340
316
|
});
|
|
@@ -346,21 +322,21 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
346
322
|
...(consumedHighlightsPath ? [consumedHighlightsPath] : []),
|
|
347
323
|
]),
|
|
348
324
|
];
|
|
349
|
-
|
|
325
|
+
execFileSync("git", ["add", ...filesToAdd], {
|
|
350
326
|
cwd,
|
|
351
327
|
stdio: ["ignore", "pipe", "ignore"],
|
|
352
328
|
});
|
|
353
|
-
|
|
354
|
-
|
|
329
|
+
ensureGitIdentity(cwd);
|
|
330
|
+
execFileSync("git", ["commit", "-m", title, "-m", VERSIONARY_RELEASE_TRAILER], {
|
|
355
331
|
cwd,
|
|
356
332
|
stdio: ["ignore", "pipe", "ignore"],
|
|
357
333
|
});
|
|
358
|
-
|
|
359
|
-
|
|
334
|
+
writeBaselineSha(cwd, releaseBaselineSha, releaseTargets);
|
|
335
|
+
execFileSync("git", ["add", getBaselineStatePath(cwd)], {
|
|
360
336
|
cwd,
|
|
361
337
|
stdio: ["ignore", "pipe", "ignore"],
|
|
362
338
|
});
|
|
363
|
-
|
|
339
|
+
execFileSync("git", ["commit", "--amend", "--no-edit"], {
|
|
364
340
|
cwd,
|
|
365
341
|
stdio: ["ignore", "pipe", "ignore"],
|
|
366
342
|
});
|
|
@@ -377,8 +353,8 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
377
353
|
highlights,
|
|
378
354
|
};
|
|
379
355
|
}
|
|
380
|
-
function renderSimpleReviewRequestBody(version, previousVersion, commits, plan = null, cwd = process.cwd(), highlights = "", loadedConfig) {
|
|
381
|
-
const rootPackageLabel =
|
|
356
|
+
export function renderSimpleReviewRequestBody(version, previousVersion, commits, plan = null, cwd = process.cwd(), highlights = "", loadedConfig) {
|
|
357
|
+
const rootPackageLabel = path.basename(cwd);
|
|
382
358
|
const formatPackageLabel = (packagePath) => packagePath === "." ? rootPackageLabel : packagePath;
|
|
383
359
|
const resolveTagPrefix = (packagePath) => {
|
|
384
360
|
if (packagePath === ".") {
|
|
@@ -388,7 +364,7 @@ function renderSimpleReviewRequestBody(version, previousVersion, commits, plan =
|
|
|
388
364
|
return normalizeReleaseNameForTag(packagePath);
|
|
389
365
|
}
|
|
390
366
|
const packageConfig = loadedConfig.packages?.[packagePath] ?? {};
|
|
391
|
-
const packageContext =
|
|
367
|
+
const packageContext = resolvePackageStrategyContext(loadedConfig, packagePath, packageConfig);
|
|
392
368
|
const releaseName = resolveReleaseName(cwd, packagePath, packageConfig, packageContext.strategy, packageContext.config);
|
|
393
369
|
return normalizeReleaseNameForTag(releaseName);
|
|
394
370
|
};
|
|
@@ -396,7 +372,7 @@ function renderSimpleReviewRequestBody(version, previousVersion, commits, plan =
|
|
|
396
372
|
const sections = [];
|
|
397
373
|
const rootPackage = plan.packages.find((pkg) => pkg.path === "." && pkg.nextVersion);
|
|
398
374
|
if (rootPackage?.nextVersion) {
|
|
399
|
-
const rootNotes =
|
|
375
|
+
const rootNotes = renderReleasePlanChangelog(plan, {
|
|
400
376
|
headerLabel: `${formatPackageLabel(".")}: ${rootPackage.nextVersion}`,
|
|
401
377
|
cwd,
|
|
402
378
|
highlights,
|
|
@@ -405,23 +381,23 @@ function renderSimpleReviewRequestBody(version, previousVersion, commits, plan =
|
|
|
405
381
|
}
|
|
406
382
|
const packageSections = plan.packages
|
|
407
383
|
.filter((pkg) => pkg.path !== "." && pkg.nextVersion)
|
|
408
|
-
.map((pkg) =>
|
|
384
|
+
.map((pkg) => renderReleaseNotesSection({
|
|
409
385
|
currentVersion: pkg.currentVersion,
|
|
410
386
|
nextVersion: pkg.nextVersion ?? "",
|
|
411
387
|
commits: pkg.commits,
|
|
412
388
|
cwd,
|
|
413
|
-
dependencies:
|
|
389
|
+
dependencies: resolvePackageDependencies(plan, pkg.path),
|
|
414
390
|
tagPrefix: resolveTagPrefix(pkg.path),
|
|
415
391
|
headerLabel: `${formatPackageLabel(pkg.path)}: ${pkg.nextVersion ?? ""}`,
|
|
416
392
|
}));
|
|
417
393
|
sections.push(...packageSections);
|
|
418
394
|
const bodySections = sections.join("\n\n");
|
|
419
395
|
if (bodySections.length === 0) {
|
|
420
|
-
return
|
|
396
|
+
return renderReviewRequestFooter();
|
|
421
397
|
}
|
|
422
|
-
return `${bodySections}\n\n${
|
|
398
|
+
return `${bodySections}\n\n${renderReviewRequestFooter()}`;
|
|
423
399
|
}
|
|
424
|
-
return
|
|
400
|
+
return renderReleaseNotesSection({
|
|
425
401
|
currentVersion: previousVersion,
|
|
426
402
|
nextVersion: version,
|
|
427
403
|
commits,
|
|
@@ -429,13 +405,13 @@ function renderSimpleReviewRequestBody(version, previousVersion, commits, plan =
|
|
|
429
405
|
highlights,
|
|
430
406
|
}, { includeFooter: true });
|
|
431
407
|
}
|
|
432
|
-
async function openOrUpdateReviewRequest(cwd, branch, title, version, previousVersion, commits, plan = null, options = {}) {
|
|
433
|
-
const loaded =
|
|
408
|
+
export async function openOrUpdateReviewRequest(cwd, branch, title, version, previousVersion, commits, plan = null, options = {}) {
|
|
409
|
+
const loaded = loadConfig(cwd);
|
|
434
410
|
const releaseFlow = loaded.config["review-mode"] ?? "pr";
|
|
435
411
|
if (releaseFlow === "direct") {
|
|
436
412
|
return "Release flow mode is direct; skipping review request creation.";
|
|
437
413
|
}
|
|
438
|
-
const scmClient =
|
|
414
|
+
const scmClient = getScmClient();
|
|
439
415
|
const result = await scmClient.createOrUpdateReviewRequest({
|
|
440
416
|
baseBranch: process.env.VERSIONARY_BASE_BRANCH ?? "main",
|
|
441
417
|
headBranch: branch,
|
|
@@ -455,12 +431,12 @@ function hasScmRuntimeContext() {
|
|
|
455
431
|
process.env.GITHUB_TOKEN);
|
|
456
432
|
return hasRepository && hasToken;
|
|
457
433
|
}
|
|
458
|
-
async function closeStaleReviewRequestIfExists(cwd = process.cwd(), options = {}) {
|
|
434
|
+
export async function closeStaleReviewRequestIfExists(cwd = process.cwd(), options = {}) {
|
|
459
435
|
if (!hasScmRuntimeContext()) {
|
|
460
436
|
return { closed: false };
|
|
461
437
|
}
|
|
462
|
-
const plan =
|
|
463
|
-
const scmClient =
|
|
438
|
+
const plan = createReleasePlan(cwd);
|
|
439
|
+
const scmClient = getScmClient();
|
|
464
440
|
const result = await scmClient.closeReviewRequestIfExists({
|
|
465
441
|
baseBranch: process.env.VERSIONARY_BASE_BRANCH ?? "main",
|
|
466
442
|
headBranch: plan.releaseBranchPrefix,
|
|
@@ -475,20 +451,20 @@ async function closeStaleReviewRequestIfExists(cwd = process.cwd(), options = {}
|
|
|
475
451
|
return result;
|
|
476
452
|
}
|
|
477
453
|
/** @deprecated Use prepareReleasePr. */
|
|
478
|
-
function prepareSimpleReleasePr(cwd = process.cwd(), options = {}) {
|
|
454
|
+
export function prepareSimpleReleasePr(cwd = process.cwd(), options = {}) {
|
|
479
455
|
return prepareReleasePr(cwd, options);
|
|
480
456
|
}
|
|
481
457
|
/** @deprecated Use openOrUpdateReviewRequest. */
|
|
482
|
-
async function openOrUpdateSimpleReviewRequest(cwd, branch, title, version, previousVersion, commits, plan = null, options = {}) {
|
|
458
|
+
export async function openOrUpdateSimpleReviewRequest(cwd, branch, title, version, previousVersion, commits, plan = null, options = {}) {
|
|
483
459
|
return openOrUpdateReviewRequest(cwd, branch, title, version, previousVersion, commits, plan, options);
|
|
484
460
|
}
|
|
485
|
-
function pushReleaseBranch(cwd, branch) {
|
|
486
|
-
|
|
461
|
+
export function pushReleaseBranch(cwd, branch) {
|
|
462
|
+
execFileSync("git", ["push", "--force-with-lease", "origin", branch], {
|
|
487
463
|
cwd,
|
|
488
464
|
stdio: ["ignore", "pipe", "ignore"],
|
|
489
465
|
});
|
|
490
466
|
}
|
|
491
|
-
function isReleaseCommitMessage(commitMessage) {
|
|
467
|
+
export function isReleaseCommitMessage(commitMessage) {
|
|
492
468
|
if (/^Versionary-Release:\s*true$/imu.test(commitMessage)) {
|
|
493
469
|
return true;
|
|
494
470
|
}
|
package/dist/release/recovery.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.executeIdempotentReleaseTarget = executeIdempotentReleaseTarget;
|
|
4
|
-
const node_child_process_1 = require("node:child_process");
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
5
2
|
function hasRemoteTag(cwd, tag) {
|
|
6
3
|
try {
|
|
7
|
-
const output =
|
|
4
|
+
const output = execFileSync("git", ["ls-remote", "--tags", "origin", `refs/tags/${tag}`], {
|
|
8
5
|
cwd,
|
|
9
6
|
encoding: "utf8",
|
|
10
7
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -17,7 +14,7 @@ function hasRemoteTag(cwd, tag) {
|
|
|
17
14
|
}
|
|
18
15
|
function readRemoteTagSha(cwd, tag) {
|
|
19
16
|
try {
|
|
20
|
-
const output =
|
|
17
|
+
const output = execFileSync("git", ["ls-remote", "--tags", "origin", `refs/tags/${tag}`], {
|
|
21
18
|
cwd,
|
|
22
19
|
encoding: "utf8",
|
|
23
20
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -33,13 +30,13 @@ function readRemoteTagSha(cwd, tag) {
|
|
|
33
30
|
}
|
|
34
31
|
}
|
|
35
32
|
function createTagWithRecovery(cwd, tag) {
|
|
36
|
-
const localTag =
|
|
33
|
+
const localTag = execFileSync("git", ["tag", "--list", tag], {
|
|
37
34
|
cwd,
|
|
38
35
|
encoding: "utf8",
|
|
39
36
|
stdio: ["ignore", "pipe", "ignore"],
|
|
40
37
|
}).trim();
|
|
41
38
|
if (localTag.length > 0) {
|
|
42
|
-
const localSha =
|
|
39
|
+
const localSha = execFileSync("git", ["rev-parse", `refs/tags/${tag}`], {
|
|
43
40
|
cwd,
|
|
44
41
|
encoding: "utf8",
|
|
45
42
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -51,7 +48,7 @@ function createTagWithRecovery(cwd, tag) {
|
|
|
51
48
|
return "exists";
|
|
52
49
|
}
|
|
53
50
|
try {
|
|
54
|
-
|
|
51
|
+
execFileSync("git", ["tag", tag], {
|
|
55
52
|
cwd,
|
|
56
53
|
stdio: ["ignore", "pipe", "ignore"],
|
|
57
54
|
});
|
|
@@ -60,7 +57,7 @@ function createTagWithRecovery(cwd, tag) {
|
|
|
60
57
|
throw new Error(`Failed creating local tag "${tag}". Ensure repository is writable and retry.`);
|
|
61
58
|
}
|
|
62
59
|
try {
|
|
63
|
-
|
|
60
|
+
execFileSync("git", ["push", "origin", tag], {
|
|
64
61
|
cwd,
|
|
65
62
|
stdio: ["ignore", "pipe", "ignore"],
|
|
66
63
|
});
|
|
@@ -68,7 +65,7 @@ function createTagWithRecovery(cwd, tag) {
|
|
|
68
65
|
}
|
|
69
66
|
catch {
|
|
70
67
|
if (hasRemoteTag(cwd, tag)) {
|
|
71
|
-
const localSha =
|
|
68
|
+
const localSha = execFileSync("git", ["rev-parse", `refs/tags/${tag}`], {
|
|
72
69
|
cwd,
|
|
73
70
|
encoding: "utf8",
|
|
74
71
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -82,7 +79,7 @@ function createTagWithRecovery(cwd, tag) {
|
|
|
82
79
|
throw new Error(`Failed pushing tag "${tag}" to origin. Check push permissions and remote connectivity, then retry.`);
|
|
83
80
|
}
|
|
84
81
|
}
|
|
85
|
-
async function executeIdempotentReleaseTarget(cwd, target, context) {
|
|
82
|
+
export async function executeIdempotentReleaseTarget(cwd, target, context) {
|
|
86
83
|
const tagStatus = createTagWithRecovery(cwd, target.tag);
|
|
87
84
|
const metadata = await context.createReleaseMetadata(target);
|
|
88
85
|
const metadataStatus = metadata.status ?? "created";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { VersionaryConfig } from "../types/config.js";
|
|
2
2
|
import type { VersionaryPluginContext } from "../types/plugins.js";
|
|
3
|
+
export declare function resolveTargetPackageName(cwd: string, config: VersionaryConfig, targetPath: string): string | undefined;
|
|
3
4
|
export declare function extractReleaseNotes(content: string, version: string, changelogFormat: "markdown-changelog" | "r-news"): string;
|
|
4
5
|
export declare function extractClosingReferencesFromNotes(notes: string): number[];
|
|
5
6
|
export declare function resolveTargetChangelogFile(config: VersionaryConfig, rootChangelogFile: string, targetPath: string): string;
|