structured-proxy 4.1.0

Universal gRPC→REST transcoding proxy — config-driven, works with any gRPC service
Documentation
name: CI

permissions:
  contents: read

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch:

env:
  CARGO_TERM_COLOR: always
  RUSTFLAGS: "-Dwarnings"

jobs:
  quality-checks:
    name: Quality Checks (${{ matrix.backend.name }})
    runs-on: ubuntu-latest
    services:
      # Shared store for the rate-limit cross-instance reconciliation test.
      redis:
        image: redis:7
        ports:
          - 6379:6379
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    strategy:
      fail-fast: false
      matrix:
        backend:
          # One leg per crypto backend, plus the build that links both: Cargo
          # features are additive, so feature unification (and every tool that
          # reaches for `--all-features`, docs.rs and cargo-semver-checks
          # included) can produce that combination.
          - name: rust_crypto
            # Pure-Rust default backend (RustCrypto / rsa).
            flags: "--features redis"
          - name: aws_lc_rs
            # Opt-in constant-time backend (aws-lc, C FFI); disables the default.
            flags: "--no-default-features --features aws_lc_rs,redis"
          - name: injected_verifier
            # No built-in verifier at all: the build a consumer takes when it
            # injects its own `hooks::TokenVerifier`. Links no JWT crypto (and
            # so no `rsa`), which is only true as long as nothing outside the
            # `builtin_jwt` gate reaches for jsonwebtoken — this leg is what
            # keeps that honest.
            flags: "--no-default-features --features redis"
          - name: all_features
            # Both backends at once, the build cargo-semver-checks and docs.rs
            # take. `aws_lc_rs` wins the tie; this leg keeps that wiring honest.
            flags: "--all-features"
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
          persist-credentials: false
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy, rustfmt
      # Third-party action: pinned to a commit SHA (dependabot keeps it fresh).
      - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
      # Runs each test in its own process, so a hang names the test that hung
      # instead of timing the whole job out. Third-party action: pinned to a
      # commit SHA (dependabot keeps it fresh).
      - uses: taiki-e/install-action@94c31af3204a9f15ab40b35ad084410b905bbc73 # v2
        with:
          tool: cargo-nextest

      - name: Format
        if: matrix.backend.name == 'rust_crypto'
        run: cargo fmt --all -- --check

      - name: Clippy
        run: cargo clippy --all-targets ${{ matrix.backend.flags }}

      - name: Build
        run: cargo build --release ${{ matrix.backend.flags }}

      - name: Test
        env:
          # Exercises the rate-limit reconciliation against the Redis service.
          SHIELD_REDIS_TEST_URL: redis://127.0.0.1:6379/
        run: cargo nextest run ${{ matrix.backend.flags }}

      # nextest does not run doctests; cargo does.
      - name: Doc tests
        run: cargo test --doc ${{ matrix.backend.flags }}

      - name: Publish dry-run
        if: matrix.backend.name == 'rust_crypto'
        run: cargo publish --dry-run

  security-audit:
    name: Security Audit
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          persist-credentials: false
      # Scans Cargo.lock for RustSec advisories; honors the ignore list in
      # deny.toml. Third-party action: pinned to a commit SHA (dependabot
      # keeps it fresh).
      - uses: EmbarkStudios/cargo-deny-action@3c6349835b2b7b196a839186cb8b78e02f7b5f25 # v2.1.1
        with:
          command: check advisories