makcu 0.3.2

Rust library for controlling MAKCU USB HID interceptor devices
Documentation
name: CI

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

permissions:
  contents: write
  pull-requests: read

env:
  CARGO_TERM_COLOR: always
  CARGO_INCREMENTAL: 0
  CARGO_NET_RETRY: 10
  RUST_BACKTRACE: short
  RUSTUP_MAX_RETRIES: 10

jobs:

  check:
    name: Check (${{ matrix.features }})
    runs-on: ubuntu-latest
    strategy:
      matrix:
        features:
          - ""
          - "batch"
          - "extras"
          - "profile"
          - "mock"
          - "async"
          - "batch,extras"
          - "async,batch,extras,profile"
          - "async,batch,extras,profile,mock"
    steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable

    - name: Install libudev
      run: sudo apt-get update && sudo apt-get install -y libudev-dev

    - name: Cache dependencies
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target
        key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}

    - name: Check
      run: cargo check --all-targets --features "${{ matrix.features }}" --verbose

  build:
    name: Build (${{ matrix.os }})
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable

    - name: Install libudev (Linux)
      if: runner.os == 'Linux'
      run: sudo apt-get update && sudo apt-get install -y libudev-dev

    - name: Cache dependencies
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target
        key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}

    - name: Build
      run: cargo build --all-features --verbose

    - name: Build examples
      run: cargo build --examples --all-features --verbose

  fmt:
    name: Rustfmt
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable
      with:
        components: rustfmt
    - name: Check formatting
      run: cargo fmt --all -- --check

  clippy:
    name: Clippy
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable
      with:
        components: clippy

    - name: Install libudev
      run: sudo apt-get update && sudo apt-get install -y libudev-dev

    - name: Run clippy
      run: cargo clippy --all-targets --all-features -- -D warnings

  security_audit:
    name: Security Audit
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable

    - name: Cache cargo-audit
      uses: actions/cache@v4
      with:
        path: |
          ~/.cargo/bin/cargo-audit
          ~/.cargo/.crates.toml
          ~/.cargo/.crates2.json
        key: ${{ runner.os }}-cargo-audit
        restore-keys: |
          ${{ runner.os }}-cargo-audit-

    - name: Install cargo-audit
      run: |
        if ! command -v cargo-audit &> /dev/null; then
          cargo install cargo-audit
        fi

    - name: Run security audit
      run: cargo audit

  docs:
    name: Documentation
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable

    - name: Install libudev
      run: sudo apt-get update && sudo apt-get install -y libudev-dev

    - name: Check documentation
      run: cargo doc --no-deps --all-features
      env:
        RUSTDOCFLAGS: "-D warnings"

  publish_check:
    name: Publish Check
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable

    - name: Install libudev
      run: sudo apt-get update && sudo apt-get install -y libudev-dev

    - name: Check if publishable
      run: cargo publish --dry-run --allow-dirty

  publish:
    name: Publish to crates.io
    runs-on: ubuntu-latest
    needs: [check, build, fmt, clippy, security_audit, docs, publish_check]
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    steps:
    - uses: actions/checkout@v4
    - uses: dtolnay/rust-toolchain@stable

    - name: Install libudev
      run: sudo apt-get update && sudo apt-get install -y libudev-dev

    - name: Check if version already published
      id: check_version
      run: |
        CRATE_VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')
        echo "version=$CRATE_VERSION" >> $GITHUB_OUTPUT

        if curl -s "https://crates.io/api/v1/crates/makcu" | jq -e ".versions[] | select(.num == \"$CRATE_VERSION\")" > /dev/null 2>&1; then
          echo "Version $CRATE_VERSION already exists on crates.io"
          echo "should_publish=false" >> $GITHUB_OUTPUT
        else
          echo "Version $CRATE_VERSION not found on crates.io, proceeding with publish"
          echo "should_publish=true" >> $GITHUB_OUTPUT
        fi

    - name: Login to crates.io
      if: steps.check_version.outputs.should_publish == 'true'
      run: cargo login ${{ secrets.CRATES_IO_TOKEN }}

    - name: Publish to crates.io
      if: steps.check_version.outputs.should_publish == 'true'
      run: cargo publish

    - name: Create GitHub Release
      if: steps.check_version.outputs.should_publish == 'true'
      uses: softprops/action-gh-release@v1
      with:
        tag_name: v${{ steps.check_version.outputs.version }}
        name: Release v${{ steps.check_version.outputs.version }}
        body: |
          ## makcu v${{ steps.check_version.outputs.version }}

          This release passed all CI checks:
          - Tests across all feature combinations
          - Build on Linux, macOS, and Windows
          - Code formatting and linting
          - Security audit
          - Documentation

          Published to [crates.io](https://crates.io/crates/makcu)
        draft: false
        prerelease: false
        generate_release_notes: true
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}