feat(build): integrate generation of manifest file in build process

This commit is contained in:
Pihkaal
2024-07-08 02:03:47 +02:00
parent 8d8d0bf26d
commit 363027187d
8 changed files with 249 additions and 5 deletions

22
build/env.ts Normal file
View File

@@ -0,0 +1,22 @@
import { z } from "zod";
import { configDotenv } from "dotenv";
configDotenv();
const schema = z.object({
GITHUB_PAT: z.string().min(1),
GITHUB_USERNAME: z.string().min(1),
});
const result = schema.safeParse(process.env);
if (result.success === false) {
console.error("❌ Invalid environment variables");
console.error(
result.error.errors
.map((error) => `- ${error.path.join(".")}: ${error.message}`)
.join("\n"),
);
process.exit(1);
}
export const env = result.data;

82
build/manifestPlugin.ts Normal file
View File

@@ -0,0 +1,82 @@
import { Plugin } from "vite";
import { readFile, writeFile } from "fs/promises";
import { spawnSync } from "child_process";
import { Octokit } from "@octokit/rest";
import { env } from "./env";
export const manifest = (): Plugin => ({
name: "generate-pages-plugin",
buildStart: async () => {
const octokit = new Octokit({ auth: env.GITHUB_PAT });
const { data: manifestRepo } = await octokit.repos.get({
owner: env.GITHUB_USERNAME,
repo: env.GITHUB_USERNAME,
});
try {
const storedUpdatedAt = (
await readFile("./node_modules/.cache/manifest")
).toString();
if (storedUpdatedAt === manifestRepo.updated_at) return;
} catch {}
await writeFile("./node_modules/.cache/manifest", manifestRepo.updated_at);
const getRepoFileContent = async (repo: string, path: string) => {
const { data: file } = await octokit.repos.getContent({
owner: env.GITHUB_USERNAME,
repo,
path,
});
if (Array.isArray(file) || file.type !== "file") throw new Error("");
return Buffer.from(file.content, "base64").toString("utf8");
};
const manifest = JSON.parse(
await getRepoFileContent(env.GITHUB_USERNAME, "manifest.json"),
) as {
files: string[];
projects: string[];
};
const projects: Array<{
name: string;
content: string;
language: string | null;
url: string;
private: boolean;
}> = [];
for (const project of manifest.projects) {
const { data: repo } = await octokit.repos.get({
owner: env.GITHUB_USERNAME,
repo: project,
});
const content = await getRepoFileContent(project, "README.md");
projects.push({
name: project,
content,
language: repo.language,
url: repo.url,
private: repo.private,
});
}
const code = `
const projects = ${JSON.stringify(projects, null, 2)};
const projectsMap = Object.fromEntries(projects.map(project => [project.name, project]));
export const manifest = {
projects,
projectsMap
};
`;
await writeFile("./src/manifest.ts", code);
spawnSync("prettier", ["--write", "./src/manifest.ts"]);
},
});