ruststream 0.7.1

Async messaging framework for Rust: broker-agnostic traits, router, codecs, and a conformance harness for broker authors.
Documentation
name: Deploy docs

on:
  # The published site tracks releases, not main. A docs change merged today describes the
  # crate that will ship, not the one a reader has installed, so publishing it immediately puts
  # instructions for unreleased API in front of everyone on the current version. Deploying from
  # the release keeps each documented version next to the code it documents; the CI workflow still
  # builds and lints every docs change on its PR, so nothing reaches main unchecked.
  release:
    types: [published]
  # The escape hatch: a typo fix or a broken link worth publishing between releases, run
  # against the tag it belongs to.
  workflow_dispatch:
    inputs:
      ref:
        description: "Tag or ref to deploy the site from (defaults to the current branch)"
        required: false
        type: string

permissions:
  contents: write

concurrency:
  group: docs-deploy
  cancel-in-progress: false

jobs:
  deploy:
    name: Deploy versioned docs
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          # On a release this is the tag; a manual run may name one, and falls back to the
          # branch it was started from.
          ref: ${{ inputs.ref || github.ref }}
          fetch-depth: 0

      - uses: actions/setup-python@v7
        with:
          python-version: "3.12"

      - name: Install docs toolchain
        run: pip install -r docs/requirements.txt

      - name: Configure git
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

      # The site is versioned by the crate's minor line, read from the manifest at the deployed
      # ref. On a release that ref is the tag, so the two must agree: a tag deployed against a
      # manifest still on the previous version would publish the new docs under the old number,
      # and `latest` would point at a version nobody released.
      - name: Deploy with mike
        env:
          TAG: ${{ github.event_name == 'release' && github.ref_name || '' }}
        run: |
          version="$(sed -nE 's/^version = "([0-9]+)\.([0-9]+).*/\1.\2/p' Cargo.toml | head -1)"
          if [ -n "$TAG" ] && [ "${TAG#v}" != "$(sed -nE 's/^version = "([^"]+)".*/\1/p' Cargo.toml | head -1)" ]; then
            echo "Tag '${TAG}' does not match the manifest version; refusing to publish docs"
            exit 1
          fi
          mike deploy --update-aliases "$version" latest
          mike set-default latest

      # mike records every deploy as a new commit on gh-pages, and each commit carries a full
      # copy of the rendered site, so the branch grows without bound (GitHub keeps the whole
      # history). Serving only needs the latest tree: rewrite the branch to a single commit
      # holding the current site and force-push, the same fix faststream applies to its docs
      # pipeline. mike itself only reads the branch tree (all deployed versions live side by
      # side in it), never the history, so squashing is invisible to the next deploy.
      - name: Squash gh-pages history and push
        run: |
          git checkout gh-pages
          # The llms.txt convention looks for the file at the site root, which mike leaves to the
          # version directories, so the root carries a copy of the latest one.
          cp latest/llms.txt llms.txt
          git add llms.txt
          git reset --hard "$(git commit-tree -m 'docs: deploy' "$(git write-tree)")"
          git push --force origin gh-pages