chore(release): add rc prerelease flow
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import { getReleaseInfoFromSourceTag } from "./release-version-utils.mjs";
|
||||
|
||||
function usageAndExit(code = 1) {
|
||||
process.stderr.write(`Usage: node scripts/emit-release-env.mjs --source-tag <tag>\n`);
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
function parseArgs(argv) {
|
||||
let sourceTag = "";
|
||||
|
||||
for (let index = 0; index < argv.length; index += 1) {
|
||||
const arg = argv[index];
|
||||
if (arg === "--source-tag") {
|
||||
sourceTag = argv[index + 1] ?? "";
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if (arg === "--help" || arg === "-h") {
|
||||
usageAndExit(0);
|
||||
}
|
||||
usageAndExit();
|
||||
}
|
||||
|
||||
if (!sourceTag) {
|
||||
usageAndExit();
|
||||
}
|
||||
|
||||
return sourceTag;
|
||||
}
|
||||
|
||||
const sourceTag = parseArgs(process.argv.slice(2));
|
||||
const info = getReleaseInfoFromSourceTag(sourceTag);
|
||||
|
||||
const entries = [
|
||||
["SOURCE_TAG", info.sourceTag],
|
||||
["RELEASE_TAG", info.releaseTag],
|
||||
["RELEASE_VERSION", info.version],
|
||||
["RELEASE_BASE_VERSION", info.baseVersion],
|
||||
["RELEASE_PRERELEASE", info.prerelease ?? ""],
|
||||
["IS_PRERELEASE", info.isPrerelease ? "true" : "false"],
|
||||
["IS_RELEASE_CANDIDATE", info.isReleaseCandidate ? "true" : "false"],
|
||||
["RELEASE_TYPE", info.releaseType],
|
||||
["DESKTOP_VERSION", info.version],
|
||||
["IS_SMOKE_TAG", info.isSmokeTag ? "true" : "false"],
|
||||
];
|
||||
|
||||
for (const [key, value] of entries) {
|
||||
process.stdout.write(`${key}=${value}\n`);
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { readFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const rootDir = path.resolve(__dirname, "..");
|
||||
const rootPackagePath = path.join(rootDir, "package.json");
|
||||
|
||||
function usageAndExit(code = 0) {
|
||||
process.stderr.write(`Usage: node scripts/finalize-current-release.mjs\n`);
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
function run(cmd, args) {
|
||||
execFileSync(cmd, args, { cwd: rootDir, stdio: "inherit" });
|
||||
}
|
||||
|
||||
function runQuiet(cmd, args) {
|
||||
return execFileSync(cmd, args, { cwd: rootDir, encoding: "utf8" }).trim();
|
||||
}
|
||||
|
||||
function parseRepoSlug(remoteUrl) {
|
||||
const trimmed = remoteUrl.trim().replace(/\.git$/, "");
|
||||
const httpsMatch = trimmed.match(/github\.com[/:]([^/]+\/[^/]+)$/);
|
||||
if (httpsMatch) {
|
||||
return httpsMatch[1];
|
||||
}
|
||||
throw new Error(`Could not determine GitHub repo from origin URL: ${remoteUrl}`);
|
||||
}
|
||||
|
||||
if (process.argv.length > 2) {
|
||||
const arg = process.argv[2];
|
||||
if (arg === "--help" || arg === "-h") {
|
||||
usageAndExit(0);
|
||||
}
|
||||
usageAndExit(1);
|
||||
}
|
||||
|
||||
const rootPackage = JSON.parse(readFileSync(rootPackagePath, "utf8"));
|
||||
const version = typeof rootPackage.version === "string" ? rootPackage.version.trim() : "";
|
||||
if (!version) {
|
||||
throw new Error('Root package.json must contain a valid "version"');
|
||||
}
|
||||
|
||||
const tag = `v${version}`;
|
||||
const repo = parseRepoSlug(runQuiet("git", ["remote", "get-url", "origin"]));
|
||||
const releaseJson = runQuiet("gh", [
|
||||
"release",
|
||||
"view",
|
||||
tag,
|
||||
"--repo",
|
||||
repo,
|
||||
"--json",
|
||||
"isDraft,tagName,url",
|
||||
]);
|
||||
const release = JSON.parse(releaseJson);
|
||||
|
||||
if (!release.isDraft) {
|
||||
throw new Error(`Release ${tag} is already published. Refusing to finalize a non-draft release.`);
|
||||
}
|
||||
|
||||
run("npm", ["run", "release:publish"]);
|
||||
run("gh", ["release", "edit", tag, "--repo", repo, "--draft=false"]);
|
||||
|
||||
console.log(`Finalized release ${tag}: npm packages published and GitHub draft release promoted.`);
|
||||
@@ -8,7 +8,7 @@ const rootDir = path.resolve(__dirname, "..");
|
||||
const rootPackagePath = path.join(rootDir, "package.json");
|
||||
|
||||
function usageAndExit(code = 0) {
|
||||
process.stderr.write(`Usage: node scripts/push-current-release-tag.mjs [--draft-release]\n`);
|
||||
process.stderr.write(`Usage: node scripts/push-current-release-tag.mjs [--branch <name>]\n`);
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
@@ -20,12 +20,32 @@ function runQuiet(cmd, args) {
|
||||
return execFileSync(cmd, args, { cwd: rootDir, encoding: "utf8" }).trim();
|
||||
}
|
||||
|
||||
function parseArgs(argv) {
|
||||
const args = { draftRelease: false };
|
||||
function getRemoteTagCommit(tag) {
|
||||
try {
|
||||
return runQuiet("git", ["ls-remote", "--exit-code", "--refs", "origin", `refs/tags/${tag}^{}`])
|
||||
.split(/\s+/)[0]
|
||||
.trim();
|
||||
} catch {
|
||||
try {
|
||||
return runQuiet("git", ["ls-remote", "--exit-code", "--refs", "origin", `refs/tags/${tag}`])
|
||||
.split(/\s+/)[0]
|
||||
.trim();
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const arg of argv) {
|
||||
if (arg === "--draft-release") {
|
||||
args.draftRelease = true;
|
||||
function parseArgs(argv) {
|
||||
const args = {
|
||||
branch: "",
|
||||
};
|
||||
|
||||
for (let index = 0; index < argv.length; index += 1) {
|
||||
const arg = argv[index];
|
||||
if (arg === "--branch") {
|
||||
args.branch = argv[index + 1] ?? "";
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if (arg === "--help" || arg === "-h") {
|
||||
@@ -37,22 +57,13 @@ function parseArgs(argv) {
|
||||
return args;
|
||||
}
|
||||
|
||||
function parseRepoSlug(remoteUrl) {
|
||||
const trimmed = remoteUrl.trim().replace(/\.git$/, "");
|
||||
const httpsMatch = trimmed.match(/github\.com[/:]([^/]+\/[^/]+)$/);
|
||||
if (httpsMatch) {
|
||||
return httpsMatch[1];
|
||||
}
|
||||
throw new Error(`Could not determine GitHub repo from origin URL: ${remoteUrl}`);
|
||||
}
|
||||
|
||||
const args = parseArgs(process.argv.slice(2));
|
||||
const rootPackage = JSON.parse(readFileSync(rootPackagePath, "utf8"));
|
||||
const version = typeof rootPackage.version === "string" ? rootPackage.version.trim() : "";
|
||||
if (!version) {
|
||||
throw new Error('Root package.json must contain a valid "version"');
|
||||
}
|
||||
|
||||
const args = parseArgs(process.argv.slice(2));
|
||||
const tag = `v${version}`;
|
||||
const headCommit = runQuiet("git", ["rev-parse", "HEAD"]);
|
||||
|
||||
@@ -71,33 +82,25 @@ if (localTagCommit !== headCommit) {
|
||||
);
|
||||
}
|
||||
|
||||
run("git", ["push", "origin", "HEAD"]);
|
||||
|
||||
let remoteTagExists = false;
|
||||
try {
|
||||
runQuiet("git", ["ls-remote", "--exit-code", "--tags", "origin", `refs/tags/${tag}`]);
|
||||
remoteTagExists = true;
|
||||
} catch {
|
||||
remoteTagExists = false;
|
||||
const currentBranch = runQuiet("git", ["branch", "--show-current"]);
|
||||
const branchRef = args.branch || currentBranch;
|
||||
if (!branchRef) {
|
||||
throw new Error("Cannot determine branch to push. Pass --branch <name>.");
|
||||
}
|
||||
run("git", ["push", "origin", `HEAD:${branchRef}`]);
|
||||
|
||||
if (remoteTagExists) {
|
||||
const remoteTagCommit = getRemoteTagCommit(tag);
|
||||
|
||||
if (remoteTagCommit) {
|
||||
if (remoteTagCommit !== localTagCommit) {
|
||||
throw new Error(
|
||||
`Remote tag ${tag} points to ${remoteTagCommit}, but local tag points to ${localTagCommit}. ` +
|
||||
"Refusing to reuse an existing release tag for a different commit.",
|
||||
);
|
||||
}
|
||||
console.log(`Tag ${tag} already exists on origin`);
|
||||
} else {
|
||||
run("git", ["push", "origin", tag]);
|
||||
}
|
||||
|
||||
if (args.draftRelease) {
|
||||
const repo = parseRepoSlug(runQuiet("git", ["remote", "get-url", "origin"]));
|
||||
run("node", [
|
||||
path.join("scripts", "sync-release-notes-from-changelog.mjs"),
|
||||
"--repo",
|
||||
repo,
|
||||
"--tag",
|
||||
tag,
|
||||
"--create-if-missing",
|
||||
"--draft",
|
||||
]);
|
||||
}
|
||||
|
||||
console.log(`Release push complete: branch HEAD and tag ${tag}`);
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
const versionPattern = /^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?:-(?<prerelease>[0-9A-Za-z.-]+))?$/;
|
||||
const sourceTagPattern =
|
||||
/^(?:(?:desktop(?:-(?:windows|linux|macos))?|android)-)?v(?<version>\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)$/;
|
||||
|
||||
function assertInteger(value, label) {
|
||||
if (!Number.isInteger(value) || value < 0) {
|
||||
throw new Error(`Invalid ${label}: ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function parseReleaseVersion(version) {
|
||||
const trimmed = version.trim();
|
||||
const match = trimmed.match(versionPattern);
|
||||
if (!match?.groups) {
|
||||
throw new Error(
|
||||
`Unsupported release version "${version}". Expected semver like 0.1.41 or 0.1.41-rc.1.`,
|
||||
);
|
||||
}
|
||||
|
||||
const major = Number.parseInt(match.groups.major, 10);
|
||||
const minor = Number.parseInt(match.groups.minor, 10);
|
||||
const patch = Number.parseInt(match.groups.patch, 10);
|
||||
const prerelease = match.groups.prerelease ?? null;
|
||||
const rcMatch = prerelease?.match(/^rc\.(?<rc>\d+)$/) ?? null;
|
||||
const rcNumber = rcMatch?.groups?.rc ? Number.parseInt(rcMatch.groups.rc, 10) : null;
|
||||
|
||||
assertInteger(major, "major version");
|
||||
assertInteger(minor, "minor version");
|
||||
assertInteger(patch, "patch version");
|
||||
if (rcNumber !== null) {
|
||||
assertInteger(rcNumber, "release candidate number");
|
||||
}
|
||||
|
||||
return {
|
||||
version: trimmed,
|
||||
major,
|
||||
minor,
|
||||
patch,
|
||||
prerelease,
|
||||
baseVersion: `${major}.${minor}.${patch}`,
|
||||
isPrerelease: prerelease !== null,
|
||||
isReleaseCandidate: rcNumber !== null,
|
||||
rcNumber,
|
||||
};
|
||||
}
|
||||
|
||||
export function formatReleaseVersion({ major, minor, patch, prerelease = null }) {
|
||||
assertInteger(major, "major version");
|
||||
assertInteger(minor, "minor version");
|
||||
assertInteger(patch, "patch version");
|
||||
return prerelease ? `${major}.${minor}.${patch}-${prerelease}` : `${major}.${minor}.${patch}`;
|
||||
}
|
||||
|
||||
export function normalizeReleaseTag(rawTag) {
|
||||
const trimmed = rawTag.trim().replace(/^refs\/tags\//, "");
|
||||
const match = trimmed.match(sourceTagPattern);
|
||||
if (!match?.groups?.version) {
|
||||
throw new Error(
|
||||
`Unsupported release tag "${rawTag}". Expected vX.Y.Z, vX.Y.Z-rc.N, desktop-v..., or android-v...`,
|
||||
);
|
||||
}
|
||||
return `v${match.groups.version}`;
|
||||
}
|
||||
|
||||
export function getReleaseInfoFromSourceTag(sourceTag) {
|
||||
const releaseTag = normalizeReleaseTag(sourceTag);
|
||||
const parsed = parseReleaseVersion(releaseTag.slice(1));
|
||||
return {
|
||||
sourceTag,
|
||||
releaseTag,
|
||||
version: parsed.version,
|
||||
baseVersion: parsed.baseVersion,
|
||||
prerelease: parsed.prerelease,
|
||||
isPrerelease: parsed.isPrerelease,
|
||||
isReleaseCandidate: parsed.isReleaseCandidate,
|
||||
rcNumber: parsed.rcNumber,
|
||||
releaseType: parsed.isPrerelease ? "prerelease" : "release",
|
||||
isSmokeTag: sourceTag.includes("gha-smoke"),
|
||||
};
|
||||
}
|
||||
|
||||
export function computeNextReleaseVersion(currentVersion, mode) {
|
||||
const parsed = parseReleaseVersion(currentVersion);
|
||||
|
||||
if (mode === "patch" || mode === "minor" || mode === "major") {
|
||||
if (parsed.isPrerelease) {
|
||||
throw new Error(
|
||||
`Cannot cut a stable ${mode} release from prerelease version ${currentVersion}. Promote it first.`,
|
||||
);
|
||||
}
|
||||
if (mode === "patch") {
|
||||
return formatReleaseVersion({
|
||||
major: parsed.major,
|
||||
minor: parsed.minor,
|
||||
patch: parsed.patch + 1,
|
||||
});
|
||||
}
|
||||
if (mode === "minor") {
|
||||
return formatReleaseVersion({
|
||||
major: parsed.major,
|
||||
minor: parsed.minor + 1,
|
||||
patch: 0,
|
||||
});
|
||||
}
|
||||
return formatReleaseVersion({
|
||||
major: parsed.major + 1,
|
||||
minor: 0,
|
||||
patch: 0,
|
||||
});
|
||||
}
|
||||
|
||||
if (mode === "rc-patch" || mode === "rc-minor" || mode === "rc-major") {
|
||||
if (parsed.isPrerelease) {
|
||||
throw new Error(
|
||||
`Cannot start a new RC line from prerelease version ${currentVersion}. Use rc-next or promote.`,
|
||||
);
|
||||
}
|
||||
if (mode === "rc-patch") {
|
||||
return formatReleaseVersion({
|
||||
major: parsed.major,
|
||||
minor: parsed.minor,
|
||||
patch: parsed.patch + 1,
|
||||
prerelease: "rc.1",
|
||||
});
|
||||
}
|
||||
if (mode === "rc-minor") {
|
||||
return formatReleaseVersion({
|
||||
major: parsed.major,
|
||||
minor: parsed.minor + 1,
|
||||
patch: 0,
|
||||
prerelease: "rc.1",
|
||||
});
|
||||
}
|
||||
return formatReleaseVersion({
|
||||
major: parsed.major + 1,
|
||||
minor: 0,
|
||||
patch: 0,
|
||||
prerelease: "rc.1",
|
||||
});
|
||||
}
|
||||
|
||||
if (mode === "rc-next") {
|
||||
if (!parsed.isReleaseCandidate || parsed.rcNumber === null) {
|
||||
throw new Error(
|
||||
`Cannot advance RC number from ${currentVersion}. Expected a version like 0.1.41-rc.1.`,
|
||||
);
|
||||
}
|
||||
return formatReleaseVersion({
|
||||
major: parsed.major,
|
||||
minor: parsed.minor,
|
||||
patch: parsed.patch,
|
||||
prerelease: `rc.${parsed.rcNumber + 1}`,
|
||||
});
|
||||
}
|
||||
|
||||
if (mode === "promote") {
|
||||
if (!parsed.isReleaseCandidate) {
|
||||
throw new Error(
|
||||
`Cannot promote ${currentVersion}. Expected a release candidate version like 0.1.41-rc.1.`,
|
||||
);
|
||||
}
|
||||
return parsed.baseVersion;
|
||||
}
|
||||
|
||||
throw new Error(`Unsupported release mode "${mode}".`);
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { readFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { computeNextReleaseVersion } from "./release-version-utils.mjs";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const rootDir = path.resolve(__dirname, "..");
|
||||
const rootPackagePath = path.join(rootDir, "package.json");
|
||||
|
||||
function usageAndExit(code = 1) {
|
||||
process.stderr.write(`Usage: node scripts/set-release-version.mjs --mode <mode> [--print]\n`);
|
||||
process.stderr.write(
|
||||
"Modes: patch, minor, major, rc-patch, rc-minor, rc-major, rc-next, promote\n",
|
||||
);
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
function parseArgs(argv) {
|
||||
const args = {
|
||||
mode: "",
|
||||
print: false,
|
||||
};
|
||||
|
||||
for (let index = 0; index < argv.length; index += 1) {
|
||||
const arg = argv[index];
|
||||
if (arg === "--mode") {
|
||||
args.mode = argv[index + 1] ?? "";
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
if (arg === "--print") {
|
||||
args.print = true;
|
||||
continue;
|
||||
}
|
||||
if (arg === "--help" || arg === "-h") {
|
||||
usageAndExit(0);
|
||||
}
|
||||
usageAndExit();
|
||||
}
|
||||
|
||||
if (!args.mode) {
|
||||
usageAndExit();
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
const args = parseArgs(process.argv.slice(2));
|
||||
const rootPackage = JSON.parse(readFileSync(rootPackagePath, "utf8"));
|
||||
const currentVersion = typeof rootPackage.version === "string" ? rootPackage.version.trim() : "";
|
||||
|
||||
if (!currentVersion) {
|
||||
throw new Error('Root package.json must contain a valid "version".');
|
||||
}
|
||||
|
||||
const nextVersion = computeNextReleaseVersion(currentVersion, args.mode);
|
||||
|
||||
if (args.print) {
|
||||
process.stdout.write(`${nextVersion}\n`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
execFileSync(
|
||||
"npm",
|
||||
[
|
||||
"version",
|
||||
nextVersion,
|
||||
"--include-workspace-root",
|
||||
"--message",
|
||||
"chore(release): cut %s",
|
||||
],
|
||||
{ cwd: rootDir, stdio: "inherit" },
|
||||
);
|
||||
@@ -2,6 +2,11 @@ import { execFileSync } from "node:child_process";
|
||||
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
import {
|
||||
getReleaseInfoFromSourceTag,
|
||||
normalizeReleaseTag,
|
||||
parseReleaseVersion,
|
||||
} from "./release-version-utils.mjs";
|
||||
|
||||
const headingPattern = /^##\s+\[?([^\]\s]+)\]?\s*-\s*([0-9]{4}-[0-9]{2}-[0-9]{2})\s*$/;
|
||||
|
||||
@@ -13,7 +18,6 @@ Options:
|
||||
--repo <owner/repo> Repository slug. Defaults to $GITHUB_REPOSITORY.
|
||||
--tag <tag> Release tag (e.g. v0.1.14). Defaults to latest changelog entry.
|
||||
--create-if-missing Create release if it does not already exist.
|
||||
--draft Create missing release as draft.
|
||||
`;
|
||||
process.stderr.write(usage.trimStart());
|
||||
process.stderr.write("\n");
|
||||
@@ -25,7 +29,6 @@ function parseArgs(argv) {
|
||||
repo: process.env.GITHUB_REPOSITORY || "",
|
||||
tag: "",
|
||||
createIfMissing: false,
|
||||
draft: false,
|
||||
};
|
||||
|
||||
for (let index = 0; index < argv.length; index += 1) {
|
||||
@@ -54,12 +57,6 @@ function parseArgs(argv) {
|
||||
args.createIfMissing = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === "--draft") {
|
||||
args.draft = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
usageAndExit();
|
||||
}
|
||||
|
||||
@@ -70,11 +67,6 @@ function parseArgs(argv) {
|
||||
return args;
|
||||
}
|
||||
|
||||
function normalizeTag(rawTag) {
|
||||
const trimmed = rawTag.trim().replace(/^refs\/tags\//, "");
|
||||
return trimmed.startsWith("v") ? trimmed : `v${trimmed}`;
|
||||
}
|
||||
|
||||
function parseChangelog(changelogText) {
|
||||
const lines = changelogText.split(/\r?\n/);
|
||||
const headings = [];
|
||||
@@ -140,23 +132,51 @@ function runGh(args) {
|
||||
execFileSync("gh", args, { stdio: "inherit" });
|
||||
}
|
||||
|
||||
function buildPrereleaseNotes({ releaseTag, version }) {
|
||||
const today = new Date().toISOString().slice(0, 10);
|
||||
const lines = [
|
||||
`## ${version} - ${today}`,
|
||||
"",
|
||||
"Release candidate build for testing from `main`.",
|
||||
"",
|
||||
`- Tag: \`${releaseTag}\``,
|
||||
];
|
||||
|
||||
if (process.env.GITHUB_SHA) {
|
||||
lines.push(`- Commit: \`${process.env.GITHUB_SHA}\``);
|
||||
}
|
||||
|
||||
lines.push("- This prerelease does not replace the website's latest stable download.");
|
||||
return `${lines.join("\n")}\n`;
|
||||
}
|
||||
|
||||
function main() {
|
||||
const args = parseArgs(process.argv.slice(2));
|
||||
const changelogPath = path.resolve("CHANGELOG.md");
|
||||
const changelogText = readFileSync(changelogPath, "utf8");
|
||||
const entries = parseChangelog(changelogText);
|
||||
|
||||
const targetTag = args.tag ? normalizeTag(args.tag) : entries[0].tag;
|
||||
const targetTag = args.tag ? normalizeReleaseTag(args.tag) : entries[0].tag;
|
||||
const releaseInfo = getReleaseInfoFromSourceTag(targetTag);
|
||||
const targetEntry = entries.find((entry) => entry.tag === targetTag);
|
||||
|
||||
if (!targetEntry) {
|
||||
let notes = targetEntry?.notes ?? null;
|
||||
|
||||
if (!notes && releaseInfo.isPrerelease) {
|
||||
notes = buildPrereleaseNotes({
|
||||
releaseTag: releaseInfo.releaseTag,
|
||||
version: releaseInfo.version,
|
||||
});
|
||||
}
|
||||
|
||||
if (!notes) {
|
||||
console.log(`No matching changelog section found for ${targetTag}. Skipping.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const tempDir = mkdtempSync(path.join(tmpdir(), "paseo-release-notes-"));
|
||||
const notesPath = path.join(tempDir, `${targetTag}-notes.md`);
|
||||
writeFileSync(notesPath, targetEntry.notes);
|
||||
writeFileSync(notesPath, notes);
|
||||
|
||||
try {
|
||||
if (hasRelease(targetTag, args.repo)) {
|
||||
@@ -184,7 +204,7 @@ function main() {
|
||||
"--notes-file",
|
||||
notesPath,
|
||||
"--verify-tag",
|
||||
...(args.draft ? ["--draft"] : []),
|
||||
...(parseReleaseVersion(releaseInfo.version).isPrerelease ? ["--prerelease"] : []),
|
||||
]);
|
||||
console.log(`Created release ${targetTag} with changelog notes.`);
|
||||
} catch (createError) {
|
||||
|
||||
Reference in New Issue
Block a user