Skip to content

fuzz-smoke

fuzz-smoke #40

Workflow file for this run

# mk-codec fuzz smoke — mk phase (the final phase) of the constellation
# stress-fuzz program (Cycle C). Two jobs:
# * `build` (compile gate) on every push/PR touching fuzz/** or
# crates/mk-codec/src/** — catches API drift between the codec and the
# fuzz targets early (the lagging-indicator lesson).
# * `smoke` on a daily cron + manual workflow_dispatch — runs each target
# for 60s and uploads any crash artifacts. NOT on every push (off the
# critical path).
#
# NOTE (relationship to ci.yml): the repo's existing ci.yml has no `paths:`
# filter, so it fires on every push to main / every PR — but it only runs
# `cargo build/test/clippy --workspace` and `cargo fmt --all` from the REPO
# ROOT, whose workspace member list is explicit (crates/mk-codec, crates/mk-cli)
# and never globs nested Cargo.toml. The fuzz/ crate has its OWN `[workspace]`,
# so ci.yml is completely blind to it and there is no path-filter collision:
# fuzz/** changes trigger only THIS workflow's build gate, and ci.yml continues
# to gate the codec + cli. (Verified the same way the md/ms phases did.)
#
# Nightly is required by cargo-fuzz (libFuzzer runtime). The toolchain is
# pinned to the same dated nightly as fuzz/rust-toolchain.toml; the
# constellation-wide FOLLOWUP `fuzz-nightly-quarterly-bump` (toolkit repo)
# tracks refreshing both in lockstep quarterly.
#
# NOTE (cron caveats): scheduled workflows run on the DEFAULT BRANCH only
# and auto-disable after 60 days of repo inactivity — workflow_dispatch is
# the manual run + post-disable recovery lever.
name: fuzz-smoke
on:
push:
paths:
- "fuzz/**"
- "crates/mk-codec/src/**"
- ".github/workflows/fuzz-smoke.yml"
pull_request:
paths:
- "fuzz/**"
- "crates/mk-codec/src/**"
- ".github/workflows/fuzz-smoke.yml"
schedule:
# Daily at 07:23 UTC (off the hour to avoid the cron thundering herd; a
# couple of minutes off the ms phase's 07:19 to spread constellation load).
- cron: "23 7 * * *"
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
jobs:
build:
name: cargo fuzz build (compile gate)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install pinned nightly
# @master + `toolchain:` input is dtolnay's documented way to pin a
# DATED nightly (dated nightlies are not available as action refs).
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2026-04-27
components: rust-src
targets: x86_64-unknown-linux-gnu
- name: Install cargo-fuzz
uses: taiki-e/install-action@v2
with:
tool: cargo-fuzz
- name: Build all fuzz targets
working-directory: fuzz
# Pin the gnu target: on the runner cargo-fuzz otherwise defaults to
# the musl host triple, and ASan is incompatible with musl's static
# libc ("sanitizer is incompatible with statically linked libc").
run: cargo +nightly-2026-04-27 fuzz build --target x86_64-unknown-linux-gnu
smoke:
name: cargo fuzz run (60s smoke)
# Only on cron + manual dispatch — never on push/PR (off the critical path).
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Both mk targets join the daily smoke: local bring-up (>=60s each,
# seeded) found NO crash on either, so neither stands red. (If a future
# finding lands, hold the crashing target out of THIS matrix while
# keeping it in the `build` compile gate above, and cite the FOLLOWUP —
# the treatment the ms phase used for ms1_decode.)
target:
- mk1_decode
- mk1_decode_single
steps:
- uses: actions/checkout@v4
- name: Install pinned nightly
# @master + `toolchain:` input is dtolnay's documented way to pin a
# DATED nightly (dated nightlies are not available as action refs).
uses: dtolnay/rust-toolchain@master
with:
toolchain: nightly-2026-04-27
components: rust-src
targets: x86_64-unknown-linux-gnu
- name: Install cargo-fuzz
uses: taiki-e/install-action@v2
with:
tool: cargo-fuzz
- name: Smoke-run ${{ matrix.target }}
working-directory: fuzz
# Pin the gnu target (see the build job's note re: musl/ASan).
run: cargo +nightly-2026-04-27 fuzz run ${{ matrix.target }} --target x86_64-unknown-linux-gnu -- -max_total_time=60
- name: Upload crash artifacts
if: failure()
uses: actions/upload-artifact@v5
with:
name: fuzz-crash-${{ matrix.target }}
path: fuzz/artifacts/${{ matrix.target }}/
if-no-files-found: ignore