name: Fuzz
on:
workflow_call:
inputs:
runs-on:
type: string
required: true
timeout:
type: number
default: 60
fork:
type: number
default: 4
workflow_dispatch:
inputs:
runs-on:
description: "Runner (e.g. ubuntu-latest, macos-latest)"
type: string
default: ubuntu-latest
timeout:
description: "Fuzz timeout in seconds"
type: number
default: 60
fork:
description: "Parallel fuzz processes (-fork=N). macOS has 3 CPUs, linux/win 4. See https://docs.github.com/en/actions/reference/runners/github-hosted-runners"
type: number
default: 4
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
fuzz:
runs-on: ${{ inputs.runs-on }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@nightly
- uses: ilammy/msvc-dev-cmd@v1
- uses: Swatinem/rust-cache@v2
with:
cache-all-crates: true
- uses: actions/cache/restore@v5
with:
path: fuzz/corpus
key: fuzz-${{ inputs.runs-on }}-${{ github.run_id }}
restore-keys: fuzz-
enableCrossOsArchive: true
- run: cargo install cargo-fuzz
- run: cargo update --ignore-rust-version
- run: |
# Ensure MSVC link.exe is found before Git's /usr/bin/link.exe
[ -n "$VCToolsInstallDir" ] && export PATH="$(cygpath -u "$VCToolsInstallDir/bin/Hostx64/x64"):$PATH"
for target in $(cargo fuzz list 2>/dev/null); do
cargo fuzz run "$target" -- -max_total_time="$TIMEOUT" -fork="$FORK"
# TODO: figure out why cmin on one platform loses coverage for the other,
# even though apple_compatible_from_normalized_cs_fallback should keep parity.
# cargo fuzz cmin "$target"
# -fork=N exits 0 even on crashes; check for crash artifacts.
if ls fuzz/artifacts/"$target"/* >/dev/null 2>&1; then
echo "Fuzz artifacts found for $target:"
ls fuzz/artifacts/"$target"/
exit 1
fi
done
shell: bash
env:
TIMEOUT: ${{ inputs.timeout }}
FORK: ${{ inputs.fork }}
- uses: actions/cache/save@v5
if: always()
with:
path: fuzz/corpus
key: fuzz-${{ inputs.runs-on }}-${{ github.run_id }}
enableCrossOsArchive: true
- uses: actions/upload-artifact@v6
if: failure()
with:
name: fuzz-artifacts-${{ inputs.runs-on }}
path: fuzz/artifacts