From 15c799ff656bad2c81383ae10d617cb3a162efa2 Mon Sep 17 00:00:00 2001 From: David Korczynski Date: Wed, 27 Oct 2021 11:53:05 +0100 Subject: [PATCH] ci: Run fuzzing only on related changes 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 Signed-off-by: Oliver Gould --- .github/workflows/fuzzers.yml | 109 +++++++++++++++++++++++++++++----- 1 file changed, 95 insertions(+), 14 deletions(-) diff --git a/.github/workflows/fuzzers.yml b/.github/workflows/fuzzers.yml index f7f81fddf4..539d4e57cf 100644 --- a/.github/workflows/fuzzers.yml +++ b/.github/workflows/fuzzers.yml @@ -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 @@ -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