versionary 0.28.0 → 0.28.2
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 +23 -34
- package/dist/release/plan.js +34 -43
- package/dist/release/pr.js +75 -92
- package/dist/release/recovery.js +9 -12
- package/dist/release/release.js +37 -50
- 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 +6 -9
- 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.js +8 -15
- 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,7 +134,7 @@ 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
|
});
|
|
@@ -170,8 +153,8 @@ function buildReleaseTargets(cwd, plan, loadedConfig) {
|
|
|
170
153
|
};
|
|
171
154
|
}
|
|
172
155
|
const packageConfig = loadedConfig.packages?.[pkg.path] ?? {};
|
|
173
|
-
const packageContext =
|
|
174
|
-
const releaseName =
|
|
156
|
+
const packageContext = resolvePackageStrategyContext(loadedConfig, pkg.path, packageConfig);
|
|
157
|
+
const releaseName = resolveReleaseName(cwd, pkg.path, packageConfig, packageContext.strategy, packageContext.config);
|
|
175
158
|
const tagPrefix = normalizeReleaseNameForTag(releaseName);
|
|
176
159
|
return {
|
|
177
160
|
path: pkg.path,
|
|
@@ -203,8 +186,8 @@ function buildPackageReleaseMetadata(cwd, plan, loadedConfig) {
|
|
|
203
186
|
continue;
|
|
204
187
|
}
|
|
205
188
|
const packageConfig = loadedConfig.packages?.[pkg.path] ?? {};
|
|
206
|
-
const packageContext =
|
|
207
|
-
const releaseName =
|
|
189
|
+
const packageContext = resolvePackageStrategyContext(loadedConfig, pkg.path, packageConfig);
|
|
190
|
+
const releaseName = resolveReleaseName(cwd, pkg.path, packageConfig, packageContext.strategy, packageContext.config);
|
|
208
191
|
metadataByPath[pkg.path] = {
|
|
209
192
|
releaseName,
|
|
210
193
|
tagPrefix: normalizeReleaseNameForTag(releaseName),
|
|
@@ -222,14 +205,14 @@ function formatReleaseCommitTitle(releaseTargets) {
|
|
|
222
205
|
}
|
|
223
206
|
return `chore(release): ${tags[0]} (+${tags.length - 1} more)`;
|
|
224
207
|
}
|
|
225
|
-
function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
226
|
-
const plan =
|
|
227
|
-
const loaded =
|
|
208
|
+
export function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
209
|
+
const plan = createReleasePlan(cwd);
|
|
210
|
+
const loaded = loadConfig(cwd);
|
|
228
211
|
if (!plan.nextVersion) {
|
|
229
212
|
throw new Error("No releasable commits found. Nothing to open a release PR for.");
|
|
230
213
|
}
|
|
231
214
|
ensureCleanWorktree(cwd, options.logger);
|
|
232
|
-
const releaseBaselineSha =
|
|
215
|
+
const releaseBaselineSha = execFileSync("git", ["rev-parse", "HEAD"], {
|
|
233
216
|
cwd,
|
|
234
217
|
encoding: "utf8",
|
|
235
218
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -267,7 +250,7 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
267
250
|
continue;
|
|
268
251
|
}
|
|
269
252
|
const packageConfig = loaded.config.packages?.[packagePlan.path] ?? {};
|
|
270
|
-
const packageContext =
|
|
253
|
+
const packageContext = resolvePackageStrategyContext(loaded.config, packagePlan.path, packageConfig);
|
|
271
254
|
const packageUpdated = packageContext.strategy.writeVersion(cwd, packageContext.config, packagePlan.nextVersion);
|
|
272
255
|
updatedVersionFiles.push(...packageUpdated);
|
|
273
256
|
addStrategyWrite(packageContext.strategy, {
|
|
@@ -279,12 +262,12 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
279
262
|
for (const strategyGroup of writesByStrategy.values()) {
|
|
280
263
|
updatedVersionFiles.push(...(strategyGroup.strategy.finalizeVersionWrites?.(cwd, strategyGroup.writes, finalizeContext) ?? []));
|
|
281
264
|
}
|
|
282
|
-
const updatedArtifactFiles =
|
|
265
|
+
const updatedArtifactFiles = applyConfiguredArtifactRules(cwd, loaded.config, plan);
|
|
283
266
|
const packageReleaseMetadata = buildPackageReleaseMetadata(cwd, plan, loaded.config);
|
|
284
267
|
const nextReleaseRead = readNextReleaseHighlights(cwd, loaded.config);
|
|
285
268
|
const highlights = nextReleaseRead?.content ?? "";
|
|
286
|
-
const section =
|
|
287
|
-
|
|
269
|
+
const section = renderReleasePlanChangelog(plan, { highlights, cwd });
|
|
270
|
+
prependChangelog(cwd, plan.changelogFile, section, plan.changelogFormat);
|
|
288
271
|
const updatedChangelogFiles = [plan.changelogFile];
|
|
289
272
|
let consumedHighlightsPath = null;
|
|
290
273
|
if (nextReleaseRead) {
|
|
@@ -298,8 +281,8 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
298
281
|
continue;
|
|
299
282
|
}
|
|
300
283
|
const packageConfig = loaded.config.packages?.[packagePlan.path] ?? {};
|
|
301
|
-
const packageContext =
|
|
302
|
-
const { changelogFile: packageChangelogFile } =
|
|
284
|
+
const packageContext = resolvePackageStrategyContext(loaded.config, packagePlan.path, packageConfig);
|
|
285
|
+
const { changelogFile: packageChangelogFile } = getChangelogDefaults({
|
|
303
286
|
"release-type": packageConfig["release-type"] ?? loaded.config["release-type"],
|
|
304
287
|
"changelog-file": packageConfig["changelog-file"] ?? loaded.config["changelog-file"],
|
|
305
288
|
"changelog-format": packageConfig["changelog-format"] ?? loaded.config["changelog-format"],
|
|
@@ -309,16 +292,16 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
309
292
|
if (!packageMetadata) {
|
|
310
293
|
continue;
|
|
311
294
|
}
|
|
312
|
-
const packageSection =
|
|
295
|
+
const packageSection = renderReleaseNotesSection({
|
|
313
296
|
currentVersion: packagePlan.currentVersion,
|
|
314
297
|
nextVersion: packagePlan.nextVersion,
|
|
315
298
|
commits: packagePlan.commits,
|
|
316
299
|
tagPrefix: packageMetadata.tagPrefix,
|
|
317
300
|
cwd,
|
|
318
|
-
dependencies:
|
|
301
|
+
dependencies: resolvePackageDependencies(plan, packagePlan.path),
|
|
319
302
|
});
|
|
320
|
-
|
|
321
|
-
updatedChangelogFiles.push(
|
|
303
|
+
prependChangelog(cwd, path.posix.join(packagePlan.path, packageChangelogFile), packageSection, "markdown-changelog");
|
|
304
|
+
updatedChangelogFiles.push(path.posix.join(packagePlan.path, packageChangelogFile));
|
|
322
305
|
}
|
|
323
306
|
const releaseTargets = buildReleaseTargets(cwd, plan, loaded.config);
|
|
324
307
|
const branch = plan.releaseBranchPrefix;
|
|
@@ -327,7 +310,7 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
327
310
|
const remoteReleaseRef = hasRemoteReleaseBranch
|
|
328
311
|
? fetchRemoteReleaseBranch(cwd, branch)
|
|
329
312
|
: null;
|
|
330
|
-
|
|
313
|
+
execFileSync("git", ["checkout", "-B", branch], {
|
|
331
314
|
cwd,
|
|
332
315
|
stdio: ["ignore", "pipe", "ignore"],
|
|
333
316
|
});
|
|
@@ -339,21 +322,21 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
339
322
|
...(consumedHighlightsPath ? [consumedHighlightsPath] : []),
|
|
340
323
|
]),
|
|
341
324
|
];
|
|
342
|
-
|
|
325
|
+
execFileSync("git", ["add", ...filesToAdd], {
|
|
343
326
|
cwd,
|
|
344
327
|
stdio: ["ignore", "pipe", "ignore"],
|
|
345
328
|
});
|
|
346
|
-
|
|
347
|
-
|
|
329
|
+
ensureGitIdentity(cwd);
|
|
330
|
+
execFileSync("git", ["commit", "-m", title, "-m", VERSIONARY_RELEASE_TRAILER], {
|
|
348
331
|
cwd,
|
|
349
332
|
stdio: ["ignore", "pipe", "ignore"],
|
|
350
333
|
});
|
|
351
|
-
|
|
352
|
-
|
|
334
|
+
writeBaselineSha(cwd, releaseBaselineSha, releaseTargets);
|
|
335
|
+
execFileSync("git", ["add", getBaselineStatePath(cwd)], {
|
|
353
336
|
cwd,
|
|
354
337
|
stdio: ["ignore", "pipe", "ignore"],
|
|
355
338
|
});
|
|
356
|
-
|
|
339
|
+
execFileSync("git", ["commit", "--amend", "--no-edit"], {
|
|
357
340
|
cwd,
|
|
358
341
|
stdio: ["ignore", "pipe", "ignore"],
|
|
359
342
|
});
|
|
@@ -370,8 +353,8 @@ function prepareReleasePr(cwd = process.cwd(), options = {}) {
|
|
|
370
353
|
highlights,
|
|
371
354
|
};
|
|
372
355
|
}
|
|
373
|
-
function renderSimpleReviewRequestBody(version, previousVersion, commits, plan = null, cwd = process.cwd(), highlights = "", loadedConfig) {
|
|
374
|
-
const rootPackageLabel =
|
|
356
|
+
export function renderSimpleReviewRequestBody(version, previousVersion, commits, plan = null, cwd = process.cwd(), highlights = "", loadedConfig) {
|
|
357
|
+
const rootPackageLabel = path.basename(cwd);
|
|
375
358
|
const formatPackageLabel = (packagePath) => packagePath === "." ? rootPackageLabel : packagePath;
|
|
376
359
|
const resolveTagPrefix = (packagePath) => {
|
|
377
360
|
if (packagePath === ".") {
|
|
@@ -381,15 +364,15 @@ function renderSimpleReviewRequestBody(version, previousVersion, commits, plan =
|
|
|
381
364
|
return normalizeReleaseNameForTag(packagePath);
|
|
382
365
|
}
|
|
383
366
|
const packageConfig = loadedConfig.packages?.[packagePath] ?? {};
|
|
384
|
-
const packageContext =
|
|
385
|
-
const releaseName =
|
|
367
|
+
const packageContext = resolvePackageStrategyContext(loadedConfig, packagePath, packageConfig);
|
|
368
|
+
const releaseName = resolveReleaseName(cwd, packagePath, packageConfig, packageContext.strategy, packageContext.config);
|
|
386
369
|
return normalizeReleaseNameForTag(releaseName);
|
|
387
370
|
};
|
|
388
371
|
if (plan?.packages && plan.packages.length > 1) {
|
|
389
372
|
const sections = [];
|
|
390
373
|
const rootPackage = plan.packages.find((pkg) => pkg.path === "." && pkg.nextVersion);
|
|
391
374
|
if (rootPackage?.nextVersion) {
|
|
392
|
-
const rootNotes =
|
|
375
|
+
const rootNotes = renderReleasePlanChangelog(plan, {
|
|
393
376
|
headerLabel: `${formatPackageLabel(".")}: ${rootPackage.nextVersion}`,
|
|
394
377
|
cwd,
|
|
395
378
|
highlights,
|
|
@@ -398,23 +381,23 @@ function renderSimpleReviewRequestBody(version, previousVersion, commits, plan =
|
|
|
398
381
|
}
|
|
399
382
|
const packageSections = plan.packages
|
|
400
383
|
.filter((pkg) => pkg.path !== "." && pkg.nextVersion)
|
|
401
|
-
.map((pkg) =>
|
|
384
|
+
.map((pkg) => renderReleaseNotesSection({
|
|
402
385
|
currentVersion: pkg.currentVersion,
|
|
403
386
|
nextVersion: pkg.nextVersion ?? "",
|
|
404
387
|
commits: pkg.commits,
|
|
405
388
|
cwd,
|
|
406
|
-
dependencies:
|
|
389
|
+
dependencies: resolvePackageDependencies(plan, pkg.path),
|
|
407
390
|
tagPrefix: resolveTagPrefix(pkg.path),
|
|
408
391
|
headerLabel: `${formatPackageLabel(pkg.path)}: ${pkg.nextVersion ?? ""}`,
|
|
409
392
|
}));
|
|
410
393
|
sections.push(...packageSections);
|
|
411
394
|
const bodySections = sections.join("\n\n");
|
|
412
395
|
if (bodySections.length === 0) {
|
|
413
|
-
return
|
|
396
|
+
return renderReviewRequestFooter();
|
|
414
397
|
}
|
|
415
|
-
return `${bodySections}\n\n${
|
|
398
|
+
return `${bodySections}\n\n${renderReviewRequestFooter()}`;
|
|
416
399
|
}
|
|
417
|
-
return
|
|
400
|
+
return renderReleaseNotesSection({
|
|
418
401
|
currentVersion: previousVersion,
|
|
419
402
|
nextVersion: version,
|
|
420
403
|
commits,
|
|
@@ -422,13 +405,13 @@ function renderSimpleReviewRequestBody(version, previousVersion, commits, plan =
|
|
|
422
405
|
highlights,
|
|
423
406
|
}, { includeFooter: true });
|
|
424
407
|
}
|
|
425
|
-
async function openOrUpdateReviewRequest(cwd, branch, title, version, previousVersion, commits, plan = null, options = {}) {
|
|
426
|
-
const loaded =
|
|
408
|
+
export async function openOrUpdateReviewRequest(cwd, branch, title, version, previousVersion, commits, plan = null, options = {}) {
|
|
409
|
+
const loaded = loadConfig(cwd);
|
|
427
410
|
const releaseFlow = loaded.config["review-mode"] ?? "pr";
|
|
428
411
|
if (releaseFlow === "direct") {
|
|
429
412
|
return "Release flow mode is direct; skipping review request creation.";
|
|
430
413
|
}
|
|
431
|
-
const scmClient =
|
|
414
|
+
const scmClient = getScmClient();
|
|
432
415
|
const result = await scmClient.createOrUpdateReviewRequest({
|
|
433
416
|
baseBranch: process.env.VERSIONARY_BASE_BRANCH ?? "main",
|
|
434
417
|
headBranch: branch,
|
|
@@ -448,12 +431,12 @@ function hasScmRuntimeContext() {
|
|
|
448
431
|
process.env.GITHUB_TOKEN);
|
|
449
432
|
return hasRepository && hasToken;
|
|
450
433
|
}
|
|
451
|
-
async function closeStaleReviewRequestIfExists(cwd = process.cwd(), options = {}) {
|
|
434
|
+
export async function closeStaleReviewRequestIfExists(cwd = process.cwd(), options = {}) {
|
|
452
435
|
if (!hasScmRuntimeContext()) {
|
|
453
436
|
return { closed: false };
|
|
454
437
|
}
|
|
455
|
-
const plan =
|
|
456
|
-
const scmClient =
|
|
438
|
+
const plan = createReleasePlan(cwd);
|
|
439
|
+
const scmClient = getScmClient();
|
|
457
440
|
const result = await scmClient.closeReviewRequestIfExists({
|
|
458
441
|
baseBranch: process.env.VERSIONARY_BASE_BRANCH ?? "main",
|
|
459
442
|
headBranch: plan.releaseBranchPrefix,
|
|
@@ -468,20 +451,20 @@ async function closeStaleReviewRequestIfExists(cwd = process.cwd(), options = {}
|
|
|
468
451
|
return result;
|
|
469
452
|
}
|
|
470
453
|
/** @deprecated Use prepareReleasePr. */
|
|
471
|
-
function prepareSimpleReleasePr(cwd = process.cwd(), options = {}) {
|
|
454
|
+
export function prepareSimpleReleasePr(cwd = process.cwd(), options = {}) {
|
|
472
455
|
return prepareReleasePr(cwd, options);
|
|
473
456
|
}
|
|
474
457
|
/** @deprecated Use openOrUpdateReviewRequest. */
|
|
475
|
-
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 = {}) {
|
|
476
459
|
return openOrUpdateReviewRequest(cwd, branch, title, version, previousVersion, commits, plan, options);
|
|
477
460
|
}
|
|
478
|
-
function pushReleaseBranch(cwd, branch) {
|
|
479
|
-
|
|
461
|
+
export function pushReleaseBranch(cwd, branch) {
|
|
462
|
+
execFileSync("git", ["push", "--force-with-lease", "origin", branch], {
|
|
480
463
|
cwd,
|
|
481
464
|
stdio: ["ignore", "pipe", "ignore"],
|
|
482
465
|
});
|
|
483
466
|
}
|
|
484
|
-
function isReleaseCommitMessage(commitMessage) {
|
|
467
|
+
export function isReleaseCommitMessage(commitMessage) {
|
|
485
468
|
if (/^Versionary-Release:\s*true$/imu.test(commitMessage)) {
|
|
486
469
|
return true;
|
|
487
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";
|