Merge the four independent gateway-gamers.net site repos (40k-rankings, aos-rankings, kingmaker, scouting) into one monorepo under sites/, preserving each site's full commit history via a manual subtree-style merge (git-subtree isn't available in this environment). - shared/: header.template.html (nav swapped in per site), footer.html, and images/ — previously byte-identical copies duplicated 4x (~100MB). - Each site's public/footer.html and public/images are now symlinks into shared/; public/header.html is generated at predev/prebuild time from shared/header.template.html + the site's own nav.html, so nav bars stay individual while everything else about the header is shared. - Single root .gitlab-ci.yml with path-scoped build/deploy jobs per site plus a deploy:shared job, replacing the 4 separate per-repo pipelines. - nginx confs (kept per-site as reference, same as before) gain location /images/ and location = /footer.html alias blocks pointing at a shared webserver directory, so the deployed site no longer duplicates the images either — see README.md for the full layout and the runbook for applying this on the webserver. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SBzcNkW7JcYipnAX6HfgmK
34 lines
1.2 KiB
JavaScript
34 lines
1.2 KiB
JavaScript
#!/usr/bin/env node
|
|
// Assembles sites/<site>/public/header.html from shared/header.template.html
|
|
// + sites/<site>/nav.html. Run automatically via each site's predev/prebuild.
|
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
import { fileURLToPath } from 'node:url';
|
|
import path from 'node:path';
|
|
|
|
const site = process.argv[2];
|
|
if (!site) {
|
|
console.error('usage: render-header.mjs <site>');
|
|
process.exit(1);
|
|
}
|
|
|
|
const root = path.resolve(fileURLToPath(import.meta.url), '../..');
|
|
const templatePath = path.join(root, 'shared/header.template.html');
|
|
const navPath = path.join(root, 'sites', site, 'nav.html');
|
|
const outPath = path.join(root, 'sites', site, 'public/header.html');
|
|
|
|
const template = readFileSync(templatePath, 'utf8');
|
|
const nav = readFileSync(navPath, 'utf8').trimEnd();
|
|
|
|
const placeholder = '<!--NAV_ITEMS-->';
|
|
const parts = template.split(placeholder);
|
|
if (parts.length !== 3) {
|
|
console.error(`expected exactly 2 occurrences of ${placeholder} in ${templatePath}, found ${parts.length - 1}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
const indent = (block, spaces) =>
|
|
block.split('\n').map(line => ' '.repeat(spaces) + line).join('\n');
|
|
|
|
const rendered = parts[0] + indent(nav, 8) + parts[1] + indent(nav, 10) + parts[2];
|
|
writeFileSync(outPath, rendered);
|