Skip to content

ci: add lint & checks workflow for pull requests#2

Merged
wittfabian merged 1 commit into
mainfrom
ci/pr-lint
Jun 28, 2026
Merged

ci: add lint & checks workflow for pull requests#2
wittfabian merged 1 commit into
mainfrom
ci/pr-lint

Conversation

@wittfabian

Copy link
Copy Markdown
Owner

A small, zero-footprint CI for pull requests (and pushes to main). No package.json/lockfile is committed — linters are fetched on the fly, configs live under .github/ so the repo root stays clean.

Checks (.github/workflows/ci.yml)

Step What it catches
htmlhint Malformed markup, duplicate IDs, unclosed tags, unquoted attrs
eslint (standalone .js + inline <script> via eslint-plugin-html) Undefined refs, dupe keys, assignment-in-condition, bad typeof, unreachable code
link & asset check Every internal href/src/<meta> image must resolve to a real file — with exact case (Pages is case-sensitive)
SW version guard (PRs only) A cached CORE file changed but VERSION in service-worker.js wasn't bumped → the stale-cache trap DEPLOY.md warns about

ESLint is deliberately rule-light: it enforces no style, so the exhibits' intentionally dense vanilla JS passes — it only flags real bugs. All steps use if: always() so a PR surfaces every failure at once.

Decisions worth a sanity-check

  • Zero-footprint (your pick): tools via pinned npx / npm install --no-save, nothing committed. Trade-off — versions live in the workflow, not lockfile-reproducible. A .gitignore keeps node_modules/package-lock.json out if you lint locally.
  • No Prettier / formatter. It would fight the hand-tuned dense style and produce enormous diffs. Lint-for-correctness only.
  • GitHub Actions pinned to @v4 tags (not SHAs) — fine for a personal site; can SHA-pin if you prefer.

Verification (locally, before pushing)

  • All four checks pass against the current tree (htmlhint 10 files, eslint clean, links resolve, guard: no bump needed).
  • Negative probes confirm each check actually bites: eslint flags a bad inline <script>; link check flags a missing path and a wrong-case favicon.SVG; the SW guard fails on a CORE edit without a bump.
  • This PR opening runs the workflow on itself — see the checks below for the real-environment result.

Small, zero-footprint CI (no package.json / lockfile committed; tools are
fetched on the fly) that runs on PRs and pushes to main:

- HTML lint via htmlhint (.github/linters/.htmlhintrc)
- ESLint over the standalone scripts AND the inline <script> blocks in
  each world (eslint-plugin-html). High-signal rules only — no style
  enforcement, so the exhibits' intentionally dense code passes while
  real mistakes (undef refs, dupe keys, assignment-in-condition,
  bad typeof, unreachable code) are caught.
- Internal link & asset check: every href/src/<meta> image in the HTML
  must resolve to a real file, with exact case (GitHub Pages is
  case-sensitive). Ignores script/style so JS-built URLs aren't flagged.
- Service-worker version guard (PRs only): fails if a cached CORE file
  changed but VERSION in service-worker.js wasn't bumped — the exact
  stale-cache trap DEPLOY.md warns about.

All steps use if: always() so a PR surfaces every failure at once.
Verified locally against the current tree: all four checks pass, and
negative probes confirm each check actually catches its target.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@wittfabian
wittfabian merged commit 8595f6a into main Jun 28, 2026
1 check passed
@wittfabian
wittfabian deleted the ci/pr-lint branch June 28, 2026 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant