Skip to content

docs: issue #47 case study — competitor comparison, requirements register, solution plans, sub-issues #49–#63 #110

docs: issue #47 case study — competitor comparison, requirements register, solution plans, sub-issues #49–#63

docs: issue #47 case study — competitor comparison, requirements register, solution plans, sub-issues #49–#63 #110

Workflow file for this run

name: CI/CD Pipeline
on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:
inputs:
release_mode:
description: 'Manual release mode'
required: true
type: choice
default: 'instant'
options:
- instant
- changelog-pr
bump_type:
description: 'Version bump type'
required: true
type: choice
options:
- patch
- minor
- major
description:
description: 'Release description (optional)'
required: false
type: string
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: -Dwarnings
# Support both CARGO_REGISTRY_TOKEN (cargo's native env var) and CARGO_TOKEN (for backwards compatibility)
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN || secrets.CARGO_TOKEN }}
CARGO_TOKEN: ${{ secrets.CARGO_TOKEN }}
# Optional: set repository variable DOCKERHUB_IMAGE to namespace/image to publish Docker Hub releases.
DOCKERHUB_IMAGE: ${{ vars.DOCKERHUB_IMAGE }}
jobs:
# === DETECT CHANGES - determines which jobs should run ===
detect-changes:
name: Detect Changes
runs-on: ubuntu-latest
timeout-minutes: 5
if: github.event_name != 'workflow_dispatch'
outputs:
rs-changed: ${{ steps.changes.outputs.rs-changed }}
toml-changed: ${{ steps.changes.outputs.toml-changed }}
docs-changed: ${{ steps.changes.outputs.docs-changed }}
workflow-changed: ${{ steps.changes.outputs.workflow-changed }}
any-code-changed: ${{ steps.changes.outputs.any-code-changed }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install rust-script
run: cargo install rust-script
- name: Detect changes
id: changes
env:
GITHUB_EVENT_NAME: ${{ github.event_name }}
run: rust-script scripts/detect-code-changes.rs
# === CHANGELOG CHECK - only runs on PRs with code changes ===
# Docs-only PRs (./docs folder, markdown files) don't require changelog fragments
changelog:
name: Changelog Fragment Check
runs-on: ubuntu-latest
timeout-minutes: 10
needs: [detect-changes]
if: github.event_name == 'pull_request' && needs.detect-changes.outputs.any-code-changed == 'true'
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install rust-script
run: cargo install rust-script
- name: Check for changelog fragments
env:
GITHUB_BASE_REF: ${{ github.base_ref }}
run: rust-script scripts/check-changelog-fragment.rs
# === VERSION CHECK - prevents manual version modification in PRs ===
# This ensures versions are only modified by the automated release pipeline
version-check:
name: Version Modification Check
runs-on: ubuntu-latest
timeout-minutes: 5
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install rust-script
run: cargo install rust-script
- name: Check for manual version changes
env:
GITHUB_EVENT_NAME: ${{ github.event_name }}
GITHUB_HEAD_REF: ${{ github.head_ref }}
GITHUB_BASE_REF: ${{ github.base_ref }}
run: rust-script scripts/check-version-modification.rs
# === LINT AND FORMAT CHECK ===
# Lint runs independently of changelog check - it's a fast check that should always run
# See: https://github.com/link-assistant/hive-mind/pull/1024 for why this dependency was removed
lint:
name: Lint and Format Check
runs-on: ubuntu-latest
timeout-minutes: 10
needs: [detect-changes]
# Note: always() is required because detect-changes is skipped on workflow_dispatch,
# and without always(), this job would also be skipped even though its condition includes workflow_dispatch.
# See: https://github.com/actions/runner/issues/491
if: |
always() && !cancelled() && (
github.event_name == 'push' ||
github.event_name == 'workflow_dispatch' ||
needs.detect-changes.outputs.rs-changed == 'true' ||
needs.detect-changes.outputs.toml-changed == 'true' ||
needs.detect-changes.outputs.docs-changed == 'true' ||
needs.detect-changes.outputs.workflow-changed == 'true'
)
steps:
- uses: actions/checkout@v6
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Install rust-script
run: cargo install rust-script
- name: Cache cargo registry
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Check formatting
run: cargo fmt --all -- --check
- name: Reject tests in src
run: rust-script scripts/check-no-src-tests.rs
- name: Run Clippy
run: cargo clippy --all-targets --all-features
- name: Check file size limit
run: rust-script scripts/check-file-size.rs
# === TEST ===
# Test runs independently of changelog check
test:
name: Test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
timeout-minutes: 10
needs: [detect-changes, changelog]
# Run if: push event, OR changelog succeeded, OR changelog was skipped (docs-only PR)
if: always() && !cancelled() && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || needs.changelog.result == 'success' || needs.changelog.result == 'skipped')
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v6
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Setup MSVC environment
if: runner.os == 'Windows'
shell: pwsh
run: |
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
$installationPath = & $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
if (-not $installationPath) {
throw "Visual Studio with C++ tools not found"
}
$vcvars = Join-Path $installationPath "VC\Auxiliary\Build\vcvars64.bat"
if (-not (Test-Path $vcvars)) {
throw "vcvars64.bat not found at $vcvars"
}
$vcvarsEnvironment = @{}
cmd /s /c "`"$vcvars`" && set" | ForEach-Object {
if ($_ -match "^(.*?)=(.*)$") {
$name = $matches[1]
$value = $matches[2]
$vcvarsEnvironment[$name] = $value
if ($name -eq "Path") {
"$name=$value" | Out-File -FilePath $env:GITHUB_ENV -Append
$value -split ";" | Where-Object { $_ } | ForEach-Object {
$_ | Out-File -FilePath $env:GITHUB_PATH -Append
}
} elseif ($name -match "^(INCLUDE|LIB|LIBPATH|VCINSTALLDIR|VCToolsInstallDir|VCToolsVersion|VSINSTALLDIR|WindowsSdkDir|WindowsSDKVersion|UniversalCRTSdkDir|UCRTVersion)$") {
"$name=$value" | Out-File -FilePath $env:GITHUB_ENV -Append
}
}
}
$vctoolsInstallDir = $vcvarsEnvironment["VCToolsInstallDir"]
if (-not $vctoolsInstallDir) {
throw "VCToolsInstallDir was not set by vcvars64.bat"
}
$msvcLinker = Join-Path $vctoolsInstallDir "bin\Hostx64\x64\link.exe"
if (-not (Test-Path $msvcLinker)) {
throw "MSVC link.exe not found at $msvcLinker"
}
"CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER=$msvcLinker" | Out-File -FilePath $env:GITHUB_ENV -Append
- name: Configure AWS-LC CMake on Windows
if: runner.os == 'Windows'
shell: pwsh
run: |
"AWS_LC_SYS_C_STD=11" | Out-File -FilePath $env:GITHUB_ENV -Append
"CMAKE_GENERATOR=Ninja" | Out-File -FilePath $env:GITHUB_ENV -Append
- name: Cache cargo registry
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Run tests
run: cargo test --all-features --verbose
- name: Run doc tests
run: cargo test --doc --verbose
# === CODE COVERAGE ===
# Generate and upload code coverage using cargo-llvm-cov
coverage:
name: Code Coverage
runs-on: ubuntu-latest
timeout-minutes: 15
needs: [detect-changes]
if: |
always() && !cancelled() && (
github.event_name == 'push' ||
github.event_name == 'workflow_dispatch' ||
needs.detect-changes.outputs.rs-changed == 'true' ||
needs.detect-changes.outputs.toml-changed == 'true'
)
steps:
- uses: actions/checkout@v6
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- name: Cache cargo registry
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-coverage-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-coverage-
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: Generate code coverage
run: cargo llvm-cov --all-features --lcov --output-path lcov.info
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
files: lcov.info
fail_ci_if_error: false
# === BUILD ===
# Build package - only runs if lint and test pass
build:
name: Build Package
runs-on: ubuntu-latest
timeout-minutes: 10
needs: [lint, test]
if: always() && !cancelled() && needs.lint.result == 'success' && needs.test.result == 'success'
steps:
- uses: actions/checkout@v6
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install rust-script
run: cargo install rust-script
- name: Cache cargo registry
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-build-
- name: Build release
run: cargo build --release --verbose
- name: Check package
run: cargo package --list --allow-dirty
- name: Check crate package size
run: rust-script scripts/check-crate-size.rs
# === AUTO RELEASE ===
# Automatic release on push to main using changelog fragments
# This job automatically bumps version based on fragments in changelog.d/
auto-release:
name: Auto Release
needs: [lint, test, build]
# Note: always() ensures consistent behavior with other jobs that depend on jobs using always().
if: |
always() && !cancelled() &&
github.event_name == 'push' &&
github.ref == 'refs/heads/main' &&
needs.build.result == 'success'
runs-on: ubuntu-latest
timeout-minutes: 30
env:
DOCKERHUB_USERNAME: ${{ vars.DOCKERHUB_USERNAME || secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
permissions:
contents: write
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install rust-script
run: cargo install rust-script
- name: Configure git
run: rust-script scripts/git-config.rs
- name: Determine bump type from changelog fragments
id: bump_type
run: rust-script scripts/get-bump-type.rs
- name: Check if version already released or no fragments
id: check
env:
HAS_FRAGMENTS: ${{ steps.bump_type.outputs.has_fragments }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: rust-script scripts/check-release-needed.rs
- name: Collect changelog and bump version
id: version
if: steps.check.outputs.should_release == 'true' && steps.check.outputs.skip_bump != 'true'
run: |
rust-script scripts/version-and-commit.rs \
--bump-type "${{ steps.bump_type.outputs.bump_type }}"
- name: Get current version
id: current_version
if: steps.check.outputs.should_release == 'true'
run: rust-script scripts/get-version.rs
- name: Build release
if: steps.check.outputs.should_release == 'true'
run: cargo build --release
- name: Check crate package size
if: steps.check.outputs.should_release == 'true' && steps.check.outputs.crate_published != 'true'
run: rust-script scripts/check-crate-size.rs
- name: Publish to Crates.io
if: steps.check.outputs.should_release == 'true' && steps.check.outputs.crate_published != 'true'
id: publish-crate
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN || secrets.CARGO_TOKEN }}
CARGO_TOKEN: ${{ secrets.CARGO_TOKEN }}
run: rust-script scripts/publish-crate.rs
- name: Wait for Crate availability on Crates.io
if: |
steps.check.outputs.should_release == 'true' && (
steps.check.outputs.crate_published == 'true' ||
steps.publish-crate.outputs.publish_result == 'success'
)
run: rust-script scripts/wait-for-crate.rs --release-version "${{ steps.current_version.outputs.version }}"
- name: Configure Docker Hub publishing
if: |
steps.check.outputs.should_release == 'true' && (
steps.check.outputs.crate_published == 'true' ||
steps.publish-crate.outputs.publish_result == 'success'
)
id: dockerhub
run: |
disable_dockerhub() {
echo "enabled=false" >> "$GITHUB_OUTPUT"
echo "$1"
}
if [ -z "$DOCKERHUB_IMAGE" ]; then
disable_dockerhub "Docker Hub publishing disabled: DOCKERHUB_IMAGE repository variable is not set"
exit 0
fi
if [ ! -f Dockerfile ]; then
disable_dockerhub "Docker Hub publishing disabled: Dockerfile was not found at repository root"
exit 0
fi
if [ -z "$DOCKERHUB_USERNAME" ] || [ -z "$DOCKERHUB_TOKEN" ]; then
echo "::error::Docker Hub publishing requires DOCKERHUB_USERNAME and DOCKERHUB_TOKEN"
echo "Set DOCKERHUB_USERNAME as a repository variable or secret, and DOCKERHUB_TOKEN as a secret."
exit 1
fi
echo "enabled=true" >> "$GITHUB_OUTPUT"
echo "docker_hub_url=https://hub.docker.com/r/${DOCKERHUB_IMAGE}" >> "$GITHUB_OUTPUT"
- name: Log in to Docker Hub
if: steps.dockerhub.outputs.enabled == 'true'
uses: docker/login-action@v4
with:
username: ${{ env.DOCKERHUB_USERNAME }}
password: ${{ env.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
if: steps.dockerhub.outputs.enabled == 'true'
uses: docker/setup-buildx-action@v4
- name: Extract Docker metadata
if: steps.dockerhub.outputs.enabled == 'true'
id: docker-meta
uses: docker/metadata-action@v6
with:
images: ${{ env.DOCKERHUB_IMAGE }}
tags: |
type=raw,value=latest
type=raw,value=${{ steps.current_version.outputs.version }}
labels: |
org.opencontainers.image.version=${{ steps.current_version.outputs.version }}
- name: Publish Docker image to Docker Hub
if: steps.dockerhub.outputs.enabled == 'true'
uses: docker/build-push-action@v7
with:
context: .
push: true
tags: ${{ steps.docker-meta.outputs.tags }}
labels: ${{ steps.docker-meta.outputs.labels }}
- name: Create GitHub Release
if: |
steps.check.outputs.should_release == 'true' && (
steps.check.outputs.crate_published == 'true' ||
steps.publish-crate.outputs.publish_result == 'success'
)
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKER_HUB_URL: ${{ steps.dockerhub.outputs.docker_hub_url }}
run: |
# Use new_version from version-and-commit when available (tag-checked), else fall back to Cargo.toml version
RELEASE_VERSION="${{ steps.version.outputs.new_version }}"
if [ -z "$RELEASE_VERSION" ]; then
RELEASE_VERSION="${{ steps.current_version.outputs.version }}"
fi
release_args=(
--release-version "$RELEASE_VERSION"
--repository "${{ github.repository }}"
)
if [ -n "$DOCKER_HUB_URL" ]; then
release_args+=(--docker-hub-url "$DOCKER_HUB_URL")
fi
rust-script scripts/create-github-release.rs "${release_args[@]}"
# === MANUAL INSTANT RELEASE ===
# Manual release via workflow_dispatch - only after CI passes
manual-release:
name: Instant Release
needs: [lint, test, build]
# Note: always() is required to evaluate the condition when dependencies use always().
# The build job ensures lint and test passed before this job runs.
if: |
always() && !cancelled() &&
github.event_name == 'workflow_dispatch' &&
github.event.inputs.release_mode == 'instant' &&
needs.build.result == 'success'
runs-on: ubuntu-latest
timeout-minutes: 30
env:
DOCKERHUB_USERNAME: ${{ vars.DOCKERHUB_USERNAME || secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
permissions:
contents: write
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install rust-script
run: cargo install rust-script
- name: Configure git
run: rust-script scripts/git-config.rs
- name: Collect changelog fragments
run: rust-script scripts/collect-changelog.rs
- name: Version and commit
id: version
env:
BUMP_TYPE: ${{ github.event.inputs.bump_type }}
DESCRIPTION: ${{ github.event.inputs.description }}
run: rust-script scripts/version-and-commit.rs --bump-type "${{ github.event.inputs.bump_type }}" --description "${{ github.event.inputs.description }}"
- name: Build release
if: steps.version.outputs.version_committed == 'true' || steps.version.outputs.already_released == 'true'
run: cargo build --release
- name: Check crate package size
if: steps.version.outputs.version_committed == 'true' || steps.version.outputs.already_released == 'true'
run: rust-script scripts/check-crate-size.rs
- name: Publish to Crates.io
if: steps.version.outputs.version_committed == 'true' || steps.version.outputs.already_released == 'true'
id: publish-crate
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN || secrets.CARGO_TOKEN }}
CARGO_TOKEN: ${{ secrets.CARGO_TOKEN }}
run: rust-script scripts/publish-crate.rs
- name: Wait for Crate availability on Crates.io
if: |
(steps.version.outputs.version_committed == 'true' ||
steps.version.outputs.already_released == 'true') &&
steps.publish-crate.outputs.publish_result == 'success'
run: rust-script scripts/wait-for-crate.rs --release-version "${{ steps.version.outputs.new_version }}"
- name: Configure Docker Hub publishing
if: |
(steps.version.outputs.version_committed == 'true' ||
steps.version.outputs.already_released == 'true') &&
steps.publish-crate.outputs.publish_result == 'success'
id: dockerhub
run: |
disable_dockerhub() {
echo "enabled=false" >> "$GITHUB_OUTPUT"
echo "$1"
}
if [ -z "$DOCKERHUB_IMAGE" ]; then
disable_dockerhub "Docker Hub publishing disabled: DOCKERHUB_IMAGE repository variable is not set"
exit 0
fi
if [ ! -f Dockerfile ]; then
disable_dockerhub "Docker Hub publishing disabled: Dockerfile was not found at repository root"
exit 0
fi
if [ -z "$DOCKERHUB_USERNAME" ] || [ -z "$DOCKERHUB_TOKEN" ]; then
echo "::error::Docker Hub publishing requires DOCKERHUB_USERNAME and DOCKERHUB_TOKEN"
echo "Set DOCKERHUB_USERNAME as a repository variable or secret, and DOCKERHUB_TOKEN as a secret."
exit 1
fi
echo "enabled=true" >> "$GITHUB_OUTPUT"
echo "docker_hub_url=https://hub.docker.com/r/${DOCKERHUB_IMAGE}" >> "$GITHUB_OUTPUT"
- name: Log in to Docker Hub
if: steps.dockerhub.outputs.enabled == 'true'
uses: docker/login-action@v4
with:
username: ${{ env.DOCKERHUB_USERNAME }}
password: ${{ env.DOCKERHUB_TOKEN }}
- name: Set up Docker Buildx
if: steps.dockerhub.outputs.enabled == 'true'
uses: docker/setup-buildx-action@v4
- name: Extract Docker metadata
if: steps.dockerhub.outputs.enabled == 'true'
id: docker-meta
uses: docker/metadata-action@v6
with:
images: ${{ env.DOCKERHUB_IMAGE }}
tags: |
type=raw,value=latest
type=raw,value=${{ steps.version.outputs.new_version }}
labels: |
org.opencontainers.image.version=${{ steps.version.outputs.new_version }}
- name: Publish Docker image to Docker Hub
if: steps.dockerhub.outputs.enabled == 'true'
uses: docker/build-push-action@v7
with:
context: .
push: true
tags: ${{ steps.docker-meta.outputs.tags }}
labels: ${{ steps.docker-meta.outputs.labels }}
- name: Create GitHub Release
if: |
(steps.version.outputs.version_committed == 'true' ||
steps.version.outputs.already_released == 'true') &&
steps.publish-crate.outputs.publish_result == 'success'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKER_HUB_URL: ${{ steps.dockerhub.outputs.docker_hub_url }}
run: |
release_args=(
--release-version "${{ steps.version.outputs.new_version }}"
--repository "${{ github.repository }}"
)
if [ -n "$DOCKER_HUB_URL" ]; then
release_args+=(--docker-hub-url "$DOCKER_HUB_URL")
fi
rust-script scripts/create-github-release.rs "${release_args[@]}"
# === MANUAL CHANGELOG PR ===
changelog-pr:
name: Create Changelog PR
if: github.event_name == 'workflow_dispatch' && github.event.inputs.release_mode == 'changelog-pr'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install rust-script
run: cargo install rust-script
- name: Create changelog fragment
env:
BUMP_TYPE: ${{ github.event.inputs.bump_type }}
DESCRIPTION: ${{ github.event.inputs.description }}
run: rust-script scripts/create-changelog-fragment.rs --bump-type "${{ github.event.inputs.bump_type }}" --description "${{ github.event.inputs.description }}"
- name: Create Pull Request
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: 'chore: add changelog for manual ${{ github.event.inputs.bump_type }} release'
branch: changelog-manual-release-${{ github.run_id }}
delete-branch: true
title: 'chore: manual ${{ github.event.inputs.bump_type }} release'
body: |
## Manual Release Request
This PR was created by a manual workflow trigger to prepare a **${{ github.event.inputs.bump_type }}** release.
### Release Details
- **Type:** ${{ github.event.inputs.bump_type }}
- **Description:** ${{ github.event.inputs.description || 'Manual release' }}
- **Triggered by:** @${{ github.actor }}
### Next Steps
1. Review the changelog fragment in this PR
2. Merge this PR to main
3. The automated release workflow will publish to crates.io and create a GitHub release
# === DEPLOY DOCUMENTATION ===
# Deploy Rust API documentation to GitHub Pages after a successful package build.
# Keep this independent from package/GitHub release publication so the website
# still updates when the release path fails. Use the official Pages artifact
# deployment path so repositories configured with "GitHub Actions" as their
# Pages source fail this job if Pages cannot deploy.
#
# One-time setup: in the repository's Settings -> Pages, set Source to
# "GitHub Actions". Without this, the first run fails on actions/deploy-pages
# with "Get Pages site failed" / "Failed to create deployment". This cannot be
# configured from a workflow. See README.md "Deploying API documentation".
deploy-docs:
name: Deploy Rust Documentation
needs: [build]
if: |
!cancelled() &&
needs.build.result == 'success' && (
(github.event_name == 'push' && github.ref == 'refs/heads/main') ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.release_mode == 'instant')
)
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v6
with:
ref: main
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Build documentation
run: cargo doc --no-deps --all-features
- name: Configure GitHub Pages
uses: actions/configure-pages@v6
- name: Upload GitHub Pages artifact
uses: actions/upload-pages-artifact@v5
with:
path: target/doc
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5