name: Continuous Fuzzing
on:
push:
branches: [main, master, staging, try]
pull_request:
branches: [main, master]
schedule:
- cron: "0 0 * * *"
permissions:
contents: read
jobs:
fuzz:
name: Fuzz ${{ matrix.target }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target: [fuzz_target_1]
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
- name: Install Rust nightly
uses: dtolnay/rust-toolchain@5b842231ba77f5c045dba54ac5560fed2db780e2
- name: Cache cargo bin
id: cache-cargo-bin
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae with:
path: ~/.cargo/bin/cargo-fuzz
key: ${{ runner.os }}-cargo-fuzz-bin
- name: Cache Fuzzing Corpus
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae with:
path: fuzz/corpus/${{ matrix.target }}
key: ${{ runner.os }}-fuzz-corpus-${{ matrix.target }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-fuzz-corpus-${{ matrix.target }}-
- name: Cache build artifacts
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
fuzz/target/
target/
key: ${{ runner.os }}-fuzz-target-${{ matrix.target }}-${{ hashFiles('Cargo.lock', 'fuzz/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-fuzz-target-${{ matrix.target }}-
- name: Run Fuzzer
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
# Run the fuzzer 5 times, each for 1 hour (3600 seconds) instead of 1 time for 5 hours.
# Long single fuzzer runs can hit memory limits or cause CPU starvation in shared CI runners.
for i in {1..5}; do
echo "Starting PR fuzzer iteration $i of 5..."
RUSTFLAGS="-Zsanitizer=address" cargo +nightly build --manifest-path ./fuzz/Cargo.toml --target x86_64-unknown-linux-gnu --release -Z build-std=std,panic_abort --config 'profile.release.debug = "line-tables-only"' --config 'profile.release.lto = false'
./target/x86_64-unknown-linux-gnu/release/${{ matrix.target }} -max_total_time=3600
done
else
echo "Starting standard fuzzer iteration (1 hour)..."
RUSTFLAGS="-Zsanitizer=address" cargo +nightly build --manifest-path ./fuzz/Cargo.toml --target x86_64-unknown-linux-gnu --release -Z build-std=std,panic_abort --config 'profile.release.debug = "line-tables-only"' --config 'profile.release.lto = false'
./target/x86_64-unknown-linux-gnu/release/${{ matrix.target }} -max_total_time=3600
fi
- name: Upload Crash Artifacts
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with:
name: fuzzer-artifacts-${{ matrix.target }}
path: fuzz/artifacts/${{ matrix.target }}
if-no-files-found: ignore