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

4
.gitignore vendored
View File

@@ -4,7 +4,7 @@
.pnp.js
# Production
/build
/dist
# Misc
.DS_Store
@@ -29,3 +29,5 @@ yarn-error.log*
# Project
.notes
# Generated
/src/manifest.ts

View File

@@ -1,3 +1,4 @@
.env.example
.idea
pnpm-lock.yaml
dist

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"]);
},
});

View File

@@ -22,6 +22,7 @@
"devDependencies": {
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
"@esbuild-plugins/node-modules-polyfill": "^0.2.2",
"@octokit/rest": "^21.0.0",
"@types/eslint": "^8.44.7",
"@types/node": "^18.17.0",
"@types/react": "^18.2.37",
@@ -31,6 +32,7 @@
"@vitejs/plugin-react-swc": "^3.5.0",
"autoprefixer": "^10.4.14",
"clsx": "^2.1.0",
"dotenv": "^16.4.5",
"eslint": "^8.54.0",
"eslint-config-next": "^14.0.4",
"eslint-plugin-react-hooks": "^4.6.0",
@@ -46,6 +48,5 @@
},
"ct3aMetadata": {
"initVersion": "7.25.1"
},
"packageManager": "pnpm@9.1.2"
}
}

135
pnpm-lock.yaml generated
View File

@@ -36,6 +36,9 @@ importers:
'@esbuild-plugins/node-modules-polyfill':
specifier: ^0.2.2
version: 0.2.2(esbuild@0.19.12)
'@octokit/rest':
specifier: ^21.0.0
version: 21.0.0
'@types/eslint':
specifier: ^8.44.7
version: 8.56.1
@@ -63,6 +66,9 @@ importers:
clsx:
specifier: ^2.1.0
version: 2.1.0
dotenv:
specifier: ^16.4.5
version: 16.4.5
eslint:
specifier: ^8.54.0
version: 8.56.0
@@ -328,6 +334,58 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
'@octokit/auth-token@5.1.1':
resolution: {integrity: sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==}
engines: {node: '>= 18'}
'@octokit/core@6.1.2':
resolution: {integrity: sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==}
engines: {node: '>= 18'}
'@octokit/endpoint@10.1.1':
resolution: {integrity: sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==}
engines: {node: '>= 18'}
'@octokit/graphql@8.1.1':
resolution: {integrity: sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg==}
engines: {node: '>= 18'}
'@octokit/openapi-types@22.2.0':
resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==}
'@octokit/plugin-paginate-rest@11.3.3':
resolution: {integrity: sha512-o4WRoOJZlKqEEgj+i9CpcmnByvtzoUYC6I8PD2SA95M+BJ2x8h7oLcVOg9qcowWXBOdcTRsMZiwvM3EyLm9AfA==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '>=6'
'@octokit/plugin-request-log@5.3.0':
resolution: {integrity: sha512-FiGcyjdtYPlr03ExBk/0ysIlEFIFGJQAVoPPMxL19B24bVSEiZQnVGBunNtaAF1YnvE/EFoDpXmITtRnyCiypQ==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '>=6'
'@octokit/plugin-rest-endpoint-methods@13.2.4':
resolution: {integrity: sha512-gusyAVgTrPiuXOdfqOySMDztQHv6928PQ3E4dqVGEtOvRXAKRbJR4b1zQyniIT9waqaWk/UDaoJ2dyPr7Bk7Iw==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '>=6'
'@octokit/request-error@6.1.1':
resolution: {integrity: sha512-1mw1gqT3fR/WFvnoVpY/zUM2o/XkMs/2AszUUG9I69xn0JFLv6PGkPhNk5lbfvROs79wiS0bqiJNxfCZcRJJdg==}
engines: {node: '>= 18'}
'@octokit/request@9.1.1':
resolution: {integrity: sha512-pyAguc0p+f+GbQho0uNetNQMmLG1e80WjkIaqqgUkihqUp0boRU6nKItXO4VWnr+nbZiLGEyy4TeKRwqaLvYgw==}
engines: {node: '>= 18'}
'@octokit/rest@21.0.0':
resolution: {integrity: sha512-XudXXOmiIjivdjNZ+fN71NLrnDM00sxSZlhqmPR3v0dVoJwyP628tSlc12xqn8nX3N0965583RBw5GPo6r8u4Q==}
engines: {node: '>= 18'}
'@octokit/types@13.5.0':
resolution: {integrity: sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==}
'@pkgjs/parseargs@0.11.0':
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
@@ -707,6 +765,9 @@ packages:
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
before-after-hook@3.0.2:
resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==}
binary-extensions@2.2.0:
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
engines: {node: '>=8'}
@@ -846,6 +907,10 @@ packages:
resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
engines: {node: '>=6.0.0'}
dotenv@16.4.5:
resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
engines: {node: '>=12'}
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
@@ -1967,6 +2032,9 @@ packages:
undici-types@5.26.5:
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
universal-user-agent@7.0.2:
resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==}
update-browserslist-db@1.0.13:
resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
hasBin: true
@@ -2225,6 +2293,67 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.16.0
'@octokit/auth-token@5.1.1': {}
'@octokit/core@6.1.2':
dependencies:
'@octokit/auth-token': 5.1.1
'@octokit/graphql': 8.1.1
'@octokit/request': 9.1.1
'@octokit/request-error': 6.1.1
'@octokit/types': 13.5.0
before-after-hook: 3.0.2
universal-user-agent: 7.0.2
'@octokit/endpoint@10.1.1':
dependencies:
'@octokit/types': 13.5.0
universal-user-agent: 7.0.2
'@octokit/graphql@8.1.1':
dependencies:
'@octokit/request': 9.1.1
'@octokit/types': 13.5.0
universal-user-agent: 7.0.2
'@octokit/openapi-types@22.2.0': {}
'@octokit/plugin-paginate-rest@11.3.3(@octokit/core@6.1.2)':
dependencies:
'@octokit/core': 6.1.2
'@octokit/types': 13.5.0
'@octokit/plugin-request-log@5.3.0(@octokit/core@6.1.2)':
dependencies:
'@octokit/core': 6.1.2
'@octokit/plugin-rest-endpoint-methods@13.2.4(@octokit/core@6.1.2)':
dependencies:
'@octokit/core': 6.1.2
'@octokit/types': 13.5.0
'@octokit/request-error@6.1.1':
dependencies:
'@octokit/types': 13.5.0
'@octokit/request@9.1.1':
dependencies:
'@octokit/endpoint': 10.1.1
'@octokit/request-error': 6.1.1
'@octokit/types': 13.5.0
universal-user-agent: 7.0.2
'@octokit/rest@21.0.0':
dependencies:
'@octokit/core': 6.1.2
'@octokit/plugin-paginate-rest': 11.3.3(@octokit/core@6.1.2)
'@octokit/plugin-request-log': 5.3.0(@octokit/core@6.1.2)
'@octokit/plugin-rest-endpoint-methods': 13.2.4(@octokit/core@6.1.2)
'@octokit/types@13.5.0':
dependencies:
'@octokit/openapi-types': 22.2.0
'@pkgjs/parseargs@0.11.0':
optional: true
@@ -2598,6 +2727,8 @@ snapshots:
base64-js@1.5.1: {}
before-after-hook@3.0.2: {}
binary-extensions@2.2.0: {}
brace-expansion@1.1.11:
@@ -2726,6 +2857,8 @@ snapshots:
dependencies:
esutils: 2.0.3
dotenv@16.4.5: {}
eastasianwidth@0.2.0: {}
electron-to-chromium@1.4.627: {}
@@ -4033,6 +4166,8 @@ snapshots:
undici-types@5.26.5: {}
universal-user-agent@7.0.2: {}
update-browserslist-db@1.0.13(browserslist@4.22.2):
dependencies:
browserslist: 4.22.2

View File

@@ -6,5 +6,5 @@
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts", "tailwind.config.ts"]
"include": ["build", "vite.config.ts", "tailwind.config.ts"]
}

View File

@@ -4,9 +4,10 @@ import tsconfigPaths from "vite-tsconfig-paths";
import rollupNodePolyfillsPlugin from "rollup-plugin-polyfill-node";
import { NodeGlobalsPolyfillPlugin } from "@esbuild-plugins/node-globals-polyfill";
import { NodeModulesPolyfillPlugin } from "@esbuild-plugins/node-modules-polyfill";
import { manifest } from "./build/manifestPlugin";
const config = defineConfig({
plugins: [tsconfigPaths(), react(), rollupNodePolyfillsPlugin()],
plugins: [manifest(), tsconfigPaths(), react(), rollupNodePolyfillsPlugin()],
resolve: {
alias: {
events: "rollup-plugin-node-polyfills/polyfills/events",