8 Commits
Author SHA1 Message Date
tiennm99 aee74d315d build(deps): bump actions/checkout from 6 to 7 2026-07-17 18:00:02 +07:00
tiennm99 d0f617d919 fix(ci): correct subpath URL emit + build into public/tsuki for htmltest
Run 25919953710 still failed htmltest on both Hugo legs. Two distinct
issues, both pre-existing latent bugs that v0.3.0 made impossible to
ignore:

1. Several theme templates piped paths with a leading slash through
   `relURL`, which in Hugo means "this is already absolute — leave it
   alone." The intended subpath prefix (`/tsuki/`) was therefore never
   added, producing hrefs like `href="/search/"` and `href="/"`. In
   production the GitHub Pages mount masked this (broken links from
   the page's perspective still happened to resolve under the repo
   path most of the time), but htmltest correctly reported them as
   broken. Fix by either:
   - using `site.Home.RelPermalink` for the home link, or
   - piping a string without a leading slash through `relLangURL`
     (so Hugo prepends the baseURL path), or
   - stripping the leading slash from data-driven URLs first via
     `strings.TrimPrefix "/"` and then `relLangURL`.

   Affected: header.html, search-button.html, recent-posts.html,
   home/hero.html, nav.html, 404.html, search/list.html (Pagefind UI
   asset URLs).

2. htmltest has no URL-rewriting feature (the `URLSwap` config in the
   prior `d30f50f` "fix" was never read by htmltest — confirmed by
   reading htmltest 0.17.0 source). The only clean way to make
   internal-link checking work with a `/repo/`-style baseURL is to
   mirror the URL structure on disk. CI now builds with
   `hugo --destination public/tsuki`, runs Pagefind/smoke/htmltest
   against that path, and uploads `exampleSite/public/tsuki/` as the
   Pages artifact. The artifact contents become the served site
   under `/tsuki/`, identical to the prior behaviour from the
   browser's point of view. `.htmltest.yml` drops the dead URLSwap
   block.

Also: `tmp/` (htmltest's runtime cache) added to .gitignore so local
runs don't dirty the working tree.

Local verification: 32 smoke checks green; htmltest reports
`✔✔✔ passed, tested 29 documents` against the subpath build.
2026-05-15 20:31:00 +07:00
tiennm99 fdc91dbc8b test: expand smoke suite to 32 checks + Hugo CI matrix
scripts/smoke-tests.sh:
- Per-kind CSS budget (home/post/list/archives/search), each ≤ 4200 B gz
- theme-color light/dark meta tags
- aria-pressed SSR on theme-toggle
- breadcrumbs nav + BreadcrumbList JSON-LD presence on post,
  absence on home
- prev/next nav + rel=prev attribute
- linkToSection aria-label on heading anchors
- Speculation Rules absent by default
- llm.txt artifact present
- Pagefind UI preload-swap pattern on /search/
- Giscus preconnect gating (absent when comments disabled)
- Per-kind CSS bundle routing (home loads home.css but not single.css;
  post loads single.css but not home.css)
- code-copy.js gating (post loads it, home does not)

.github/workflows/pages.yml:
- Build matrix on Hugo 0.146.0 (theme.toml floor) + 0.154.0 (current).
  Smoke + htmltest run on both. Artifact upload + deploy gated on
  the current version only.
- Drop the redundant standalone CSS-budget step; smoke-tests.sh now
  enforces per-kind budgets.
2026-05-15 18:55:59 +07:00
tiennm99 1eafaefff8 fix: post-v0.2.0 review P1s + CI hygiene (v0.2.1)
Security:
- render-link: drop `| safeHTML` on .Text (self-XSS surface w/ Goldmark unsafe:true)
- projects.html: safeURL + noreferrer + target=_blank on repo/demo
- comments: require repo+repoId+categoryId in gate (prevent broken Giscus iframe)
- htmltest-action: pin to commit SHA 31be84a (supply-chain)

Fixed:
- seo.html: nil-safe \$authorURL chain (no nil.url template error)
- nav.html: relURL on Menu.URL (sub-path deploy correctness)
- pages.yml: drop dead if-find Pagefind guard
2026-05-10 03:04:58 +07:00
tiennm99 944a6c8e1b ci: htmltest smoke tests and build validation
Add htmltest configuration, smoke test script, CSS budget assertion in CI
pipeline for quality gates.
2026-05-09 09:32:40 +07:00
tiennm99 4f17588f19 feat: core layouts and partials (Phase 3)
- baseof.html with named blocks (head_extra, body_class, main, scripts)
- single.html with data-pagefind-body wrapper
- list.html using post-card partial
- home.html placeholder (Phase 4 fills hero/projects/recent-posts)
- 404.html with vi i18n
- _partials: head (full meta + OG + Twitter Card + RSS autodiscovery + theme-flash script), header, nav, footer, meta, post-card, icon
- Sample post fixture in exampleSite to validate render

ci: bump GitHub Actions to Node 24-compatible versions

- actions/checkout v4 → v6
- actions/setup-node v4 → v6, node 20 → 22
- actions/upload-pages-artifact v3 → v5
- actions/deploy-pages v4 → v5
2026-05-07 20:45:31 +07:00
tiennm99 05d71218dc ci: skip Pagefind step when no HTML pages exist yet 2026-05-07 20:29:33 +07:00
tiennm99 afc5d25885 feat: initial theme scaffold
- Repo metadata: theme.toml, README, Apache-2.0 license
- Hugo defaults: vi language, post permalinks, taxonomies, paginate, TOC config
- exampleSite skeleton with themesDir wiring
- CI: Hugo build + Pagefind index + Pages deploy
- Pagefind devDependency in package.json (Dependabot weekly)
- vi i18n strings, default archetype
- Empty layouts/_partials/_markup/_shortcodes directories ready for Phase 3
2026-05-07 20:27:07 +07:00