name: CI
on:
push:
branches: [master, main]
pull_request: {}
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 - name: Install Rust toolchain
run: rustup toolchain install stable --profile minimal --component rustfmt,clippy && rustup default stable
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 with:
path: target
key: x86_64-unknown-linux-gnu-lint
- name: Format
run: cargo fmt --all -- --check
- name: Clippy (all features)
run: cargo clippy --all-features --all-targets -- -D warnings
- name: Clippy (no features)
run: cargo clippy --all-targets -- -D warnings
- name: Docs
env:
RUSTDOCFLAGS: "-D warnings"
run: cargo doc --no-deps --document-private-items
build:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 - name: Install Rust toolchain
run: rustup toolchain install stable --profile minimal && rustup default stable
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 with:
path: target
key: x86_64-unknown-linux-gnu-build
- name: Build (debug)
run: cargo build --verbose
- name: Build (release)
run: cargo build --release --verbose
- name: Feature check
run: |
cargo check --no-default-features
cargo check --all-features
cargo check --benches --all-features
test:
name: test (${{ matrix.engine.type }} ${{ matrix.engine.version }}, ${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- { runner: ubuntu-24.04, arch: x64, engine: { type: valkey, version: "8.1" } }
- { runner: ubuntu-24.04, arch: x64, engine: { type: valkey, version: "8.0" } }
- { runner: ubuntu-24.04, arch: x64, engine: { type: valkey, version: "7.2" } }
- { runner: ubuntu-24.04, arch: x64, engine: { type: redis, version: "7.2" } }
- { runner: ubuntu-24.04-arm, arch: arm64, engine: { type: valkey, version: "8.1" } }
- { runner: ubuntu-24.04-arm, arch: arm64, engine: { type: valkey, version: "8.0" } }
- { runner: ubuntu-24.04-arm, arch: arm64, engine: { type: valkey, version: "7.2" } }
- { runner: ubuntu-24.04-arm, arch: arm64, engine: { type: redis, version: "7.2" } }
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 - name: Install Rust toolchain
run: rustup toolchain install stable --profile minimal && rustup default stable
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 with:
path: target
key: ${{ matrix.arch }}-test-${{ matrix.engine.type }}-${{ matrix.engine.version }}
- name: Cache ${{ matrix.engine.type }} ${{ matrix.engine.version }} build
id: engine-cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 with:
path: ~/engine-install
key: engine-${{ matrix.arch }}-${{ matrix.engine.type }}-${{ matrix.engine.version }}
- name: Build ${{ matrix.engine.type }} ${{ matrix.engine.version }} from source
if: steps.engine-cache.outputs.cache-hit != 'true'
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libssl-dev tcl
if [ "${{ matrix.engine.type }}" = "valkey" ]; then
REPO="https://github.com/valkey-io/valkey.git"
else
REPO="https://github.com/redis/redis.git"
fi
git clone --depth 1 --branch "${{ matrix.engine.version }}" "$REPO" engine-src
make -C engine-src -j"$(nproc)" BUILD_TLS=yes
mkdir -p "$HOME/engine-install"
cp engine-src/src/*-server engine-src/src/*-cli "$HOME/engine-install/"
- name: Register engine on PATH
run: |
set -euo pipefail
echo "$HOME/engine-install" >> "$GITHUB_PATH"
if [ -x "$HOME/engine-install/valkey-server" ]; then
echo "VALKEY_SERVER_PATH=$HOME/engine-install/valkey-server" >> "$GITHUB_ENV"
else
echo "VALKEY_SERVER_PATH=$HOME/engine-install/redis-server" >> "$GITHUB_ENV"
fi
- name: Server version
run: "${VALKEY_SERVER_PATH} --version"
- name: Build tests
run: cargo test --no-run --verbose
- name: Test
run: cargo test --verbose
coverage:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 - name: Install Rust toolchain
run: rustup toolchain install stable --profile minimal --component llvm-tools-preview && rustup default stable
- name: Install cargo-llvm-cov
run: cargo install --locked cargo-llvm-cov
- name: Install a Valkey/Redis server
run: |
sudo apt-get update
sudo apt-get install -y valkey-server || sudo apt-get install -y redis-server
echo "VALKEY_SERVER_PATH=$(command -v valkey-server || command -v redis-server)" >> "$GITHUB_ENV"
- name: Coverage
run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info --summary-only -- --test-threads=2
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v7
with:
files: lcov.info
fail_ci_if_error: false
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
deny:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 - name: Install Rust toolchain
run: rustup toolchain install stable --profile minimal && rustup default stable
- name: Cache cargo registry, git deps, and cargo-deny
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 with:
path: |
~/.cargo/registry/index
~/.cargo/registry/cache
~/.cargo/git/db
~/.cargo/bin/cargo-deny
key: deny-${{ hashFiles('Cargo.lock') }}
restore-keys: |
deny-
- name: Install cargo-deny
run: command -v cargo-deny >/dev/null 2>&1 || cargo install --locked cargo-deny
- name: cargo-deny (retry transient network errors only)
run: |
set -uo pipefail
for attempt in 1 2 3; do
out="$(cargo deny check 2>&1)"; status=$?
echo "$out"
if [ "$status" -eq 0 ]; then
exit 0
fi
# Retry only spurious registry/network failures; a real
# advisory/license/ban/source violation fails immediately.
if echo "$out" | grep -qiE 'spurious network error|failed to fetch|Updating crates.io index|http status code: (403|429|5[0-9][0-9])|failed to get .* as a dependency'; then
echo "::warning::cargo deny hit a transient network error (attempt ${attempt}); retrying..."
sleep $((attempt * 15))
else
echo "::error::cargo deny reported a policy violation (not a network error)."
exit "$status"
fi
done
echo "::error::cargo deny still failing after retries (persistent network issue)."
exit 1