unicom 0.4.0

Unified communication for IoT clients
Documentation
name: Rust
on:
  push:
    branches:
      - master
    tags:
      - '[0-9]+.[0-9]+.[0-9]+'
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

jobs:
  format:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Rust
        uses: dtolnay/rust-toolchain@v1
        with:
          toolchain: stable
          components: rustfmt
      - uses: Swatinem/rust-cache@v2
      - name: Format
        run: cargo fmt --all -- --check

  doc:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Rust
        uses: dtolnay/rust-toolchain@v1
        with:
          toolchain: nightly
          components: rust-docs
      - uses: Swatinem/rust-cache@v2
      - name: Docs core
        env:
          DOCS_RS: 1
        run: cargo doc --all --features rustdoc

  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@v1
        with:
          toolchain: nightly
          components: clippy
      - uses: Swatinem/rust-cache@v2
      - name: Code check (tokio)
        run: cargo clippy --all --all-targets --features tokio
      - name: Code check (async)
        run: cargo clippy -p unicom-tcp -p unicom-unix --all-targets --features async

  test:
    needs:
      - format
      - doc
      - check
    strategy:
      fail-fast: ${{ startsWith(github.ref, 'refs/tags/') }}
      matrix:
        include:
          # Test features
          ## Linux i686
          - task: features
            os: ubuntu-latest
            rust: stable
            target: i686-unknown-linux-gnu
            features: tokio
          - task: features
            os: ubuntu-latest
            rust: stable
            target: i686-unknown-linux-gnu
            features: async
          ## Linux x86_64
          - task: features
            os: ubuntu-latest
            rust: stable
            target: x86_64-unknown-linux-gnu
            features: tokio
          - task: features
            os: ubuntu-latest
            rust: stable
            target: x86_64-unknown-linux-gnu
            features: async
          ## MacOS x86_64
          - task: features
            os: macos-latest
            rust: stable
            target: x86_64-apple-darwin
            features: tokio
          - task: features
            os: macos-latest
            rust: stable
            target: x86_64-apple-darwin
            features: async
          ## Windows GNU i686
          - task: features
            os: windows-latest
            rust: stable
            target: i686-pc-windows-gnu
            features: tokio
          - task: features
            os: windows-latest
            rust: stable
            target: i686-pc-windows-gnu
            features: async
          ## Windows GNU x86_64
          - task: features
            os: windows-latest
            rust: stable
            target: x86_64-pc-windows-gnu
            features: tokio
          - task: features
            os: windows-latest
            rust: stable
            target: x86_64-pc-windows-gnu
            features: async
          ## Windows MSVC i686
          - task: features
            os: windows-latest
            rust: stable
            target: i686-pc-windows-msvc
            features: tokio
          - task: features
            os: windows-latest
            rust: stable
            target: i686-pc-windows-msvc
            features: async
          ## Windows MSVC x86_64
          - task: features
            os: windows-latest
            rust: stable
            target: x86_64-pc-windows-msvc
            features: tokio
          - task: features
            os: windows-latest
            rust: stable
            target: x86_64-pc-windows-msvc
            features: async
          # Test channels
          ## Stable channel
          - task: channels
            os: ubuntu-latest
            rust: stable
            target: x86_64-unknown-linux-gnu
            features: tokio
          - task: channels
            os: ubuntu-latest
            rust: stable
            target: x86_64-unknown-linux-gnu
            features: async
          ## Beta channel
          - task: channels
            os: ubuntu-latest
            rust: beta
            target: x86_64-unknown-linux-gnu
            features: tokio
          - task: channels
            os: ubuntu-latest
            rust: beta
            target: x86_64-unknown-linux-gnu
            features: async
          ## Nightly channel
          - task: channels
            os: ubuntu-latest
            rust: nightly
            target: x86_64-unknown-linux-gnu
            features: tokio
          - task: channels
            os: ubuntu-latest
            rust: nightly
            target: x86_64-unknown-linux-gnu
            features: async
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - name: Setup cross linux toolchain
        if: contains(matrix.target, '-linux-') && !startsWith(matrix.target, 'x86_64-')
        run: |
          case "${{ matrix.target }}" in
            i686-*) SYSTEM_ARCH=i386 ;;
          esac
          GCC_TARGET=$(printf "${{ matrix.target }}" | sed 's/-unknown-/-/' | sed 's/arm[^-]*/arm/g')
          ENV_TARGET=$(printf "${{ matrix.target }}" | tr '[:lower:]' '[:upper:]' | tr '-' '_')
          sudo dpkg --add-architecture ${SYSTEM_ARCH}
          sudo apt-get update -y
          sudo apt-get install -y libc6-dev:${SYSTEM_ARCH} gcc-${GCC_TARGET}
          echo "CARGO_TARGET_${ENV_TARGET}_LINKER=${GCC_TARGET}-gcc" >> $GITHUB_ENV
      - name: Setup clang on windows
        if: startsWith(matrix.os, 'windows')
        uses: KyleMayes/install-llvm-action@v1
        with:
          version: 11.0
          directory: ${{ runner.temp }}/llvm
      - name: Prepare env for windows
        if: startsWith(matrix.os, 'windows') && endsWith(matrix.target, '-gnu')
        run: |
          # Add symlinks to the GNU C headers for Clang
          New-Item -Path "${{ runner.temp }}\llvm\x86_64-w64-mingw32" -ItemType SymbolicLink -Value "C:\msys64\mingw64\x86_64-w64-mingw32"
          New-Item -Path "${{ runner.temp }}\llvm\i686-w64-mingw32" -ItemType SymbolicLink -Value "C:\msys64\mingw32\i686-w64-mingw32"
          # Add mingw executable paths to PATH
          echo "C:\msys64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
          echo "C:\msys64\mingw32\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
          echo "CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
          echo "CC_i686_pc_windows_gnu=i686-w64-mingw32-gcc" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
      - name: Setup Rust
        uses: dtolnay/rust-toolchain@v1
        with:
          toolchain: ${{ matrix.rust }}
          target: ${{ matrix.target }}
      - uses: Swatinem/rust-cache@v2
      - name: Update deps
        run: cargo update
      - name: Build tcp backend
        run: cargo build -p unicom-tcp --target ${{ matrix.target }} --features ${{ matrix.features }}
      - name: Build unix backend
        if: ${{ !contains(matrix.os, 'windows') }}
        run: cargo build -p unicom-unix --target ${{ matrix.target }} --features ${{ matrix.features }}
      - name: Build serial backend
        if: ${{ !contains(matrix.features, 'async') }}
        run: cargo build -p unicom-serial --target ${{ matrix.target }} --features ${{ matrix.features }}

  publish:
    if: (github.repository == 'katyo/unicom') && startsWith(github.ref, 'refs/tags/')
    needs:
      - format
      - doc
      - check
      - test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Rust
        uses: dtolnay/rust-toolchain@v1
        with:
          toolchain: stable
      - name: Publish crates
        uses: katyo/publish-crates@v2
        with:
          registry-token: ${{ secrets.CRATES_TOKEN }}
          args: --no-verify