Consolidate gateway-gamers sites, dedupe shared header/footer/images

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
This commit is contained in:
2026-09-04 14:59:06 -05:00
co-authored by Claude Sonnet 5
parent 60076ac885
commit 0ab611b6fc
60 changed files with 350 additions and 323 deletions
+33
View File
@@ -0,0 +1,33 @@
#!/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);