name: docs # Rebuild the documentation site and publish it to the `pages` branch on every # push to main that touches the docs sources. The site is generated from the # per-symbol source of truth in docs/language/** — nothing is hand-edited on the # pages branch. on: push: branches: [main] paths: - 'docs/**' - 'tools/docgen/**' - 'tools/ludic-cli/**' # the site publishes the installer, so a change to it has to redeploy the # site — otherwise a fixed install.sh sits in main while the old one is # still what `curl … | sh` fetches - 'install.sh' - '.forgejo/workflows/docs.yml' workflow_dispatch: {} # Deploying is a force-push of an orphan branch, so two runs racing can land out # of order and leave `pages` holding the older build — the site would silently # go backwards with both runs green. Serialise them, and let a newer push cancel # an older one that is still building rather than queue behind it. concurrency: group: pages-deploy cancel-in-progress: true permissions: contents: write jobs: build-and-deploy: # Match the label our Forgejo runner actually advertises. The runner is # Docker-capable (it provides the `container:` below); `ubuntu-latest` is a # GitHub-ism this runner does not register, so a job requesting it sits in # "Waiting" forever with "no online runner found matching this label". runs-on: docker # The generator is now Ludic, so this builds the toolchain from its IR seed # (clang assembles the seed into bin/ludicc, which compiles bin/ludic) exactly # like the ci workflow, then runs `ludic-dev docs-gen`. node:20-bookworm carries git # for the clone + publish; clang-16 is the only extra the bootstrap needs. container: node:20-bookworm steps: - name: Install clang-16 run: | set -eu export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq --no-install-recommends clang-16 git ca-certificates clang-16 --version | head -1 - name: Generate the documentation site env: SOURCE_REF: ${{ github.ref_name }} REPO_URL: ${{ github.server_url }}/${{ github.repository }}.git run: | set -eu git config --global --add safe.directory '*' git clone --depth 1 --branch "${SOURCE_REF:-main}" "$REPO_URL" src cd src # The toolchain is macOS-first; on this Linux runner it links against a # tiny C-free IR shim supplying the Darwin stdout/stderr globals over # glibc's, injected through LUDIC_CC. docs-gen is a pure CLI (no # windowing), so the C-free bootstrap is all it needs. export LUDIC_CC="clang-16 $(pwd)/tools/ci/linux_stdio_shim.ll -lm" export LUDIC_HOME="$(pwd)" mkdir -p bin clang-16 tools/ci/linux_stdio_shim.ll selfhost/ludicc.seed.ll -o bin/ludicc bin/ludicc tools/ludic-cli/dev.ludic -o bin/ludic-dev bin/ludic-dev docs-gen --out ../public bin/ludic-dev docs-check ../public cd .. echo "--- generated files ---" ls -la public - name: Publish to the pages branch env: PAGES_TOKEN: ${{ secrets.PAGES_TOKEN }} AUTO_TOKEN: ${{ secrets.GITHUB_TOKEN }} SOURCE_SHA: ${{ github.sha }} SERVER_URL: ${{ github.server_url }} REPO: ${{ github.repository }} run: | set -eu TOKEN="${PAGES_TOKEN:-${AUTO_TOKEN:-}}" if [ -z "$TOKEN" ]; then echo "::error::No deploy token. Add a repo secret PAGES_TOKEN (write access) or enable the automatic Actions token for pushes." exit 1 fi cd public git init -q -b pages git config user.name "ludic-docs-bot" git config user.email "docs@workshopsoft.io" git add -A git commit -q -m "docs: regenerate site from ${SOURCE_SHA}" # the same server and repository the run came from, with the token spliced in git push -f "${SERVER_URL%%://*}://ludic-docs-bot:${TOKEN}@${SERVER_URL#*://}/${REPO}.git" pages echo "published $(git rev-parse --short HEAD) to pages"