cmc/cleberg.net
My personal web garden & blog.
clone: git clone https://gitbay.org/cmc/cleberg.net.git
fab92e702d2db99b85572b8e505ce7b194de5130
unsigned
author: Christian Cleberg <hello@cleberg.net> · 2026-08-22T03:34:42Z
.github/workflows/build.yml | 77 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) new file mode 100644 @@ -0,0 +1,77 @@ +name: Build + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +env: + # orgo is installed from crates.io, so nothing bumps this automatically — + # dependabot does not see `cargo install` in a workflow. Raise it by hand when + # a new orgo lands, which is also how you find out orgo broke the site. + ORGO_VERSION: "0.22.0" + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + # Compiling orgo takes minutes; the binary only changes when the pinned + # version does, so key the cache on it. + - name: Cache orgo + id: cache-orgo + uses: actions/cache@v6 + with: + path: ~/.cargo/bin/orgo + key: orgo-${{ env.ORGO_VERSION }}-${{ runner.os }} + + - name: Install orgo + if: steps.cache-orgo.outputs.cache-hit != 'true' + run: | + cargo --version + cargo install orgo --version "$ORGO_VERSION" --locked + + - name: Show versions + run: | + orgo --version + python3 --version + + # build.py deploys with rsync when DEPLOY=true and ENV=prod. CI passes + # neither, but "we did not set the variable" is an assumption, not a + # guarantee. Shadowing rsync with a failing stub turns it into one: if the + # deploy path is ever reached from CI, the job fails loudly instead of + # quietly reaching for a production host. + - name: Block the deploy path + run: | + mkdir -p "$RUNNER_TEMP/bin" + cat > "$RUNNER_TEMP/bin/rsync" <<'EOF' + #!/usr/bin/env bash + echo "::error::rsync was invoked from CI — the deploy path must never run here" >&2 + exit 1 + EOF + chmod +x "$RUNNER_TEMP/bin/rsync" + echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH" + + # ENV=prod is deliberate. The development path in build.py runs + # `ruff check --fix` and `ruff format`, which rewrite files in place — + # CI should verify the tree, not edit it. Production is also the build + # that actually ships, including the onion image-URL rewrite. DEPLOY is + # left unset, so main() builds and stops. + - name: Build the site + env: + ENV: prod + BUILD: "true" + run: python3 build.py + + - name: Check the build produced pages + run: | + pages=$(find .build -name '*.html' | wc -l) + echo "built $pages html pages" + if [ "$pages" -lt 100 ]; then + echo "::error::only $pages pages built; expected the full site" + exit 1 + fi