quiver-dsp 0.1.0

A modular audio synthesis library using Arrow-style combinators and graph-based patching
Documentation
name: Documentation

on:
  push:
    branches: [main, master]
    paths:
      - 'docs/**'
      - 'src/**'
      - 'Cargo.toml'
  pull_request:
    paths:
      - 'docs/**'
      - 'src/**'
  workflow_dispatch:

# Cancel outdated runs for the same branch/PR
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always

jobs:
  # Build both doc types in parallel
  build:
    name: Build Documentation
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Setup Rust for rustdoc
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2

      # Install mdBook tools
      - name: Install mdBook
        uses: peaceiris/actions-mdbook@v2
        with:
          mdbook-version: 'latest'

      - name: Cache mdbook-mermaid
        id: cache-mermaid
        uses: actions/cache@v4
        with:
          path: ~/.cargo/bin/mdbook-mermaid
          key: mdbook-mermaid-${{ runner.os }}

      - name: Install mdbook-mermaid
        if: steps.cache-mermaid.outputs.cache-hit != 'true'
        run: cargo install mdbook-mermaid

      - name: Setup mdbook-mermaid
        run: mdbook-mermaid install docs/

      # Build both doc types in parallel
      - name: Build documentation
        run: |
          # Build mdBook and rustdoc in parallel. A bare `wait` returns 0
          # regardless of child exit status, so capture each PID and wait on it
          # individually; under `set -e` a nonzero child then fails the step.
          mdbook build docs/ &
          mdbook_pid=$!
          cargo doc --no-deps --all-features &
          cargo_doc_pid=$!
          wait "$mdbook_pid"
          wait "$cargo_doc_pid"
        env:
          # Match ci.yml's doc job. Do NOT set `--cfg docsrs` here: on the stable
          # toolchain that enables the nightly-only `feature(doc_cfg)` and fails
          # with E0554. docs.rs sets docsrs itself on nightly via
          # [package.metadata.docs.rs] in Cargo.toml.
          RUSTDOCFLAGS: -D warnings

      # Combine into single site structure
      - name: Prepare site
        run: |
          mkdir -p site
          cp -r docs/book/* site/
          cp -r target/doc site/api

      - name: Upload site artifact
        uses: actions/upload-artifact@v4
        with:
          name: site
          path: site/

  # Validate documentation quality
  validate:
    name: Validate Documentation
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Download site
        uses: actions/download-artifact@v4
        with:
          name: site
          path: site/

      - name: Validate documentation structure
        run: |
          echo "Checking documentation structure..."

          # Check mdBook files
          html_count=$(find site -name "*.html" -not -path "site/api/*" | wc -l)
          echo "mdBook: $html_count HTML files"
          if [ "$html_count" -lt 20 ]; then
            echo "Error: Expected at least 20 mdBook HTML files, found $html_count"
            exit 1
          fi

          # Check rustdoc files
          api_count=$(find site/api -name "*.html" 2>/dev/null | wc -l)
          echo "Rustdoc: $api_count HTML files"
          if [ "$api_count" -lt 10 ]; then
            echo "Error: Expected at least 10 rustdoc HTML files, found $api_count"
            exit 1
          fi

          # Check for index files
          [ -f "site/index.html" ] || { echo "Missing site/index.html"; exit 1; }
          [ -f "site/api/quiver/index.html" ] || { echo "Missing API index"; exit 1; }

          echo "Documentation validation passed!"

  # Deploy to GitHub Pages (main branch only)
  deploy:
    name: Deploy to GitHub Pages
    needs: [build, validate]
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
    permissions:
      pages: write
      id-token: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Download site
        uses: actions/download-artifact@v4
        with:
          name: site
          path: site/

      - name: Setup Pages
        uses: actions/configure-pages@v4

      - name: Upload to Pages
        uses: actions/upload-pages-artifact@v3
        with:
          path: site/

      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4