portgraph 0.16.1

Data structure library for directed graphs with first-level ports.
Documentation
name: Continuous integration

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
  merge_group:
    types: [checks_requested]
  workflow_dispatch: {}

env:
  CARGO_TERM_COLOR: always
  CARGO_INCREMENTAL: 0
  MIRIFLAGS: "-Zmiri-permissive-provenance" # Required due to warnings in bitvec 1.0.1

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Install stable toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy
      - uses: Swatinem/rust-cache@v2
        with:
          prefix-key: v0
      - name: Check formatting
        run: cargo fmt -- --check
      - name: Run clippy
        run: cargo clippy --all-targets --all-features -- -D warnings
      - name: Build docs
        run: cargo doc --no-deps --all-features
        env:
          RUSTDOCFLAGS: "-Dwarnings"

  miri:
    # Not required, we can ignore it for the merge queue check.
    if: github.event_name != 'merge_group'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Install latest nightly
        uses: dtolnay/rust-toolchain@nightly
        with:
          components: miri
      - uses: Swatinem/rust-cache@v2
        with:
          prefix-key: v0-nightly
      - name: Run miri
        run: cargo miri test

  benches:
    name: continuous benchmarking
    # Not required, we can ignore it for the merge queue check.
    if: github.event_name != 'merge_group'
    runs-on: ubuntu-latest
    permissions:
      checks: write
    steps:
      - uses: actions/checkout@v6
      - name: Install stable toolchain
        uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
        with:
          prefix-key: v0
      - uses: cargo-bins/cargo-binstall@main
      - name: Install cargo-codspeed
        run: cargo binstall cargo-codspeed --force
      - name: Override criterion with the CodSpeed harness
        run: cargo add --dev codspeed-criterion-compat --rename criterion
      - name: Build benchmarks
        run: cargo codspeed build --bench criterion_benches --profile bench
      - name: Run benchmarks
        uses: CodSpeedHQ/action@v4
        with:
          token: ${{ secrets.CODSPEED_TOKEN }}
          run: "cargo codspeed run --bench criterion_benches"
          mode: "instrumentation"

  tests:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        rust: [stable, beta, nightly]
        # workaround to ignore non-stable tests when running the merge queue checks
        # see: https://github.community/t/how-to-conditionally-include-exclude-items-in-matrix-eg-based-on-branch/16853/6
        isMerge:
          - ${{ github.event_name == 'merge_group' }}
        exclude:
          - rust: beta
            isMerge: true
          - rust: nightly
            isMerge: true
    name: tests (Rust ${{ matrix.rust }})
    steps:
      - uses: actions/checkout@v6
      - id: toolchain
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: ${{ matrix.rust }}
      - name: Configure default rust toolchain
        run: rustup override set ${{steps.toolchain.outputs.name}}
      - uses: Swatinem/rust-cache@v2
        with:
          prefix-key: v0-rust-${{ matrix.rust }}
      - name: Build with no features
        run: cargo test --verbose --no-default-features --no-run
      - name: Tests with no features
        run: cargo test --verbose --no-default-features
      - name: Build with all features
        run: cargo test --verbose --all-features --no-run
      - name: Tests with all features
        run: cargo test --verbose --all-features

  # Run tests on the minimum supported rust version, with minimal dependency versions
  tests-msrv:
    if: ${{ github.event_name != 'merge_group' }}
    runs-on: ubuntu-latest
    name: tests (Rust MSRV, min dependencies)
    steps:
      - uses: actions/checkout@v6
      - uses: mozilla-actions/sccache-action@v0.0.9
      - name: Install MSRV toolchain
        id: toolchain
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: "1.75"
      - name: Install nightly toolchain
        uses: dtolnay/rust-toolchain@master
        with:
          # Nightly must be installed for `cargo-minimal-versions` to work
          toolchain: "nightly"
      - name: Configure default rust toolchain
        run: rustup override set ${{steps.toolchain.outputs.name}}
      - uses: cargo-bins/cargo-binstall@main
      - name: Install cargo-minimal-versions
        run: |
          # Install older versions that still support rust 1.75
          cargo binstall cargo-hack@0.6.38 --force
          cargo binstall cargo-minimal-versions@0.1.32 --force
      - name: Pin transitive dependencies not compatible with our MSRV
        # Add new dependencies as needed if the check fails due incorrectly set minimum versions in transitive dependencies,
        # you will see a message like:
        # "package `XXX` cannot be built because it requires rustc YYY or newer, while the currently active rustc version is 1.75.0"
        run: |
          rm Cargo.lock
          cargo add -p portgraph derive_more@=2.0.1
          cargo add -p portgraph half@=2.4.1
          cargo add -p portgraph rayon-core@=1.12.1
          cargo add -p portgraph toml_datetime@=0.7.1
          cargo add -p portgraph toml_parser@=1.0.2
          cargo add -p portgraph indexmap@=2.11.4
          cargo add -p portgraph proptest@=1.8.0
          cargo add -p portgraph rmp@=0.8.14
          cargo add -p portgraph getrandom@=0.3.4
          cargo add -p portgraph tempfile@=3.24.0
          cargo add -p portgraph clap@=4.5.61
          cargo add -p portgraph clap_lex@=1.0.1
      - name: Build with no features
        run: cargo minimal-versions --direct test --verbose  --no-default-features --no-run
      - name: Tests with no features
        run: cargo minimal-versions --direct test --verbose  --no-default-features
      - name: Build with all features
        run: cargo minimal-versions --direct test --verbose  --all-features --no-run
      - name: Tests with all features
        run: cargo minimal-versions --direct test --verbose  --all-features

  rs-semver-checks:
    needs: [check]
    if: ${{ github.event_name == 'pull_request' }}
    uses: Quantinuum/hugrverse-actions/.github/workflows/rs-semver-checks.yml@main
    permissions:
      pull-requests: write
    secrets:
      # Post as @hugrbot when possible, fallback to the GitHub Actions user for fork PRs.
      GITHUB_PAT: ${{ secrets.HUGRBOT_PAT || github.token }}

  coverage:
    if: github.event_name != 'merge_group'
    needs: [tests, check]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: mozilla-actions/sccache-action@v0.0.9
      - uses: dtolnay/rust-toolchain@nightly
        with:
          components: llvm-tools-preview
      - name: Install cargo-llvm-cov
        uses: taiki-e/install-action@cargo-llvm-cov
      - name: Run tests with coverage instrumentation
        run: |
          cargo llvm-cov clean --workspace
          cargo llvm-cov --doctests
      - name: Generate coverage report
        run: cargo llvm-cov report --codecov --output-path coverage.json
      - name: Upload coverage to codecov.io
        uses: codecov/codecov-action@v6
        with:
          files: coverage.json
          name: ubuntu
          token: ${{ secrets.CODECOV_TOKEN }}