Skip to content

Main Fuzz Saturate

Main Fuzz Saturate #7

Workflow file for this run

# .github/workflows/main-fuzz.yml
name: Main Fuzz Saturate
on:
workflow_dispatch:
schedule:
- cron: "0 2 * * 6"
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
concurrency:
group: fuzz-main
cancel-in-progress: true
jobs:
discover:
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
results: ${{ steps.q.outputs.results }}
count: ${{ steps.q.outputs.count }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- uses: ./.github/actions/setup
with:
fetch-depth: 1
cache-pnpm: false
- id: q
uses: ./.github/actions/moon-q-projects
with:
task: fuzz-ci
saturate:
needs: discover
if: fromJson(needs.discover.outputs.count) > 0
runs-on: ubuntu-latest
timeout-minutes: 360
permissions:
contents: write
strategy:
fail-fast: false
matrix:
project: ${{ fromJson(needs.discover.outputs.results) }}
env:
FUZZ_MAXTIME: "14400"
FUZZ_JOBS: "4"
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- uses: ./.github/actions/setup
with:
fetch-depth: 1
cache-pnpm: false
- name: Resolve paths
id: paths
run: |
SOURCE="${{ matrix.project.source }}"
CORPUS="${{ matrix.project.metadata.corpus-path }}"
REGRESSIONS="${{ matrix.project.metadata.regressions-path }}"
echo "corpus=${SOURCE}/${CORPUS:-corpus}" >> "$GITHUB_OUTPUT"
echo "regressions=${SOURCE}/${REGRESSIONS:-regressions}" >> "$GITHUB_OUTPUT"
- uses: ./.github/actions/fuzz-cache
with:
mode: pull
project-id: ${{ matrix.project.id }}
corpus-path: ${{ steps.paths.outputs.corpus }}
- name: Fuzz
id: fuzz
continue-on-error: true
uses: ./.github/actions/moon-run
with:
task: ${{ matrix.project.id }}:fuzz-ci
- uses: ./.github/actions/fuzz-cache
if: always() && steps.fuzz.outcome != 'skipped'
with:
mode: push
project-id: ${{ matrix.project.id }}
corpus-path: ${{ steps.paths.outputs.corpus }}
- name: Triage
if: steps.fuzz.outcome == 'failure'
uses: ./.github/actions/moon-run
with:
task: ${{ matrix.project.id }}:fuzz-triage
- uses: actions/upload-artifact@v4
if: steps.fuzz.outcome == 'failure'
with:
name: fuzz-regressions-${{ matrix.project.id }}
path: ${{ steps.paths.outputs.regressions }}/
retention-days: 90
- name: Fail if crashes
if: steps.fuzz.outcome == 'failure'
run: exit 1
create-pr:
needs: [discover, saturate]
if: failure()
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Build target map
id: targets
run: |
TARGETS=$(echo '${{ needs.discover.outputs.results }}' \
| jq -c '[.[] | {
key: .id,
value: (.source + "/" + (.metadata["regressions-path"] // "regressions"))
}] | from_entries')
echo "map=${TARGETS}" >> "$GITHUB_OUTPUT"
- id: stage
uses: ./.github/actions/git-stage-artifacts
with:
artifact-prefix: fuzz-regressions
targets: ${{ steps.targets.outputs.map }}
- name: Build PR metadata
if: steps.stage.outputs.file-count != '0'
id: meta
run: |
PROJECTS="${{ steps.stage.outputs.projects }}"
FILECOUNT="${{ steps.stage.outputs.file-count }}"
PROJECT_COUNT=$(echo "$PROJECTS" | tr ',' '\n' | wc -l)
RUN_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
if [[ "$PROJECT_COUNT" -eq 1 ]]; then
TITLE="chore(${PROJECTS}): add ${FILECOUNT} fuzz regression files"
else
TITLE="chore(fuzz): add ${FILECOUNT} regression files across ${PROJECTS}"
fi
{
echo "title=${TITLE}"
echo "body<<EOF"
echo "Automated saturation run found new crashes."
echo ""
echo "**${FILECOUNT} regression files** across \`${PROJECTS}\`."
echo "Triaged and minimized. Merge to add them to the test suite."
echo ""
echo "[View fuzz run](${RUN_URL})"
echo "EOF"
} >> "$GITHUB_OUTPUT"
- uses: ./.github/actions/pr-create
if: steps.stage.outputs.file-count != '0'
with:
add-paths: "**/regressions/"
branch: chore/fuzz-regressions
title: ${{ steps.meta.outputs.title }}
body: ${{ steps.meta.outputs.body }}
github-token: ${{ secrets.GITHUB_TOKEN }}