oximg 0.9.0

High-performance image compression: library, CLI, and self-hostable server (PoC).
Documentation
name: CI

on:
  push:
    branches: [main]
  pull_request:

env:
  CARGO_TERM_COLOR: always
  # The Dockerfile's pinned post-4.1 SVT-AV1 revision (aarch64 QM/IQ
  # kernels; ABI-verified against the pregenerated bindings). Keep the
  # two in sync when bumping.
  SVT_AV1_REV: d3c4cb3947a8bfed0aa5a2be996b37bb117fa1bd

jobs:
  test:
    strategy:
      fail-fast: false
      matrix:
        include:
          # NEON kernels are production code (Graviton, Apple silicon):
          # both architectures run the full suite in both feature
          # configurations.
          - os: ubuntu-latest
            arch: amd64
          - os: ubuntu-24.04-arm
            arch: arm64
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v5
      - name: Install build dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y --no-install-recommends cmake nasm pkg-config libdav1d-dev
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - name: Cache SVT-AV1
        id: svt-cache
        uses: actions/cache@v4
        with:
          path: svt-install
          key: svt-av1-${{ env.SVT_AV1_REV }}-${{ matrix.arch }}
      - name: Build SVT-AV1
        if: steps.svt-cache.outputs.cache-hit != 'true'
        run: |
          git clone --depth 1 https://gitlab.com/AOMediaCodec/SVT-AV1.git svt
          git -C svt fetch --depth 1 origin "$SVT_AV1_REV"
          git -C svt checkout "$SVT_AV1_REV"
          cmake -S svt -B svt/build -DCMAKE_BUILD_TYPE=Release \
            -DBUILD_APPS=OFF -DBUILD_TESTING=OFF \
            -DCMAKE_INSTALL_PREFIX="$PWD/svt-install" -DCMAKE_INSTALL_LIBDIR=lib
          make -C svt/build -j"$(nproc)" install
          rm -rf svt
      - name: Install SVT-AV1
        run: |
          sudo cp -r svt-install/* /usr/local/
          sudo ldconfig
      - name: Format
        if: matrix.arch == 'amd64'
        run: cargo fmt --check
      - name: Clippy (default features)
        run: cargo clippy --release --all-targets -- -D warnings
      - name: Clippy (avif)
        run: cargo clippy --release --all-targets --features avif -- -D warnings
      - name: Test (default features)
        run: cargo test --release
      - name: Test (avif)
        run: cargo test --release --features avif
      - name: Build all targets
        run: cargo build --release --all-targets --features avif
      # The library must build without the HTTP stack (no server feature).
      - name: Check (library only)
        if: matrix.arch == 'amd64'
        run: cargo clippy --release --no-default-features --features avif -- -D warnings
      # Runtime smoke for the examples/tools — they compile under
      # --all-targets above, but nothing ran them, so a broken CLI path
      # (arg handling, read_ppm) would slip through.
      - name: Examples smoke
        if: matrix.arch == 'amd64'
        run: |
          cargo run --release --example probe -- tests/fixtures/photo.webp
          cargo run --release --example thumbnail -- tests/fixtures/photo.jpg 64 64 /tmp/t.jpg
          cargo run --release --example transcode --features avif -- tests/fixtures/photo.jpg 64 64 avif /tmp/t.avif
          cargo run --release --example qcli --features avif -- transcode tests/fixtures/photo.jpg 64 64 webp /tmp/q.webp

  # The declared rust-version must actually build: cargo-install users
  # on the MSRV toolchain hit whatever this job would have caught.
  msrv:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - name: Install build dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y --no-install-recommends cmake nasm pkg-config
      - uses: dtolnay/rust-toolchain@master
        with:
          toolchain: "1.90"
      - uses: Swatinem/rust-cache@v2
      - name: Check (default features, MSRV)
        run: cargo check --release --all-targets

  # Coverage is informational (no threshold yet): the number is most
  # useful over pipeline/'s knob-gated branches.
  coverage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - name: Install build dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y --no-install-recommends cmake nasm pkg-config libdav1d-dev
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: llvm-tools-preview
      - uses: taiki-e/install-action@v2
        with:
          tool: cargo-llvm-cov
      - uses: Swatinem/rust-cache@v2
      - name: Cache SVT-AV1
        id: svt-cache
        uses: actions/cache@v4
        with:
          path: svt-install
          key: svt-av1-${{ env.SVT_AV1_REV }}-amd64
      - name: Build SVT-AV1
        if: steps.svt-cache.outputs.cache-hit != 'true'
        run: |
          git clone --depth 1 https://gitlab.com/AOMediaCodec/SVT-AV1.git svt
          git -C svt fetch --depth 1 origin "$SVT_AV1_REV"
          git -C svt checkout "$SVT_AV1_REV"
          cmake -S svt -B svt/build -DCMAKE_BUILD_TYPE=Release \
            -DBUILD_APPS=OFF -DBUILD_TESTING=OFF \
            -DCMAKE_INSTALL_PREFIX="$PWD/svt-install" -DCMAKE_INSTALL_LIBDIR=lib
          make -C svt/build -j"$(nproc)" install
          rm -rf svt
      - name: Install SVT-AV1
        run: |
          sudo cp -r svt-install/* /usr/local/
          sudo ldconfig
      # The threshold is a collapse detector, not a target: current
      # line coverage sits ~86%, and 80 leaves room for normal churn
      # while making a silent slide into the 70s a red build.
      - name: Coverage summary
        run: cargo llvm-cov --release --features avif --summary-only --fail-under-lines 80