diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 79e7f6f..1c4d465 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -52,6 +52,29 @@ jobs: echo "No HTML files found yet (layouts not implemented). Skipping Pagefind." fi + - name: Assert CSS bundle budget (≤ 4200 B gz) + run: | + css=$(find exampleSite/public -name 'tsuki.bundle.*.css' -print -quit) + if [ -z "$css" ]; then + echo "::error::Could not locate tsuki.bundle.*.css under exampleSite/public" + exit 1 + fi + sz=$(gzip -9 -c "$css" | wc -c) + echo "tsuki bundle gz: ${sz} B (limit 4200)" + if [ "$sz" -gt 4200 ]; then + echo "::error::CSS bundle exceeds 4200 B gz budget (was ${sz} B)" + exit 1 + fi + + - name: Smoke tests (SEO + a11y + features regression guard) + run: ./scripts/smoke-tests.sh exampleSite/public + + - name: htmltest (broken internal links + HTML5 validation) + # TODO before v0.2.0 tag: pin @master to a commit SHA (supply-chain hygiene). + uses: wjdp/htmltest-action@master + with: + config: .htmltest.yml + - name: Upload artifact uses: actions/upload-pages-artifact@v5 with: diff --git a/.htmltest.yml b/.htmltest.yml new file mode 100644 index 0000000..34194ef --- /dev/null +++ b/.htmltest.yml @@ -0,0 +1,10 @@ +DirectoryPath: exampleSite/public +CheckExternal: false +IgnoreDirectoryMissingTrailingSlash: true +IgnoreInternalEmptyHash: true +IgnoreEmptyHref: false +EnforceHTML5: true +IgnoreURLs: + - "^https://giscus.app" + - "^https://github.com/" + - "^https://gohugo.io" diff --git a/scripts/smoke-tests.sh b/scripts/smoke-tests.sh new file mode 100755 index 0000000..bb6049a --- /dev/null +++ b/scripts/smoke-tests.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +# tsuki theme post-build smoke tests +# Run after hugo build of exampleSite to assert key features still emit. +# Usage: scripts/smoke-tests.sh [] +# Default : exampleSite/public + +set -euo pipefail + +public_dir="${1:-exampleSite/public}" +fail=0 + +assert() { + local label="$1" pattern="$2" file="$3" min="${4:-1}" + local count + count=$(grep -cE "$pattern" "$file" 2>/dev/null || true) + if [ "$count" -lt "$min" ]; then + echo "::error file=$file::FAIL [$label] expected ≥${min} matches of /$pattern/, got ${count}" + fail=1 + else + echo " ok [$label] ${count} match(es) in ${file##$public_dir/}" + fi +} + +[ -d "$public_dir" ] || { echo "::error::Public dir not found: $public_dir"; exit 2; } + +# Pick a known leaf post (any 2026 post will do). +post=$(find "$public_dir" -name 'index.html' -path '*/2026/*' -not -path '*/page/*' | head -1 || true) +[ -n "$post" ] || { echo "::error::No demo post HTML found under $public_dir"; exit 2; } +home="$public_dir/index.html" +[ -f "$home" ] || { echo "::error::No home HTML at $home"; exit 2; } + +echo "Smoke testing tsuki build:" +echo " home: $home" +echo " post: $post" +echo + +# SEO (Phase 3) +assert "JSON-LD on post" '