Skip to content

fuzz

fuzz #2

Workflow file for this run

# cargo-fuzz weekly cron + manual workflow_dispatch.
# Slice 3 of T1 test-architecture decomposition.
# See spec: docs/superpowers/specs/2026-04-25-cargo-fuzz-design.md
#
# WHY a separate workflow (not added to ci.yml): fuzz runs are bounded
# minutes, NOT seconds; they would dominate per-PR queue if added to
# the main matrix. Decoupling lets fuzz fail-or-skip independently of
# the main `just ci` matrix.
name: fuzz
# WHY cron disabled (2026-04-25): user opted to run this manually for now;
# weekly automation will resume when re-added. workflow_dispatch retained.
on:
workflow_dispatch:
inputs:
max_total_time:
description: 'Per-target fuzz duration in seconds'
type: string
default: '300'
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
fuzz:
name: cargo fuzz / ${{ matrix.target }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target: [exif, blake3]
steps:
- uses: actions/checkout@v4
# WHY install nightly here (not via dtolnay/rust-toolchain@stable):
# the fuzz/ subdir's rust-toolchain.toml pins nightly; rustup honors
# the toolchain file when invoked from inside fuzz/.
- name: Install nightly via fuzz/rust-toolchain.toml
run: |
cd fuzz
rustup show
- uses: Swatinem/rust-cache@v2
with:
workspaces: fuzz -> target
- name: Install cargo-fuzz
uses: taiki-e/install-action@v2
with:
tool: cargo-fuzz
# WHY install GTK deps defensively: matches slice 1 cargo-mutants
# workflow pattern to keep workflow scaffolding uniform across the
# T1 test-architecture slices. Strictly speaking, perima-hash +
# perima-media do NOT transitively require GTK on ubuntu-latest's
# default features; keeping the install avoids silent breakage if
# a future cargo-features change pulls in something system-dep-ful.
- name: Install image/system deps
run: |
sudo apt-get update -q
sudo apt-get install -yq \
libgtk-3-dev \
libwebkit2gtk-4.1-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
patchelf
# WHY continue-on-error: per spec D-4, observability-only mode.
# libFuzzer exits non-zero on a crash; without continue-on-error
# the very first crash blocks all future runs of this workflow
# until the crash is fixed. Precedent: kani.yml + mutants.yml use
# the same pattern.
#
# WHY --target x86_64-unknown-linux-gnu (added 2026-04-25): cargo-fuzz
# 0.13+ defaults to --target x86_64-unknown-linux-musl on Linux, but
# musl statically links libc which AddressSanitizer rejects
# ("sanitizer is incompatible with statically linked libc"). Pinning
# gnu uses the host triple already installed by dtolnay/rust-toolchain
# — no extra `rustup target add` step needed.
- name: Run cargo fuzz target ${{ matrix.target }}
continue-on-error: true
env:
MAX_TIME: ${{ github.event.inputs.max_total_time || '300' }}
run: |
cd fuzz
cargo fuzz run ${{ matrix.target }} --target x86_64-unknown-linux-gnu -- -max_total_time=$MAX_TIME
- name: Upload artifacts (if any crashes)
if: always()
uses: actions/upload-artifact@v4
with:
name: fuzz-artifacts-${{ matrix.target }}
path: fuzz/artifacts/${{ matrix.target }}/
if-no-files-found: ignore