Skip to content

Commit 5bd3455

Browse files
TMHSDigitalclaude
andcommitted
site: licence freshness line on the homepage, a freshness page, and a weekly rebuild
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
1 parent 89e9776 commit 5bd3455

7 files changed

Lines changed: 27 additions & 3 deletions

File tree

‎.github/workflows/pages.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ on:
99
- "site/**"
1010
- ".github/workflows/pages.yml"
1111
workflow_dispatch:
12+
# Weekly rebuild so the freshness ages never lag the calendar by more than
13+
# about a week when nothing is pushed.
14+
schedule:
15+
- cron: "17 6 * * 1"
1216

1317
permissions:
1418
contents: read

‎site/build.mjs‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { deprecationReason, MarkdownError, renderBlocks, renderInline, splitEntr
1414
import { checkPage } from "./lib/page-checks.mjs";
1515
import { checkStacks } from "./checks.mjs";
1616
import { stackPageHtml } from "./lib/stack-page.mjs";
17+
import { freshnessLineHtml, freshnessPageHtml, freshnessStats } from "./lib/freshness.mjs";
1718
import { licenceTerms, listStackFiles, owes, parseStack, pickPath } from "./lib/stacks.mjs";
1819

1920
const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -337,6 +338,7 @@ function sitemapXml(site, entries, stacks = []) {
337338
const base = site.siteUrl.replace(/\/+$/, "");
338339
const urls = [
339340
` <url><loc>${esc(base)}/</loc></url>`,
341+
` <url><loc>${esc(base)}/freshness/</loc></url>`,
340342
...stacks.map((s) => ` <url><loc>${esc(base)}/stack/${esc(s.meta.id)}/</loc><lastmod>${esc(s.meta.walked)}</lastmod></url>`),
341343
...entries.map(
342344
(e) =>
@@ -595,7 +597,9 @@ function main() {
595597
const indexPath = path.join(DIST, "index.html");
596598
const stamp = payload.generatedAt.slice(0, 10);
597599
const visible = entries.filter((e) => e.status !== "deprecated");
600+
const fresh = freshnessStats(entries, now);
598601
const substitutions = {
602+
FRESHNESS_LINE: freshnessLineHtml(fresh, stamp, "freshness/"),
599603
HEAD_META: headMetaHtml(config.site, stats, payload.generatedAt, hasCard),
600604
STACK_ROWS: stackRowsHtml(stacks),
601605
STARTER_ROWS: starterRowsHtml(featured),
@@ -620,14 +624,19 @@ function main() {
620624
fs.writeFileSync(path.join(DIST, "sitemap.xml"), sitemapXml(config.site, visible, stacks));
621625
fs.writeFileSync(path.join(DIST, "robots.txt"), robotsTxt(config.site));
622626
fs.writeFileSync(path.join(DIST, "404.html"), notFoundHtml(config.site));
627+
fs.mkdirSync(path.join(DIST, "freshness"), { recursive: true });
628+
fs.writeFileSync(
629+
path.join(DIST, "freshness", "index.html"),
630+
freshnessPageHtml({ stats: fresh, site: config.site, stamp, total: stats.total, hasCard })
631+
);
623632

624633
const pages = writeEntryPages({ entries, bodies, config, stats, stamp, hasCard, now, usedIn });
625634
const stackPages = writeStackPages({ stacks, entries, config, stats, stamp, hasCard, now });
626635
const pageErrors = [
627636
...stackErrors,
628637
...pages.errors,
629638
...stackPages.errors,
630-
...checkPages(["index.html", ...pages.written, ...stackPages.written]),
639+
...checkPages(["index.html", "freshness/index.html", ...pages.written, ...stackPages.written]),
631640
];
632641
if (pageErrors.length) {
633642
console.error(`Page build failed (${pageErrors.length}):`);
@@ -654,7 +663,7 @@ function main() {
654663
`Built ${entries.length} entries → site/dist (${stats.active} active, ${stats.commercialOk} commercial-ok, ${stats.commercialVaries} per-file)`
655664
);
656665
console.log(
657-
`Prerendered ${visible.length} entry rows into index.html; wrote ${pages.written.length} entry pages, ${stackPages.written.length} stack pages, sitemap.xml, robots.txt, 404.html`
666+
`Prerendered ${visible.length} entry rows into index.html; wrote ${pages.written.length} entry pages, ${stackPages.written.length} stack pages, sitemap.xml, robots.txt, 404.html, freshness/index.html`
658667
);
659668
if (errors.length) process.exitCode = 0; // soft-fail missing fields as warnings
660669
}

‎site/lib/entry-page.mjs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export function entryPageHtml({ entry, leadHtml, restHtml, deprecatedReasonHtml,
165165
</main>
166166
<footer class="footer">
167167
<p>Catalog metadata is CC0. Linked assets keep their own licenses: re-check the live source before shipping.</p>
168+
<p><a href="../../freshness/">Licence freshness</a></p>
168169
<p class="footer-stamp">Built ${esc(stamp)} from ${total} catalog entries.</p>
169170
</footer>
170171
${c.script ? '<script src="../../entry.js" defer></script>' : ""}

‎site/lib/lib.test.mjs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,11 @@ has("an undated row says so", fp, "no check date");
416416
has("recent section present", fp, 'id="recent"');
417417
lacks("deprecated left out of the page", fp, "Theta");
418418

419+
/* freshness: links in ------------------------------------------------------ */
420+
has("entry page footer links freshness", p, '<a href="../../freshness/">Licence freshness</a>');
421+
has("stack page footer links freshness", spage, '<a href="../../freshness/">Licence freshness</a>');
422+
has("llms points at freshness", lt, "Licence freshness, every entry by check date: https://x.test/s/freshness/");
423+
419424
/* report (keep last) ------------------------------------------------------ */
420425
if (failures.length) {
421426
console.error(`lib.test failed (${failures.length}):`);

‎site/lib/llms.mjs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/** Plain-text indexes of the catalog for AI assistants (llmstxt.org format). */
22
import { sectionMarkdown, splitEntryBody } from "./markdown.mjs";
3-
import { commercialLabel, entryPageUrl, stackPageUrl } from "./shared.mjs";
3+
import { commercialLabel, entryPageUrl, freshnessPageUrl, stackPageUrl } from "./shared.mjs";
44
import { owes } from "./stacks.mjs";
55

66
/** The first paragraph of the body before its first `##`, lines joined. */
@@ -38,6 +38,8 @@ function header(site) {
3838
> ${site.tagline}
3939
4040
A curated catalog of free game assets, libraries and tools. It holds links and licence metadata only; nothing is rehosted. Each licence was read at its source on the entry's verified date, and the entry page quotes it with dates. "needs-review" means a real question is open: read the entry's Notes before shipping. Deprecated entries are not listed.
41+
42+
Licence freshness, every entry by check date: ${freshnessPageUrl(site)}
4143
`;
4244
}
4345

‎site/lib/stack-page.mjs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ export function stackPageHtml({ stack, sections, gapsHtml, leadHtml, owed, site,
164164
</main>
165165
<footer class="footer">
166166
<p>Catalog metadata is CC0. Linked assets keep their own licenses: re-check the live source before shipping.</p>
167+
<p><a href="../../freshness/">Licence freshness</a></p>
167168
<p class="footer-stamp">Built ${esc(stamp)} from ${total} catalog entries.</p>
168169
</footer>
169170
${script}

‎site/public/index.html‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ <h1 id="hero-title">Free Game Dev Assets</h1>
4343
<a class="btn" href="#catalog">Browse catalog</a>
4444
<a class="text-link" href="#starters">Jump to safe starters</a>
4545
</p>
46+
<p class="freshness-line"><!--FRESHNESS_LINE--></p>
4647
</section>
4748

4849
<section class="section" id="stacks" aria-labelledby="stacks-title">
@@ -175,6 +176,7 @@ <h2 id="guides-title">Guides</h2>
175176
<a id="footer-repo" href="https://github.com/TMHSDigital/Free-Game-Dev-Assets">Contribute on GitHub</a>
176177
· add entries from <code>catalog/TEMPLATE.md</code>
177178
</p>
179+
<p><a href="freshness/">Licence freshness</a></p>
178180
<p class="footer-stamp"><!--FOOTER_STAMP--></p>
179181
</footer>
180182

0 commit comments

Comments
 (0)