name: CI
on:
push:
branches: [main]
pull_request:
env:
CARGO_TERM_COLOR: always
SVT_AV1_REV: d3c4cb3947a8bfed0aa5a2be996b37bb117fa1bd
jobs:
test:
strategy:
fail-fast: false
matrix:
include:
- 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
- name: Clippy (bench tools)
if: matrix.arch == 'amd64'
run: cargo clippy --release --examples --features avif,bench-internals -- -D warnings
- name: Check (library only)
if: matrix.arch == 'amd64'
run: cargo clippy --release --no-default-features --features avif -- -D warnings
- 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
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:
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
- name: Coverage summary
run: cargo llvm-cov --release --features avif --summary-only --fail-under-lines 80
rubygem:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ruby: ["3.1", "3.4"]
steps:
- uses: actions/checkout@v5
- name: Install build dependencies
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends cmake nasm
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Build the oximg binary
run: cargo build
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
- name: Test oximg
working-directory: rubygem/oximg
run: |
bundle install --jobs 4
bundle exec rake test
- name: Test oximg-rails
working-directory: rubygem/oximg-rails
run: |
bundle install --jobs 4
bundle exec rake test
rubygem-musl:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Build the musl binary in Alpine
run: |
docker run --rm -v "$PWD":/src -w /src rust:alpine sh -c '
apk add --no-cache build-base cmake nasm >/dev/null &&
cargo build --release --locked'
# Root inside the container is root on the mount too, so the
# build output lands root-owned on the runner. Give it back
# here rather than discovering it in a later step.
sudo chown -R "$(id -u):$(id -g)" target
- name: Test both gems on Alpine
run: |
docker run --rm -v "$PWD":/src -w /src alpine:latest sh -c '
set -e
apk add --no-cache ruby ruby-bundler >/dev/null
test "$(ruby -e "puts Gem::Platform.local")" = "x86_64-linux-musl"
export BUNDLE_SILENCE_ROOT_WARNING=1
for gem in oximg oximg-rails; do
cd "/src/rubygem/$gem"
bundle config set --local path vendor/bundle >/dev/null
bundle install --jobs 4 >/dev/null
bundle exec rake test
done'
# bundler wrote vendor/bundle and lockfiles as root.
sudo chown -R "$(id -u):$(id -g)" rubygem
- name: Install the musl platform gem and use it
run: |
# A file, not `ruby -e`: this string would otherwise cross a
# YAML block, a shell, `docker run`, and another shell, and
# each layer wants its own quoting.
cat > /tmp/smoke.rb <<'RUBY'
require "oximg"
puts "executable: #{Oximg.executable}"
Oximg.resize("/src/tests/fixtures/photo.jpg", "/tmp/o.webp", width: 120)
raise "unexpected output" unless Oximg.probe("/tmp/o.webp") == {content_type: "image/webp", format: :webp, width: 120, height: 90}
puts "ok: the platform gem resized on bare Alpine"
RUBY
docker run --rm -v "$PWD":/src -v /tmp/smoke.rb:/smoke.rb -w /src alpine:latest sh -c '
set -e
apk add --no-cache ruby >/dev/null
cd /src/rubygem/oximg
mkdir -p exe && install -m 0755 /src/target/release/oximg exe/oximg
OXIMG_GEM_PLATFORM=x86_64-linux-musl gem build oximg.gemspec -o /tmp/musl.gem >/dev/null
rm -f exe/oximg
GEM_HOME=/tmp/gh gem install /tmp/musl.gem --no-document >/dev/null
env -u OXIMG_BIN PATH=/usr/bin:/bin GEM_HOME=/tmp/gh ruby /smoke.rb'
sudo chown -R "$(id -u):$(id -g)" rubygem target