zenwave 0.4.0

Ergonomic HTTP client framework.
Documentation
name: CI

permissions:
  contents: read
  id-token: write
  checks: write

on:
  push:
    branches: ["**"]
  pull_request:
    branches: ["**"]

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always

jobs:
  fmt:
    name: Format
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@nightly
        with:
          components: rustfmt
      - run: cargo fmt --all -- --check

  clippy:
    name: Clippy (${{ matrix.name }})
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: Linux
            os: ubuntu-latest
            features: "--all-features"
            targets: "--all-targets"
          - name: macOS + Apple backend
            os: macos-latest
            features: "--no-default-features --features apple-backend"
            targets: ""
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@nightly
        with:
          components: clippy
      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: clippy-${{ matrix.name }}
      - run: cargo clippy ${{ matrix.targets }} ${{ matrix.features }} -- -D warnings

  wasm:
    name: WASM
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@nightly
        with:
          targets: wasm32-unknown-unknown
      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: ci-ubuntu
      - run: cargo build --target wasm32-unknown-unknown

  mobile:
    name: Mobile (${{ matrix.name }})
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: iOS device
            os: macos-latest
            target: aarch64-apple-ios
            features: apple-backend
            android-api: ""
            android-clang-prefix: ""
            android-rust-target-env: ""
          - name: iOS simulator
            os: macos-latest
            target: aarch64-apple-ios-sim
            features: apple-backend
            android-api: ""
            android-clang-prefix: ""
            android-rust-target-env: ""
          - name: Android arm64
            os: ubuntu-latest
            target: aarch64-linux-android
            features: hyper-rustls
            android-api: "35"
            android-clang-prefix: aarch64-linux-android
            android-rust-target-env: aarch64_linux_android
          - name: Android x86_64
            os: ubuntu-latest
            target: x86_64-linux-android
            features: hyper-rustls
            android-api: "35"
            android-clang-prefix: x86_64-linux-android
            android-rust-target-env: x86_64_linux_android
          - name: Android armv7
            os: ubuntu-latest
            target: armv7-linux-androideabi
            features: hyper-rustls
            android-api: "35"
            android-clang-prefix: armv7a-linux-androideabi
            android-rust-target-env: armv7_linux_androideabi
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@nightly
        with:
          targets: ${{ matrix.target }}
      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: mobile-${{ matrix.target }}
      - name: Configure Android NDK compiler
        if: matrix.android-api != ''
        shell: bash
        run: |
          : "${ANDROID_NDK_LATEST_HOME:?ANDROID_NDK_LATEST_HOME is required on ubuntu-latest}"
          toolchain="$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin"
          cc="$toolchain/${{ matrix.android-clang-prefix }}${{ matrix.android-api }}-clang"
          cxx="$toolchain/${{ matrix.android-clang-prefix }}${{ matrix.android-api }}-clang++"
          ar="$toolchain/llvm-ar"

          test -x "$cc" || { echo "::error::Android C compiler not found: $cc"; exit 1; }
          test -x "$cxx" || { echo "::error::Android C++ compiler not found: $cxx"; exit 1; }
          test -x "$ar" || { echo "::error::Android archiver not found: $ar"; exit 1; }

          rust_target_env="${{ matrix.android-rust-target-env }}"
          cargo_target_env="$(echo "$rust_target_env" | tr '[:lower:]' '[:upper:]')"

          {
            echo "CC_${rust_target_env}=$cc"
            echo "CXX_${rust_target_env}=$cxx"
            echo "AR_${rust_target_env}=$ar"
            echo "CARGO_TARGET_${cargo_target_env}_LINKER=$cc"
          } >> "$GITHUB_ENV"
      - name: Check mobile target
        run: cargo check --target ${{ matrix.target }} --no-default-features --features ${{ matrix.features }}

  coverage:
    name: Coverage
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@nightly
        with:
          components: llvm-tools-preview
      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: ci-ubuntu
      - uses: taiki-e/install-action@cargo-llvm-cov
      - run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
      - uses: codecov/codecov-action@v4
        with:
          use_oidc: true
          fail_ci_if_error: true

  typos:
    name: Typos
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: ci-ubuntu
      - uses: crate-ci/typos@master

  audit:
      name: Security Audit
      runs-on: ubuntu-latest
      steps:
        - uses: actions/checkout@v4
        - uses: Swatinem/rust-cache@v2
          with:
            shared-key: ci-ubuntu
        - name: Generate Lockfile
          run: cargo generate-lockfile
        - uses: rustsec/audit-check@v2
          with:
            token: ${{ secrets.GITHUB_TOKEN }}

  unused-deps:
    name: Unused Dependencies
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@nightly
      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: ci-ubuntu
      - uses: taiki-e/install-action@cargo-machete
      - run: cargo machete

  feature-checks:
    name: Features
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@nightly
      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: ci-ubuntu
      # Test valid backend + TLS combinations
      - run: cargo check --no-default-features --features curl-backend
      - run: cargo check --no-default-features --features hyper-backend,native-tls
      - run: cargo check --no-default-features --features hyper-backend,rustls
      - run: cargo check --no-default-features --features hyper-backend,native-tls,ws
      - run: cargo check --no-default-features --features hyper-backend,rustls,ws

  test:
    name: Test
    uses: ./.github/workflows/test.yml