ruststream 0.7.2

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

on:
  # `latest` tracks releases. A docs change merged today describes the crate that will ship, not
  # the one a reader has installed, so it reaches the numbered versions with the release that
  # ships it.
  release:
    types: [published]
  # `main` is published as `next`, marked as unreleased on every page, so a reader of the
  # upcoming version finds its documentation before the release.
  push:
    branches: [main]
    paths:
      - "docs/**"
      - "website/**"
      - "examples/**"
  # A manual run either republishes a release from its tag (a typo fix or a broken link worth
  # publishing between releases), or, with `archive_ref`, rebuilds an older line from its archive
  # branch with the site code of the branch the run starts from.
  workflow_dispatch:
    inputs:
      ref:
        description: "Tag or ref to deploy the site from (defaults to the current branch)"
        required: false
        type: string
      version:
        description: "Minor line of an archive, such as 0.6 (with archive_ref)"
        required: false
        type: string
      archive_ref:
        description: "Archive branch holding that line's pages, such as docs/archive/v0.6"
        required: false
        type: string

permissions:
  contents: write

# Every deploy rewrites the whole gh-pages branch, so deploys run one at a time, in order. The
# queue keeps every waiting run: without it a newer run would cancel a waiting one, and a push to
# main could drop a release deploy.
concurrency:
  group: docs-deploy
  cancel-in-progress: false
  queue: max

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. An archive run builds with the site code of that branch.
          ref: ${{ inputs.ref || github.ref }}
          fetch-depth: 0

      # The archive branch holds the old line's pages, the sources they include and its sidebar;
      # it carries no site code.
      - name: Check out the archive
        if: inputs.archive_ref
        uses: actions/checkout@v7
        with:
          ref: ${{ inputs.archive_ref }}
          path: archive

      - uses: actions/setup-node@v7
        with:
          node-version: "22"
          cache: npm
          cache-dependency-path: website/package-lock.json

      - name: Install site toolchain
        working-directory: website
        run: npm ci

      - 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.
      #
      # Every version lives side by side in the gh-pages tree, so a deploy rebuilds only its own
      # directory. `latest` follows the newest release: `next`, an archive and a fix to a past
      # release leave it where it is.
      - name: Build and place the site
        env:
          TAG: ${{ github.event_name == 'release' && github.ref_name || '' }}
          EVENT: ${{ github.event_name }}
          ARCHIVE_VERSION: ${{ inputs.version }}
          ARCHIVE_REF: ${{ inputs.archive_ref }}
        run: |
          git fetch origin gh-pages
          git worktree add -B gh-pages gh-pages origin/gh-pages
          if [ "$EVENT" = "push" ]; then
            GH_PAGES_DIR=gh-pages scripts/deploy_docs.sh next
            exit 0
          fi
          if [ -n "$ARCHIVE_REF" ]; then
            if ! [[ "$ARCHIVE_VERSION" =~ ^[0-9]+\.[0-9]+$ ]]; then
              echo "An archive run needs the version of its line, such as 0.6; got '${ARCHIVE_VERSION}'"
              exit 1
            fi
            GH_PAGES_DIR=gh-pages scripts/deploy_docs.sh "$ARCHIVE_VERSION" \
              --content archive --source-ref "$ARCHIVE_REF"
            exit 0
          fi
          if [ -n "$ARCHIVE_VERSION" ]; then
            echo "version names the line of an archive and needs archive_ref"
            exit 1
          fi
          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
          newest="$(node -e '
            const versions = require("./gh-pages/versions.json");
            const release = versions.find((entry) => /^v?\d/.test(entry.version));
            console.log(release ? release.version : "");
          ')"
          alias_args=()
          if [ -z "$newest" ] || [ "$(printf '%s\n%s\n' "$version" "$newest" | sort -V | tail -1)" = "$version" ]; then
            alias_args=(--alias latest)
          fi
          GH_PAGES_DIR=gh-pages scripts/deploy_docs.sh "$version" "${alias_args[@]}"

      # Each deploy would otherwise add a commit carrying a full copy of the rendered site, and
      # the branch would grow 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. The deploy reads only
      # the branch tree (all versions live side by side in it), never the history.
      - name: Squash gh-pages history and push
        working-directory: gh-pages
        run: |
          git add -A
          git reset --hard "$(git commit-tree -m 'docs: deploy' "$(git write-tree)")"
          git push --force origin gh-pages