tappers 0.4.2

Cross-platform TUN, TAP and vETH interfaces
Documentation
name: full CI

on:
  push:
    branches: [ "master" ]
  merge_group:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  style_check:
    name: Style check
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - name: Setup Rust toolchain
        run: sh ./ci/install-rust.sh
      - name: Check style
        run: sh ci/style.sh

  build_channels_linux:
    name: Build Channels Linux
    runs-on: ubuntu-22.04
    env:
      OS: linux
    strategy:
      fail-fast: true
      max-parallel: 2
      matrix:
        toolchain:
          - stable
          - 1.70.0
    steps:
      - uses: actions/checkout@v4
      - name: Setup Rust toolchain
        run: TOOLCHAIN=${{ matrix.toolchain }} sh ./ci/install-rust.sh
      - name: Execute run.sh
        run: TOOLCHAIN=${{ matrix.toolchain }} sh ./ci/run.sh

  build_channels_macos:
    name: Build Channels macOS
    env:
      OS: macos
    strategy:
      fail-fast: true
      max-parallel: 2
      matrix:
        target:
          - { toolchain: stable, os: macos-14 }
          - { toolchain: 1.70.0, os: macos-14 }
    runs-on: ${{ matrix.target.os }}
    steps:
      - uses: actions/checkout@v4
      - name: Setup Rust toolchain
        run: sh ./ci/install-rust.sh
      - name: Execute build.sh
        run: TOOLCHAIN=${{ matrix.target.toolchain }} sh ./ci/run.sh

  build_channels_windows:
    name: Build Channels Windows
    runs-on: windows-2022
    env:
      OS: windows
    strategy:
      fail-fast: true
      matrix:
        toolchain:
          - stable
          - 1.70.0
        target:
          - x86_64-pc-windows-msvc
    steps:
      - uses: actions/checkout@v4
      - name: Self-update rustup
        run: TARGET=${{ matrix.target }} sh ./ci/install-rust.sh
        shell: bash
      - name: Execute build.sh
        run: TOOLCHAIN=${{ matrix.toolchain }} sh ./ci/run.sh
        shell: bash

  build_channels_dragonflybsd:
    name: Build Channels DragonFlyBSD
    runs-on: ubuntu-latest
    env:
      OS: dragonfly
    strategy:
      fail-fast: true
      matrix:
        toolchain:
          - stable # Note: not actually stable, just current rustc version for DragonFlyBSD 6.4
    steps:
    - uses: actions/checkout@v4
    - name: Test in DragonFlyBSD
      id: dragonflybsd-ci
      uses: vmactions/dragonflybsd-vm@v1
      with:
        release: "6.4.0"
        envs: 'OS'
        usesh: true
        # DragonFly BSD does not have TAP interfaces by default; use kldload if_tap
        prepare: |
          pkg install -y sudo
          pkg install -y rust
          pkg upgrade -y
          kldload if_tap
        run: |
          TOOLCHAIN=${{ matrix.toolchain }} sh ./ci/run.sh

  build_channels_openbsd:
    name: Build Channels OpenBSD
    runs-on: ubuntu-latest
    env:
      OS: openbsd
    strategy:
      fail-fast: true
      matrix:
        toolchain:
          - stable # Note: not actually stable, just current rustc version for OpenBSD 7.5
    steps:
    - uses: actions/checkout@v4
    - name: Test in OpenBSD
      id: openbsd-ci
      uses: vmactions/openbsd-vm@v1
      with:
        release: "7.5"
        envs: 'OS'
        usesh: true
        prepare: |
          pkg_add curl
          pkg_add sudo-1.9.15.5
          pkg_add rust
        run: |
          TOOLCHAIN=${{ matrix.toolchain }} sh ./ci/run.sh

  build_channels_freebsd:
    name: Build Channels FreeBSD
    runs-on: ubuntu-latest
    env:
      OS: freebsd
    strategy:
      fail-fast: true
      matrix:
        toolchain:
          - stable
          - 1.70.0
    steps:
    - uses: actions/checkout@v4
    - name: Test in FreeBSD
      id: freebsd-ci
      uses: vmactions/freebsd-vm@v1
      with:
        envs: 'OS'
        usesh: true
        prepare: |
          pkg install -y curl
          pkg install -y sudo
          curl https://sh.rustup.rs -sSf | sh -s -- -y
        run: |
          export PATH="$HOME/.cargo/bin:$PATH"
          TARGET=${{ matrix.target }} sh ./ci/install-rust.sh
          TOOLCHAIN=${{ matrix.toolchain }} sh ./ci/run.sh

  build_channels_netbsd:
    name: Build Channels NetBSD
    runs-on: ubuntu-latest
    env:
      DEBUG: 1
      OS: netbsd
    strategy:
      fail-fast: true
      matrix:
        toolchain:
          - stable
          - 1.70.0
    steps:
    - uses: actions/checkout@v4
    - name: Test in NetBSD
      id: netbsd-ci
      uses: vmactions/netbsd-vm@v1
      with:
        envs: 'DEBUG OS'
        usesh: true
        prepare: |
          /usr/sbin/pkg_add curl
          /usr/sbin/pkg_add sudo

          curl https://sh.rustup.rs -sSf | sh -s -- -y
        run: |
          export PATH="$HOME/.cargo/bin:$PATH"
          TARGET=${{ matrix.target }} sh ./ci/install-rust.sh
          TOOLCHAIN=${{ matrix.toolchain }} sh ./ci/run.sh

  build_channels_arm_linux:
    name: Build Channels ARM (Linux)
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: pguyot/arm-runner-action@v2
      with:
        image_additional_mb: 4096 # Enlarge raspi image by 4GB
        commands: |
          curl https://sh.rustup.rs -sSf | sh -s -- -y
          export PATH="$HOME/.cargo/bin:$PATH"
          TOOLCHAIN=stable sh ./ci/install-rust.sh
          TOOLCHAIN=stable OS=linux sh ./ci/run.sh

  check_cfg:
    name: "Check #[cfg]s"
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - name: Setup Rust toolchain
        run: TOOLCHAIN=nightly sh ./ci/install-rust.sh
      - name: Build with check-cfg
        run: LIBC_CHECK_CFG=1 cargo build -Z unstable-options -Z check-cfg

  # One job that "summarizes" the success state of this pipeline. This can then be added to branch
  # protection, rather than having to add each job separately.
  success:
    name: success
    runs-on: ubuntu-22.04
    needs:
      - style_check
      - build_channels_linux
      - build_channels_macos
      - build_channels_windows
    # Github branch protection is exceedingly silly and treats "jobs skipped because a dependency
    # failed" as success. So we have to do some contortions to ensure the job fails if any of its
    # dependencies fails.
    if: always() # make sure this is never "skipped"
    steps:
      # Manually check the status of all dependencies. `if: failure()` does not work.
      - name: check if any dependency failed
        run: jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'

# TODO: when it comes time to add Solaris/IllumOS, add this to install TUN/TAP driver:
# `pkg-get install tap`