feat: customize launcher version check and CI/CD release workflow for G-Launcher

This commit is contained in:
CAtlas0784 committed 2026-10-30 21:07:59 +07:00
1 parent a5205d1bed
commit 88a1f1c40a
12 files changed
+435 -61

No files matched your search

+74
View File
@@ -0,0 +1,74 @@
import { createHash } from "node:crypto";
import { readFile, writeFile } from "node:fs/promises";
import { pathToFileURL } from "node:url";
const versionPattern = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
export function nextLauncherVersion(currentVersion) {
const match = currentVersion.match(versionPattern);
if (!match) {
throw new Error(`Invalid launcher version: ${currentVersion}`);
}
let [major, minor, patch] = match.slice(1).map(Number);
patch += 1;
if (patch === 10) {
patch = 0;
minor += 1;
if (minor === 10) {
minor = 0;
major += 1;
}
}
return `${major}.${minor}.${patch}`;
}
export async function createLauncherManifest(version, executablePath) {
if (!versionPattern.test(version)) {
throw new Error(`Invalid launcher version: ${version}`);
}
const executable = await readFile(executablePath);
return {
version,
sha256: createHash("sha256").update(executable).digest("hex"),
};
}
async function main(args) {
const [command, ...values] = args;
if (command === "next" && values.length === 1) {
console.log(nextLauncherVersion(values[0]));
return;
}
if (command === "manifest" && values.length === 3) {
const [version, executablePath, manifestPath] = values;
const manifest = await createLauncherManifest(version, executablePath);
await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
return;
}
if (command === "stamp-info" && values.length === 2) {
const [version, infoPath] = values;
if (!versionPattern.test(version)) {
throw new Error(`Invalid launcher version: ${version}`);
}
const info = JSON.parse(await readFile(infoPath, "utf8"));
info.fixed.file_version = version;
info.info["0000"].ProductVersion = version;
await writeFile(infoPath, `${JSON.stringify(info, null, 2)}\n`);
return;
}
throw new Error(
"Usage: launcher-release.mjs next <version> | manifest <version> <exe> <output> | stamp-info <version> <info.json>",
);
}
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
main(process.argv.slice(2)).catch((error) => {
console.error(error.message);
process.exitCode = 1;
});
}
+34
View File
@@ -0,0 +1,34 @@
import assert from "node:assert/strict";
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { test } from "node:test";
import { createLauncherManifest, nextLauncherVersion } from "./launcher-release.mjs";
test("increments patch digits and rolls over minor and major digits", () => {
assert.equal(nextLauncherVersion("2.1.0"), "2.1.1");
assert.equal(nextLauncherVersion("2.1.9"), "2.2.0");
assert.equal(nextLauncherVersion("2.9.9"), "3.0.0");
});
test("rejects versions outside the three-number sequence", () => {
assert.throws(() => nextLauncherVersion("2.1"), /Invalid launcher version/);
assert.throws(() => nextLauncherVersion("02.1.0"), /Invalid launcher version/);
});
test("creates a manifest with the executable SHA-256", async () => {
const directory = await mkdtemp(join(tmpdir(), "sunbringer-release-test-"));
const executablePath = join(directory, "launcher.exe");
try {
await writeFile(executablePath, "test executable");
const manifest = await createLauncherManifest("2.1.1", executablePath);
assert.equal(manifest.version, "2.1.1");
assert.equal(
manifest.sha256,
"ff8715f0270731bbdb0bb3586a77d032f5e883b8909dcafbf3e8909cb8c71201",
);
} finally {
await rm(directory, { recursive: true, force: true });
}
});