diff --git a/site/vendor/pages-theme/README.md b/site/vendor/pages-theme/README.md index bcadd33..9884935 100644 --- a/site/vendor/pages-theme/README.md +++ b/site/vendor/pages-theme/README.md @@ -67,7 +67,7 @@ export const collections = { docs: docsCollection() }; | `tagline` | – | A few words for the start page's `` and the OG image; see „Search engines" | | `website` | – | The project's landing page (`https://judge.casoon.de`): header, footer, JSON-LD `sameAs` | | `catalog` | repository name | Slug of the project's entry on casoon.dev (`#projekt-<slug>`), linked in the footer; `false` for none | -| `version` | – | Header badge, "Docs for vX" | +| `version` | the project's manifest | Header badge, "Docs for vX"; see „Version" | | `license` | `MIT` | SPDX id for footer and JSON-LD; `false` for proprietary code names no licence | | `branch` | `main` | "Edit this page" links | | `accent` | CASOON petrol | `{ light, dark }` project colour; needs 4.5:1 on `#f6f6f5` and `#101010` | @@ -80,6 +80,18 @@ export const collections = { docs: docsCollection() }; | `lang` | `en` | `en` or `de`: `<html lang>` and the theme's own UI strings (`lib/i18n.ts`); props passed by the project win | | `showcaseLead` | – | Lead paragraph of the showcase overview, instead of the theme's generic one | +#### Version + +Left out, `version` comes from the manifest next to `site/`: `version` in `package.json`, else +`[package]` or `[workspace.package]` in `Cargo.toml`. So the number is maintained in one place, +and a release updates the site by itself. Pages read it as `config.version` from +`virtual:casoon-pages/config` — a start page that shows the release in a `Badge` takes it from +there instead of typing it out. + +A wrong number is worse than none, so anything that cannot be read with certainty yields none: +a workspace whose version sits in a member crate, a `package.json` without `version`, a project +with neither manifest. Those pass `version` themselves, and `false` shows none at all. + ### Routes | Route | Source | @@ -222,13 +234,19 @@ in `astro.config.mjs`. `website`, the project's catalog entry on casoon.dev and the catalog itself, all with descriptive text in the page's `lang`. -`casoon.github.io` has no root repository, so there is no root `robots.txt` pointing at the -sitemaps. Register each site in Google Search Console instead, once per project: +The root `https://casoon.github.io/` comes from the repository `casoon/casoon.github.io`: an +overview of the project sites, the only `robots.txt` crawlers read for the domain (one `Sitemap:` +line per project), and the Google Search Console verification. Its URL-prefix property +`https://casoon.github.io/` covers every project site, so a project needs no property and no +verification file of its own. For a new site: + +1. Deploy it and check that `https://casoon.github.io/<repo>/sitemap.xml` answers 200. +2. In `casoon/casoon.github.io`, add `Sitemap: https://casoon.github.io/<repo>/sitemap.xml` to + `robots.txt` and the site to `index.html`, then push. +3. In the property `https://casoon.github.io/`, *Sitemaps* → submit `<repo>/sitemap.xml`. -1. *Add property* → *URL prefix* → `https://casoon.github.io/<repo>/`. -2. Verify ownership with the *HTML file* method: put the downloaded `google<id>.html` into the - project's `site/public/` and deploy; it is served at `https://casoon.github.io/<repo>/google<id>.html`. -3. *Sitemaps* → submit `sitemap.xml` (resolved against the prefix). +Never set a custom domain on `casoon/casoon.github.io`: GitHub would redirect every project site +to it as well. ## Rules the theme enforces diff --git a/site/vendor/pages-theme/SOURCE b/site/vendor/pages-theme/SOURCE index 8235137..54ba735 100644 --- a/site/vendor/pages-theme/SOURCE +++ b/site/vendor/pages-theme/SOURCE @@ -1,6 +1,6 @@ -@casoon/pages-theme 0.7.3 -source: gh-pages-template@884a602 -synced: 2026-10-24 +@casoon/pages-theme 0.8.0 +source: gh-pages-template@a03f9ef +synced: 2026-10-26 Vendored copy. Do not edit here: change the theme in gh-pages-template, then run scripts/sync-theme.sh <this repo>. diff --git a/site/vendor/pages-theme/index.ts b/site/vendor/pages-theme/index.ts index d67067f..1791212 100644 --- a/site/vendor/pages-theme/index.ts +++ b/site/vendor/pages-theme/index.ts @@ -1,4 +1,4 @@ -import { existsSync } from 'node:fs'; +import { existsSync, readFileSync } from 'node:fs'; import { writeFile } from 'node:fs/promises'; import { resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -6,6 +6,7 @@ import mdx from '@astrojs/mdx'; import type { AstroIntegration } from 'astro'; import type { Lang } from './lib/i18n'; import { renderOgImage } from './lib/og'; +import { projectVersion } from './lib/version'; export interface PackageLink { /** Label shown in the footer and as badge, e.g. "crates.io" or "npm". */ @@ -26,8 +27,9 @@ export interface CasoonPagesOptions { catalog?: string | false; /** GitHub repository as "owner/name". Omit for a private repository: no GitHub or edit links. */ repo?: string; - /** Current release, shown in the header and on docs pages. */ - version?: string; + /** Current release, shown in the header and on docs pages. + * Omitted: read from package.json or Cargo.toml next to site/. `false` shows none. */ + version?: string | false; /** SPDX licence identifier, or false for proprietary code (no licence named). Default: "MIT". */ license?: string | false; /** Default branch, used for "Edit this page" links. Default: "main". */ @@ -108,7 +110,10 @@ export default function casoonPages(options: CasoonPagesOptions): AstroIntegrati catalog: options.catalog === false ? '' : (options.catalog ?? options.repo?.split('/')[1] ?? ''), repo: options.repo ?? '', - version: options.version ?? '', + version: + options.version === false + ? '' + : (options.version ?? projectVersion(resolve(root, '..'))), license: options.license ?? 'MIT', branch: options.branch ?? 'main', accent: options.accent ?? null, @@ -162,6 +167,17 @@ export default function casoonPages(options: CasoonPagesOptions): AstroIntegrati }, }); }, + // Project pages may import the virtual modules too (`config.version` on a start page), + // so the declarations go into the project's generated types, not just the theme's. + 'astro:config:done': ({ injectTypes }) => { + injectTypes({ + filename: 'virtual.d.ts', + content: readFileSync(new URL('./virtual.d.ts', import.meta.url), 'utf8').replace( + "'./index'", + "'@casoon/pages-theme'" + ), + }); + }, // Sitemap and OG image need absolute URLs, so both depend on `site`. 'astro:build:done': async ({ dir, pages }) => { const base = site; diff --git a/site/vendor/pages-theme/lib/version.ts b/site/vendor/pages-theme/lib/version.ts new file mode 100644 index 0000000..9c919d2 --- /dev/null +++ b/site/vendor/pages-theme/lib/version.ts @@ -0,0 +1,50 @@ +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; + +/** + * The project's current release, read from the manifest next to site/ so it is never + * maintained twice. npm projects keep it in package.json, Rust projects in Cargo.toml + * (also as `[workspace.package]`, which a crate inherits with `version.workspace = true`). + * + * A wrong number on the page is worse than none: anything this cannot read with certainty + * yields '', and the project passes `version` itself. + */ +export function projectVersion(repoRoot: string): string { + return fromPackageJson(repoRoot) || fromCargoToml(repoRoot) || ''; +} + +function read(path: string): string | null { + try { + return readFileSync(path, 'utf8'); + } catch { + return null; + } +} + +function fromPackageJson(repoRoot: string): string { + const raw = read(join(repoRoot, 'package.json')); + if (raw === null) return ''; + try { + const { version } = JSON.parse(raw) as { version?: unknown }; + return typeof version === 'string' ? version : ''; + } catch { + return ''; + } +} + +function fromCargoToml(repoRoot: string): string { + const raw = read(join(repoRoot, 'Cargo.toml')); + if (raw === null) return ''; + return section(raw, 'package') || section(raw, 'workspace.package'); +} + +/** First `version = "…"` inside [<name>], stopping at the next table header. */ +function section(toml: string, name: string): string { + const start = toml.search(new RegExp(`^\\[${name.replaceAll('.', '\\.')}\\]\\s*$`, 'm')); + if (start === -1) return ''; + const rest = toml.slice(start); + const next = rest.indexOf('\n[', 1); + const body = next === -1 ? rest : rest.slice(0, next); + const match = body.match(/^version\s*=\s*"([^"]+)"/m); + return match ? match[1] : ''; +} diff --git a/site/vendor/pages-theme/package.json b/site/vendor/pages-theme/package.json index aa52ccb..1035e42 100644 --- a/site/vendor/pages-theme/package.json +++ b/site/vendor/pages-theme/package.json @@ -1,6 +1,6 @@ { "name": "@casoon/pages-theme", - "version": "0.7.3", + "version": "0.8.0", "private": true, "description": "Shared Astro theme for the GitHub Pages sites of CASOON open-source projects", "type": "module",