Initial Commit
This commit is contained in:
commit
0534f88f70
14 changed files with 5590 additions and 0 deletions
144
scripts/pack-release.mjs
Normal file
144
scripts/pack-release.mjs
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
import { createHash } from "node:crypto";
|
||||
import { createReadStream, createWriteStream } from "node:fs";
|
||||
import { mkdir, readdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import process from "node:process";
|
||||
import * as tar from "tar";
|
||||
import { ZipFile } from "yazl";
|
||||
|
||||
const root = process.cwd();
|
||||
const distDir = path.join(root, "dist");
|
||||
const releaseDir = path.join(distDir, "release");
|
||||
|
||||
function releaseTag() {
|
||||
const value = process.env.TAG ?? process.env.FORGEJO_REF_NAME ?? process.env.GITHUB_REF_NAME ?? "";
|
||||
return value.replace(/^refs\/tags\//, "") || "dev";
|
||||
}
|
||||
|
||||
function cleanTag(tag) {
|
||||
return tag.replace(/[^A-Za-z0-9._-]+/g, "-");
|
||||
}
|
||||
|
||||
async function ensureBuilt() {
|
||||
const index = path.join(distDir, "index.html");
|
||||
try {
|
||||
const info = await stat(index);
|
||||
if (!info.isFile()) throw new Error();
|
||||
} catch {
|
||||
throw new Error("dist/index.html is missing. Run `pnpm run build` before `pnpm run release:pack`.");
|
||||
}
|
||||
}
|
||||
|
||||
async function distEntries() {
|
||||
const entries = await readdir(distDir);
|
||||
return entries.filter((entry) => entry !== "release");
|
||||
}
|
||||
|
||||
async function addZipPath(zip, source, name) {
|
||||
const info = await stat(source);
|
||||
if (info.isDirectory()) {
|
||||
const children = await readdir(source);
|
||||
if (children.length === 0) {
|
||||
zip.addEmptyDirectory(name);
|
||||
return;
|
||||
}
|
||||
for (const child of children) {
|
||||
await addZipPath(zip, path.join(source, child), `${name}/${child}`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
zip.addFile(source, name);
|
||||
}
|
||||
|
||||
async function writeZip(file, entries, bundleName) {
|
||||
await new Promise((resolve, reject) => {
|
||||
const output = createWriteStream(file);
|
||||
const zip = new ZipFile();
|
||||
output.on("close", resolve);
|
||||
output.on("error", reject);
|
||||
zip.outputStream.on("error", reject);
|
||||
zip.outputStream.pipe(output);
|
||||
Promise.all(entries.map((entry) => addZipPath(zip, path.join(distDir, entry), `${bundleName}/${entry}`)))
|
||||
.then(() => zip.end())
|
||||
.catch(reject);
|
||||
});
|
||||
}
|
||||
|
||||
async function sha256(file) {
|
||||
const hash = createHash("sha256");
|
||||
await new Promise((resolve, reject) => {
|
||||
createReadStream(file)
|
||||
.on("data", (chunk) => hash.update(chunk))
|
||||
.on("error", reject)
|
||||
.on("end", resolve);
|
||||
});
|
||||
return hash.digest("hex");
|
||||
}
|
||||
|
||||
async function readBuildInfo() {
|
||||
try {
|
||||
return JSON.parse(await readFile(path.join(distDir, "spec", "build-info.json"), "utf8"));
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await ensureBuilt();
|
||||
const tag = cleanTag(releaseTag());
|
||||
const bundleName = `wry-docs-${tag}`;
|
||||
const entries = await distEntries();
|
||||
|
||||
await rm(releaseDir, { recursive: true, force: true });
|
||||
await mkdir(releaseDir, { recursive: true });
|
||||
|
||||
const tarball = path.join(releaseDir, `${bundleName}.tar.gz`);
|
||||
const zipfile = path.join(releaseDir, `${bundleName}.zip`);
|
||||
|
||||
await tar.c(
|
||||
{
|
||||
cwd: distDir,
|
||||
file: tarball,
|
||||
gzip: true,
|
||||
portable: true,
|
||||
prefix: `${bundleName}/`
|
||||
},
|
||||
entries
|
||||
);
|
||||
await writeZip(zipfile, entries, bundleName);
|
||||
|
||||
const assets = [tarball, zipfile];
|
||||
const sums = [];
|
||||
for (const file of assets) {
|
||||
sums.push(`${await sha256(file)} ${path.basename(file)}`);
|
||||
}
|
||||
await writeFile(path.join(releaseDir, "SHA256SUMS"), `${sums.join("\n")}\n`);
|
||||
|
||||
const info = await readBuildInfo();
|
||||
const notes = [
|
||||
`# Wry Docs ${tag}`,
|
||||
"",
|
||||
"Static documentation bundle generated from Wry's TOML configuration specs.",
|
||||
"",
|
||||
"## Source",
|
||||
"",
|
||||
`- Wry branch: \`${info.sourceBranch ?? "unknown"}\``,
|
||||
`- Wry commit: \`${info.sourceCommit ?? "unknown"}\``,
|
||||
`- Generated at: \`${info.generatedAt ?? "unknown"}\``,
|
||||
"",
|
||||
"## Assets",
|
||||
"",
|
||||
`- \`${path.basename(tarball)}\``,
|
||||
`- \`${path.basename(zipfile)}\``,
|
||||
"- `SHA256SUMS`",
|
||||
""
|
||||
].join("\n");
|
||||
await writeFile(path.join(releaseDir, "RELEASE_NOTES.md"), notes);
|
||||
|
||||
console.log(`Wrote release assets to ${releaseDir}`);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue