Skip to content

Commit

Permalink
ci: Run fuzzing only on related changes
Browse files Browse the repository at this point in the history
We previously always built fuzzers. This change updates the fuzzers
workflow as follows:

* the workflow is only invoked when a fuzz crate changes (or when the
  workflow itself changes).
* fuzzer builds are only executed for changed crate directories
* furthermore, this change closes #1336, running cifuzz actions whenever
  a fuzzed crate changes.

Co-authored-by: David Korczynski <[email protected]>
Signed-off-by: Oliver Gould <[email protected]>
  • Loading branch information
DavidKorczynski authored and olix0r committed Feb 16, 2022
1 parent b3d1236 commit 15c799f
Showing 1 changed file with 95 additions and 14 deletions.
109 changes: 95 additions & 14 deletions .github/workflows/fuzzers.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
name: fuzzers

on:
pull_request: {}
# Only run on PRs that touch fuzzed crates
pull_request:
paths:
- 'linkerd/addr/**'
- 'linkerd/app/inbound/**'
- 'linkerd/dns/**'
- 'linkerd/proxy/http/**'
- 'linkerd/tls/**'
- 'linkerd/transport-header/**'
- .github/workflows/fuzzers.yml

env:
CARGO_INCREMENTAL: 0
Expand All @@ -13,27 +22,99 @@ permissions:
contents: read

jobs:
list-changed:
timeout-minutes: 3
runs-on: ubuntu-latest
container:
image: docker://rust:1.56.1-buster
outputs:
dirs: ${{ steps.list-changed.outputs.dirs }}
steps:
- run: apt update && apt install -y jq
- uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- run: cargo fetch
- uses: tj-actions/changed-files@b3b79dbb9cf4fd390105963b48346e14b4842cc1
id: changed-files
- name: list changed crates
id: list-changed
run: |
files="${{ steps.changed-files.outputs.all_changed_files }}"
# Find the nearest fuzzer crate, or nothing.
find_fuzz_dir() {
d=$(dirname "$1")
if [ "$d" = . ]; then
return
elif [ -d "$d" ] && [[ "$d" = /fuzz$ ]]; then
echo "$d"
elif [ -f "$d/fuzz/Cargo.toml" ]; then
echo "$d/fuzz"
else
find_fuzz_dir "$d"
fi
}
list_dirs() {
dirs=""
for file in $(echo $*) ; do
if [ "$file" = ./github/workflows/fuzzers.yml ]; then
dirs=$(find . -type d -name fuzz)
break
fi
d=$(find_fuzz_dir "$file")
if [ -n "$d" ]; then
if [ -z "$dirs" ]; then
dirs="$d"
else
dirs="$dirs $d"
fi
fi
done
echo "${dirs}" | tr ' ' "\n" | sort -u
}
echo "::set-output name=dirs::$(list_dirs $files | tr "\n" " ")"
# Ensure that all of the fuzzers continue to build.
#
# This is depends on the nightly toolchain, so it may break unexpectedly.
fuzzers-build:
# Build fuzzers for any changed crates.
build:
needs: [list-changed]
timeout-minutes: 40
runs-on: ubuntu-latest
container:
image: docker://rust:1.56.1-buster
strategy:
matrix:
dir:
- addr
- app/inbound
- dns
- proxy/http
- tls
- transport-header
dir: ${{ fromJson(needs.list-changed.outputs.dirs) }}
steps:
- uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- run: rustup toolchain add nightly
- run: cargo install cargo-fuzz
- working-directory: linkerd/${{matrix.dir}}/fuzz
- uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- working-directory: ${{matrix.dir}}
run: cargo +nightly fetch
- working-directory: ${{matrix.dir}}
run: cargo +nightly fuzz build

# Run fuzzing whenever any fuzzed crate is changed.
#
# There's currently no way to restric tthis to a single fuzzed crate.
cifuzz:
timeout-minutes: 40
runs-on: ubuntu-latest
steps:
- name: build
id: build
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@2c164afcbab66dd27378dc6dab69bb3c285e8e83
with:
oss-fuzz-project-name: linkerd2-proxy
language: rust

- name: run
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@2c164afcbab66dd27378dc6dab69bb3c285e8e83
with:
oss-fuzz-project-name: linkerd2-proxy
language: rust
fuzz-seconds: 600

- name: upload crash
uses: actions/upload-artifact@v1
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
path: ./out/artifacts

0 comments on commit 15c799f

Please sign in to comment.