diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b109aa4 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,31 @@ +name: CI + +# The `gate` job's `run:` steps are also the AFK factory's gate (.sandcastle/run-gate.ts), +# run in the sandcastle-agent image, which has Python 3.11. Keep build.py runnable on 3.11. + +on: + pull_request: + push: + branches: [main] + +jobs: + gate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: Build the site + run: python3 build.py + - name: Built pages match their sources + run: | + changed="$(git status --porcelain)" + if [ -n "$changed" ]; then + echo "python3 build.py changed files; run it and commit the result:" + echo "$changed" + git diff + exit 1 + fi + - name: install.sh parses + run: sh -n install.sh diff --git a/CLAUDE.md b/CLAUDE.md index dab531c..84bf21a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -25,9 +25,9 @@ labelled `wayfinder:*` are skipped (`.sandcastle/ready-issues.ts`). A human merg **The gate reads its steps from CI.** The gate is the `run:` steps of the `gate` job (else the `checks` job) of `.github/workflows/ci.yml` **on `main`**, in order. If there is no `ci.yml`, no such job, or no runnable step, the gate runs nothing and logs that loudly. -Today this repo has no `.github/workflows/ci.yml`, so the gate runs nothing and the -review is the only check. Adding a `ci.yml` with a job named `gate` (or `checks`) makes the -factory gate on it with no further change. +Today the gate is the `gate` job of `.github/workflows/ci.yml`: `python3 build.py`, then a +check that the built pages match their sources, then `sh -n install.sh`. It runs in the +sandbox image's Python 3.11, so `build.py` must stay runnable on 3.11. The rule lives in one place, `gateFromCi` in `.sandcastle/run-gate.ts`, tested by `.sandcastle/run-gate.test.ts`. diff --git a/build.py b/build.py index 1c45ed2..f1a9819 100644 --- a/build.py +++ b/build.py @@ -154,9 +154,10 @@ def head(title, description, root): def nav_groups(active, wrapper_class): out = [] + active_attr = ' class="active"' for section, pages in NAV: links = "\n".join( - f' {html.escape(title)}' + f' {html.escape(title)}' for slug, title, _ in pages) out.append(f'
\n

{html.escape(section)}

\n{links}\n
') return "\n".join(out)