Repository navigation
ci(docs): build & deploy Astro docs to gh-pages with PR previews #160
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Docs | |
| # Deploy the Astro docs site at `docs/` to GitHub Pages. | |
| # | |
| # Behaviour: | |
| # - Push to `main` → build with PPVM_BASE=/ and publish | |
| # to the gh-pages branch root. | |
| # - Pull request (opened / → build with PPVM_BASE=/pr-preview/pr-<N> | |
| # synchronize / reopened) and let rossjrw/pr-preview-action publish | |
| # the build to gh-pages under | |
| # `pr-preview/pr-<N>/`. Triggered only when | |
| # the diff actually touches inputs the | |
| # site depends on. | |
| # - Pull request closed → cleanup-preview job removes the | |
| # `pr-preview/pr-<N>/` subdirectory. | |
| # | |
| # The Rust API site under `/rust-api/` is published by `rust-docs.yml` | |
| # and survives our deploys via `keep_files: true`. | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| paths: | |
| # Site sources. Other paths (crates/, ppvm-python/) don't affect | |
| # the build because the API JSON consumed by /api/ is committed | |
| # under docs/src/data/ and regenerated manually. | |
| - "docs/**" | |
| - ".github/workflows/docs.yml" | |
| pull_request_target: | |
| types: [closed] | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| concurrency: | |
| # Serialise per-PR (and main); a fresh build cancels any in-flight one | |
| # for the same ref so PR comments don't pile up on rapid pushes. | |
| group: docs-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build: | |
| # Build the static site once, upload it as an artifact, and let the | |
| # downstream jobs decide where (if anywhere) to publish it. | |
| if: github.event.action != 'closed' | |
| name: Build Astro site | |
| runs-on: ubuntu-latest | |
| outputs: | |
| base: ${{ steps.compute-base.outputs.base }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # Build inputs: nightly Rust for the rustdoc-JSON extractor, | |
| # uv to run griffe for the Python extractor, Node 20 for Astro. | |
| - uses: dtolnay/rust-toolchain@nightly | |
| - uses: Swatinem/rust-cache@v2 | |
| - uses: astral-sh/setup-uv@v5 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "npm" | |
| cache-dependency-path: docs/package-lock.json | |
| - name: Install Astro deps | |
| # `npm ci` is faster than `npm install` and asserts the | |
| # lockfile is in sync; it fails loudly if package.json and | |
| # package-lock.json have drifted. | |
| run: npm ci | |
| working-directory: docs | |
| - name: Compute base path | |
| id: compute-base | |
| run: | | |
| if [[ "${{ github.event_name }}" == "pull_request" ]]; then | |
| echo "base=/pr-preview/pr-${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "base=/" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Generate API JSON | |
| # The /api/ page reads docs/src/data/{rust,python}-api.json, | |
| # which are .gitignore'd and produced by docs/scripts/. The | |
| # Rust extractor needs nightly for `--output-format json`; | |
| # the Python extractor uses griffe via `uv run --with griffe`. | |
| working-directory: docs | |
| env: | |
| RUSTFLAGS: "-C target-feature=+aes,+sse2" | |
| run: | | |
| node scripts/extract-rust.mjs | |
| node scripts/extract-python.mjs | |
| - name: Build site | |
| working-directory: docs | |
| env: | |
| PPVM_SITE: https://congenial-bassoon-l436wp3.pages.github.io | |
| PPVM_BASE: ${{ steps.compute-base.outputs.base }} | |
| run: npx astro build | |
| - name: Upload built site | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: docs-dist | |
| path: docs/dist/ | |
| if-no-files-found: error | |
| retention-days: 7 | |
| deploy-main: | |
| name: Deploy to gh-pages | |
| needs: build | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: deploy-gh-pages | |
| cancel-in-progress: false | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: docs-dist | |
| path: docs/dist/ | |
| - name: Publish to gh-pages root | |
| uses: peaceiris/actions-gh-pages@v3 | |
| with: | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| publish_dir: ./docs/dist | |
| # Preserve /rust-api/ (managed by rust-docs.yml) and | |
| # /pr-preview/* (managed by pr-preview-action below). | |
| keep_files: true | |
| commit_message: "docs: deploy ${{ github.sha }}" | |
| deploy-preview: | |
| name: Deploy PR preview | |
| needs: build | |
| if: github.event_name == 'pull_request' && github.event.action != 'closed' | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: deploy-gh-pages | |
| cancel-in-progress: false | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: docs-dist | |
| path: docs/dist/ | |
| - name: Deploy PR preview to gh-pages/pr-preview/pr-<N> | |
| uses: rossjrw/pr-preview-action@v1 | |
| with: | |
| source-dir: docs/dist/ | |
| preview-branch: gh-pages | |
| umbrella-dir: pr-preview | |
| cleanup-preview: | |
| name: Clean up PR preview | |
| if: github.event_name == 'pull_request_target' && github.event.action == 'closed' | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: deploy-gh-pages | |
| cancel-in-progress: false | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: rossjrw/pr-preview-action@v1 | |
| with: | |
| source-dir: docs/dist/ | |
| preview-branch: gh-pages | |
| umbrella-dir: pr-preview | |
| action: remove |