Skip to content

Commit

Permalink
chore: add release script (#2490)
Browse files Browse the repository at this point in the history
  • Loading branch information
marvinhagemeister authored Jun 4, 2024
1 parent 0ca7568 commit b0b4bf1
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 4 deletions.
15 changes: 11 additions & 4 deletions init/src/init.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import * as colors from "@std/fmt/colors";
import * as path from "@std/path";

// Keep these as is, as we replace these version in our release script
const FRESH_VERSION = "2.0.0-alpha.8";
const FRESH_TAILWIND_VERSION = "0.0.1-alpha.6";
const PREACT_VERSION = "10.22.0";
const PREACT_SIGNALS_VERSION = "1.2.3";

export const enum InitStep {
ProjectName = "ProjectName",
Force = "Force",
Expand Down Expand Up @@ -497,10 +503,11 @@ if (Deno.args.includes("build")) {
},
exclude: ["**/_fresh/*"],
imports: {
"@fresh/core": "jsr:@fresh/core@^2.0.0-alpha.8",
"@fresh/plugin-tailwind": "jsr:@fresh/plugin-tailwind@^0.0.1-alpha.6",
"preact": "npm:preact@^10.22.0",
"@preact/signals": "npm:@preact/signals@^1.2.3",
"@fresh/core": `jsr:@fresh/core@^${FRESH_VERSION}`,
"@fresh/plugin-tailwind":
`jsr:@fresh/plugin-tailwind@^${FRESH_TAILWIND_VERSION}`,
"preact": `npm:preact@^${PREACT_VERSION}`,
"@preact/signals": `npm:@preact/signals@^${PREACT_SIGNALS_VERSION}`,
} as Record<string, string>,
compilerOptions: {
lib: ["dom", "dom.asynciterable", "deno.ns"],
Expand Down
149 changes: 149 additions & 0 deletions tools/release.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import * as cl from "@std/fmt/colors";
import * as path from "@std/path";
import type { DenoJson } from "../update/src/update.ts";
import * as semver from "@std/semver";

function showHelp() {
console.log(`
Usage: deno run -A release.ts <major|minor|patch|...>
`);
}

function exitError(msg: string): never {
console.error(cl.red(msg));
showHelp();
Deno.exit(1);
}

if (Deno.args.length === 0) {
exitError(`Missing version argument.`);
} else if (Deno.args.length > 1) {
exitError(`Too many arguments. Expected only one release argument`);
}

const ROOT_DIR = path.join(import.meta.dirname!, "..");
const denoJsonPath = path.join(ROOT_DIR, "deno.json");
const denoJson = JSON.parse(await Deno.readTextFile(denoJsonPath)) as DenoJson;

const version = Deno.args[0];
const current = semver.parse(denoJson.version!);
const next = semver.parse(denoJson.version!);
if (version === "major") {
next.major++;
} else if (version === "minor") {
next.minor++;
} else if (version === "patch") {
next.patch++;
} else {
if (!next.prerelease) {
exitError(`Unknown prelease version`);
}

if (next.prerelease[0] === version) {
((next.prerelease[1]) as number)++;
} else {
next.prerelease[0] = version;
next.prerelease[1] = 1;
}
}

const initJsonPath = path.join(ROOT_DIR, "init", "deno.json");
const initJson = JSON.parse(await Deno.readTextFile(initJsonPath));
const currentInit = semver.parse(initJson.version);

const updateJsonPath = path.join(ROOT_DIR, "update", "deno.json");
const updateJson = JSON.parse(await Deno.readTextFile(updateJsonPath));
const currentUpdate = semver.parse(updateJson.version);

function formatUpgradeMsg(
name: string,
from: semver.SemVer,
to: semver.SemVer,
): string {
const nameMsg = cl.yellow(name);
const fromMsg = cl.green(semver.format(from));
const toMsg = cl.yellow(semver.format(to));

return ` ${nameMsg}: ${fromMsg} -> ${toMsg}`;
}

console.log(formatUpgradeMsg(denoJson.name!, current, next));
console.log(formatUpgradeMsg(initJson.name!, currentInit, next));
console.log(formatUpgradeMsg(updateJson.name!, currentUpdate, next));

if (!confirm("Proceed with update?")) {
Deno.exit(0);
}

const denoTailwindJson = JSON.parse(
await Deno.readTextFile(
path.join(ROOT_DIR, "plugin-tailwindcss", "deno.json"),
),
) as DenoJson;

async function replaceInFile(
file: string,
replacer: (content: string) => string,
) {
const raw = await Deno.readTextFile(file);
const replaced = replacer(raw);
await Deno.writeTextFile(file, replaced);
}

const nextVersion = semver.format(next);

function replaceJsonVersion(version: string) {
return (content: string) =>
content.replace(/"version":\s"[^"]+"/, `"version": "${version}"`);
}
await replaceInFile(denoJsonPath, replaceJsonVersion(nextVersion));
await replaceInFile(initJsonPath, replaceJsonVersion(nextVersion));
await replaceInFile(updateJsonPath, replaceJsonVersion(nextVersion));

async function getNpmVersion(name: string) {
const res = await fetch(`https://registry.npmjs.org/${name}`, {
headers: {
"Accept":
"application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*",
},
});
const json = await res.json();
return json["dist-tags"].latest;
}

const [preactVersion, preactSignalsVersion] = await Promise.all([
getNpmVersion("preact"),
getNpmVersion("@preact/signals"),
]);

function updateVersions(content: string): string {
const replaced = content
.replace(
/FRESH_VERSION\s=\s["']([^'"]+)['"]/g,
`FRESH_VERSION = "${nextVersion}"`,
)
.replace(
/FRESH_TAILWIND_VERSION\s=\s["']([^'"]+)['"]/g,
`FRESH_TAILWIND_VERSION = "${denoTailwindJson.version!}"`,
)
.replace(
/PREACT_VERSION\s=\s["']([^'"]+)['"]/g,
`PREACT_VERSION = "${preactVersion!}"`,
)
.replace(
/PREACT_SIGNALS_VERSION\s=\s["']([^'"]+)['"]/g,
`PREACT_SIGNALS_VERSION = "${preactSignalsVersion!}"`,
);

if (content === replaced) {
exitError(`Did not find FRESH_VERSION string`);
}

return replaced;
}

const updateScriptPath = path.join(ROOT_DIR, "update", "src", "update.ts");
await replaceInFile(updateScriptPath, updateVersions);

const initScriptPath = path.join(ROOT_DIR, "init", "src", "init.ts");
await replaceInFile(initScriptPath, updateVersions);
2 changes: 2 additions & 0 deletions update/src/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export const PREACT_VERSION = "10.20.2";
export const PREACT_SIGNALS_VERSION = "1.2.3";

export interface DenoJson {
name?: string;
version?: string;
imports?: Record<string, string>;
}

Expand Down

0 comments on commit b0b4bf1

Please sign in to comment.