The source of vmactions.org.
Static HTML and CSS. No build step, no generator at serve time, no npm, no
external requests at runtime -- every asset is served from this repository.
Push to main and GitHub Pages serves it.
Every page is bilingual (English / Chinese) and follows the reader's system theme, with manual switches for both.
index.html Landing page
docs/inputs.html Every `with:` input, one authoritative reference
assets/style.css The only stylesheet, shared by every page
assets/site.js Language + theme switches, copy buttons, the hero run
animation, and the docs scroll-spy
assets/data.js Generated. Feeds only the hero animation.
tools/build-data.js Generates the matrix, the cards, the counters and the
hero list from the sibling *-vm checkouts
tools/build-data.test.js Tests the conf-name parser
tools/check-contrast.js Verifies the palette against WCAG
404.html
CNAME vmactions.org
Each page also carries a small inline script in <head>. It applies the stored
theme and language before first paint -- without it a reader who chose dark gets
a white flash on every navigation. It is the only inline script.
Serve the directory over HTTP -- the pages link /assets/... with absolute
paths, so opening a file directly with file:// loses the stylesheet:
python3 -m http.server 8791Then open http://127.0.0.1:8791/.
Port 8791 rather than 8765 on purpose: 8765 is what anyvm-org.github.io uses,
and serving one site while reading the other is a confusing five minutes.
Nothing about the coverage of this project is typed in by hand. The matrix, the
system cards, the three counters and the hero's run list are generated by
tools/build-data.js, which reads the *-vm checkouts sitting next to this
repository:
| Source | Yields |
|---|---|
conf/*.conf filenames |
which releases exist, and the arch of each |
conf/default.release.conf |
the default release |
.github/data/sync-map.json |
sync methods per arch |
.github/data/datafile.ini |
display name, shell note, prepare example, upstream builder |
README.md |
the action's major version |
Run it after anything moves upstream:
node tools/build-data.jsIt rewrites the regions between <!-- BEGIN generated:NAME --> and
<!-- END generated:NAME --> in index.html, and rewrites assets/data.js.
It is idempotent: running it twice leaves the files byte-identical.
Three parsing rules exist because the conf directories are not as regular as
they look, and tools/build-data.test.js pins all three:
- Architecture comes from a whitelist, never from "whatever follows the last
dash". Without it, GhostBSD's
26.1-xfce.confand Solaris'11.4-gcc-14.confbecome architectures namedxfceand14. *-build.confis skipped -- those are build-only variants, not something a user selects withrelease:.base-vmis excluded -- it is the template the others are generated from, not a shipped action.
Release lists are deliberately not reproduced here. Each builder repository owns the authoritative list for its guest, and the cards link to it. The site states only the default release and the supported architectures.
An identity of its own; it deliberately does not reuse the anyvm.org "Coverage" system, though it borrows that repository's sourced system colours.
Colour carries exactly one meaning at a time. --pass means a run
succeeded and appears in the hero's run list and nowhere else. --debug marks
the debug-on-error path. --os-* identifies a system. Buttons, links and focus
rings stay neutral on purpose, so a coloured element always means one thing.
System colours were sampled from each project's own site or logo, never
written from memory, and the source is recorded beside every value in
assets/style.css. Two projects publish no palette at all (MidnightBSD's logo
is a plain outline, the Hurd logo is monochrome); those are marked DERIVED
and must never be presented anywhere as official.
There are two full sets of those colours, one per theme, because one set
cannot serve both grounds -- a colour picked for a white page disappears on
ink, and the reverse. The light set is each project's published value, darkened
only where the published value itself falls under 3:1 on white; the dark set is
the value lifted for the ink ground, carried over from
anyvm-org.github.io/assets/style.css. Only lightness moves between the sets.
Monospace is the utility face and carries every label, count, axis and code sample; the body face is the system UI stack. No web fonts are loaded.
The mark is a check inside an offset frame -- a run that passed, inside a machine that is not the runner. It appears inline in each page's nav and as an SVG data URI favicon.
- No external resources. No CDN, no web fonts, no remote images, no analytics. Icons are inline SVG.
- Both colour schemes, both languages. Every surface must work under light
and dark, and in English and Chinese; all text meets WCAG AA and every
non-text mark clears 3:1.
tools/check-contrast.jsreads the values straight out of the stylesheet and checks this, so the check cannot drift from what is served. - Responsive down to 375px. Wide content -- the matrix, code blocks -- scrolls
inside its own
.scroll-xcontainer; the page body never scrolls sideways. assets/site.jsis optional. It enhances; it must never be required to read or navigate a page. Without it every page is still a complete document in the default language and the system theme, including the coverage matrix. That is why the generator writes markup intoindex.htmlrather than having the page build itself fromdata.jsat runtime.- No BOM in any file. Windows PowerShell 5.1 both misreads BOM-less UTF-8 and writes a BOM back on top; use node or an editor that does neither.
Both languages live in the markup and CSS picks one:
<h2 lang="en">Coverage</h2>
<h2 lang="zh">覆盖矩阵</h2>Two rules about how, both learned the hard way:
The selectors are written [lang="zh"][lang] rather than [lang="zh"]. A
single attribute selector ties with a class, so component rules further down
the file that set display win on source order and leak the wrong language.
The doubled selector outranks them. They are also scoped to body, because
<html> carries lang too and an unscoped rule hides the whole document. Do
not "simplify" either back.
Inside a table row or a grid row, use one element containing two spans, not two elements:
<th scope="col"><span lang="en">System</span><span lang="zh">系统</span></th>Emitting <th> twice put nine header cells above eight columns. It looks
correct, because one of them is hidden -- but the table is ragged to anything
that reads structure rather than pixels.
Adding copy means adding both halves. An English node with no Chinese twin simply vanishes when the reader switches -- it does not fall back.
This site states what vmactions supports, so it goes stale the moment base-vm or a builder changes.
- Re-run
node tools/build-data.jsand commit the result. That covers the matrix, the cards, the counters and the hero list. - Hand-edit only what the generator cannot know:
docs/inputs.htmlwhenbase-vm/action.ymlgains, loses or changes an input. Bothlang="en"andlang="zh"must be written; an option showing a heading with no body is the signature of a missing half.assets/style.csswhen a new system needs a colour -- two of them, one per theme, each sampled and sourced.index.htmlwhen a new architecture needs a column label. The generator emits the column; the bilingual header text is not derivable from the repositories.
There is no CI. Before pushing:
node tools/build-data.test.js
node tools/check-contrast.js
node --check assets/site.js
node tools/build-data.js # then confirm git diff is emptyThen load both pages and confirm the language switch partitions cleanly -- every English node hidden in Chinese mode and the reverse:
const vis = l => [...document.querySelectorAll(`[lang="${l}"]`)]
.filter(e => getComputedStyle(e).display !== 'none').length;
vis('en'); vis('zh'); // one of these must be 0And check both themes at 1280px and 375px, then reload with JavaScript disabled -- both pages must stay complete and readable, matrix included.
The domain currently redirects to the GitHub organization. To serve this instead:
- Push this repository to
vmactions/vmactions.github.io. - Repoint
vmactions.orgDNS at GitHub Pages -- apexA/AAAArecords to the GitHub Pages addresses, or aCNAMEforwwwtovmactions.github.io. - Settings -> Pages: set the custom domain to
vmactions.organd enable Enforce HTTPS. - Point the organization profile README (
vmactions/.github,profile/README.md) at the site.