admin: updated version bump script

This commit is contained in:
Richard Moore 2022-09-29 22:54:58 -04:00
parent 1f2318a34a
commit c1f86802fb
5 changed files with 227 additions and 8 deletions

@ -1,8 +0,0 @@
import { atomicWrite } from "./utils/fs.js";
import { resolve } from "./utils/path.js";
import { loadJson } from "./utils/json.js";
const version = loadJson(resolve("package.json")).version;
const content = `export const version = "${ version }";\n`;
atomicWrite(resolve("src.ts/_version.ts"), content);

@ -0,0 +1,74 @@
import semver from "semver";
import { FetchRequest } from "../utils/index.js";
import { atomicWrite } from "./utils/fs.js";
import { getGitTag } from "./utils/git.js";
import { loadJson, saveJson } from "./utils/json.js";
import { resolve } from "./utils/path.js";
const cache: Record<string, any> = { };
async function getNpmPackage(name: string): Promise<any> {
if (!cache[name]) {
const resp = await (new FetchRequest("https:/\/registry.npmjs.org/" + name)).send();
resp.assertOk();
cache[name] = resp.bodyJson;
}
return cache[name] || null;
}
function writeVersion(version: string): void {
const content = `export const version = "${ version }";\n`;
atomicWrite(resolve("src.ts/_version.ts"), content);
}
(async function() {
// Local pkg
const pkgPath = resolve("package.json");
const pkgInfo = loadJson(pkgPath);
const tag = pkgInfo.publishConfig.tag;
// Get the remote version that matches our dist-tag
const remoteInfo = await getNpmPackage(pkgInfo.name);
const remoteVersion = remoteInfo["dist-tags"][tag];
// Remote pkg
const remotePkgInfo = remoteInfo.versions[remoteVersion];
const remoteGitHead = remotePkgInfo.gitHead;
const gitHead = await getGitTag(resolve("."));
// There are new commits, not reflected in the package
// published on npm; update the gitHead and version
if (gitHead !== remoteGitHead) {
// Bump the version from the remote version
if (tag.indexOf("beta") >= 0) {
// Still a beta branch; advance the beta version
const prerelease = semver.prerelease(remoteVersion);
if (prerelease == null || prerelease.length !== 2) {
throw new Error("no prerelease found");
}
pkgInfo.version = semver.inc(remoteVersion, "prerelease", String(prerelease[0]));
} else if (semver.minor(remoteVersion) == semver.minor(pkgInfo.version)) {
// If we want to bump the minor version, it was done explicitly in the pkg
pkgInfo.version = semver.inc(remoteVersion, "patch");
}
pkgInfo.gitHead = gitHead;
// Save the package.json
saveJson(pkgPath, pkgInfo, true);
// Save the src.ts/_version.ts
writeVersion(pkgInfo.version);
}
})().catch((error) => {
console.log("ERROR");
console.log(error);
process.exit(1)
});

@ -0,0 +1,14 @@
import { run } from "./run.js";
// Returns the most recent git commit hash for a given filename
export async function getGitTag(filename: string): Promise<null | string> {
const result = await run("git", [ "log", "-n", "1", "--", filename ]);
if (!result.ok) { throw new Error(`git log error`); }
let log = result.stdout.trim();
if (!log) { return null; }
const hashMatch = log.match(/^commit\s+([0-9a-f]{40})\n/i);
if (!hashMatch) { return null; }
return hashMatch[1];
}

@ -0,0 +1,76 @@
/*
import semver from "semver";
import { FetchRequest } from "../../utils/index.js";
export type PackageInfo = {
dependencies: { [ name: string ]: string };
devDependencies: { [ name: string ]: string };
gitHead: string;
name: string;
version: string;
tarballHash: string;
location: "remote" | "local";
_ethers_nobuild: boolean;
};
export class Package {
readonly #info: PackageInfo;
constructor(info: PackageInfo) {
this.#info = info;
}
get name(): string { return this.#info.name; }
get version(): string { return this.#info.version; }
get dependencies(): Record<string, string> { return this.#info.dependencies; }
get devDependencies(): Record<string, string> { return this.#info.devDependencies; }
get gitHead(): string { return this.#info.gitHead; }
get tarballHash(): string { return this.#info.tarballHash; }
}
const cache: Record<string, any> = { };
async function getPackageInfo(name: string): Promise<any> {
if (!cache[name]) {
const resp = await (new FetchRequest("https:/\/registry.npmjs.org/" + name)).send();
resp.assertOk();
cache[name] = resp.bodyJson();
}
return cache[name] || null;
}
export async function getPackage(name: string, version?: string): Promise<null | Package> {
const infos = await getPackageInfo(name);
if (infos == null) { return null; }
if (version == null) {
const versions = Object.keys(infos.versions);
versions.sort(semver.compare);
// HACK: So v5 continues working while v6 is managed by reticulate
version = "6.0.0";
while (version.indexOf("beta") >= 0 || semver.gte(version, "6.0.0")) {
version = versions.pop();
}
}
const info = infos.versions[version];
return new Package({
dependencies: (info.dependencies || {}),
devDependencies: (info.devDependencies || {}),
gitHead: info.gitHead,
location: "remote",
name: info.name,
tarballHash: info.tarballHash,
version : info.version,
_ethers_nobuild: !!info._ethers_nobuild,
});
}
*/

@ -0,0 +1,63 @@
import { spawnSync } from "child_process";
export class RunResult {
readonly #cmd: string;
readonly #status: null | number;
readonly #stdout: string | Buffer;
readonly #stderr: string | Buffer;
constructor(progname: string, args: Array<string>, status: null | number, stdout: string | Buffer, stderr: string | Buffer) {
this.#cmd = `${ progname } ${ args.map((a) => JSON.stringify(a))}`;
this.#status = status;
this.#stdout = stdout;
this.#stderr = stderr;
}
get cmd(): string { return this.#cmd; }
get stderr(): string | null {
return this._stderr.toString() || null;
}
get _stderr(): string | Buffer {
return this.#stderr;
}
get stdout(): string {
return this._stdout.toString();
}
get _stdout(): string | Buffer {
return this.#stdout;
}
get status(): null | number { return this.#status; }
get ok(): boolean {
return (this.#stderr.length === 0 && this.#status === 0);
}
assertOk(message?: string): void {
if (!this.ok) {
throw new Error(message || `failed to run: ${ this.#cmd }`);
}
}
};
export function run(progname: string, args?: Array<string>, currentWorkingDirectory?: string): RunResult {
if (args == null) { args = [ ]; }
const options: any = { };
if (currentWorkingDirectory) { options.cwd = currentWorkingDirectory; }
const child = spawnSync(progname, args, options);
const result = new RunResult(progname, args, child.status, child.stdout, child.stderr);
if (child.error) {
const error = child.error;
(<any>error).result = result;
throw error;
}
return result;
}