-
Notifications
You must be signed in to change notification settings - Fork 1
155 lines (142 loc) · 6.16 KB
/
Copy pathfuzz-pr.yml
File metadata and controls
155 lines (142 loc) · 6.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
name: fuzz (per-PR)
on:
pull_request:
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
# Default to read-only; the `fuzz` job opts into `issues: write` for
# auto-issue filing on crash (gated on same-repo PRs only).
permissions:
contents: read
jobs:
fuzz:
name: ${{ matrix.target }}
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
issues: write
contents: read
strategy:
# One target crashing must not cancel the others; we want to see every
# regression on a single PR, not just the first one.
fail-fast: false
matrix:
target:
- record_decode
- record_roundtrip
- dense_record_decode
- dense_record_roundtrip
- proto_get_ts_request_decode
- proto_get_ts_response_decode
- proto_leader_hint_decode
- log_entry_decode
- snapshot_payload_decode
- toolkit_codec_decode
- openraft_entry_decode
- openraft_meta_decode
- openraft_advance_dense_batch_decode
- openraft_set_leases_decode
- codec_roundtrip
- paxos_log_entry_decode
- paxos_snapshot_decode
- paxos_meta_ballot_decode
- paxos_codec_roundtrip
steps:
# cargo-fuzz compiles the whole dependency tree (rocksdb included) with
# ASAN instrumentation, so the artifacts are large. Reclaim ~30 GB before
# cargo starts; tool-cache: false keeps the runner tool cache (where
# cargo-fuzz is installed) intact.
- name: free disk space
uses: jlumbroso/free-disk-space@ceedf095f4ec1a097402bc6bd80831f2e1a6fde6 # v2.0.0
with:
tool-cache: false
android: true
dotnet: true
haskell: true
large-packages: false
docker-images: true
swap-storage: true
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install pinned nightly toolchain
# The pin lives in fuzz/rust-toolchain.toml; this step installs the
# matching channel so the rustup proxy picks it up automatically.
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with:
toolchain: nightly-2026-03-31
components: rust-src, llvm-tools-preview
- name: Install protoc
timeout-minutes: 5
uses: awalsh128/cache-apt-pkgs-action@553a35bb8ebd9fcabcb1c9451aa4c98e1b4ca8a9 # v1.6.3
with:
packages: protobuf-compiler
version: 1
- name: Install cargo-fuzz
uses: taiki-e/install-action@83ac0ad63c0167e6f06796fab0fce28db1bf3db0 # v2.87.22
with:
tool: cargo-fuzz@0.13.1
- name: Restore working corpus
# The save key embeds github.run_id so every run writes a unique
# cache entry (GitHub's actions/cache only writes on miss; a stable
# key would silently discard newly-discovered corpus entries).
# restore-keys does prefix-match fallback to the most recent matching
# entry; the last fallback line catches harness refactors.
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: fuzz/corpus/${{ matrix.target }}
key: fuzz-corpus-${{ matrix.target }}-${{ hashFiles('fuzz/Cargo.lock', format('fuzz/fuzz_targets/{0}.rs', matrix.target)) }}-${{ github.run_id }}
restore-keys: |
fuzz-corpus-${{ matrix.target }}-${{ hashFiles('fuzz/Cargo.lock', format('fuzz/fuzz_targets/{0}.rs', matrix.target)) }}-
fuzz-corpus-${{ matrix.target }}-
- name: Run fuzz target (5 minutes)
id: fuzz
working-directory: fuzz
# No +nightly override; fuzz/rust-toolchain.toml controls the channel.
# --sanitizer address is the load-bearing safety net (ASAN catches
# use-after-free and buffer overruns from the libc FFI in driver-file).
# UBSAN is a stretch goal; cargo-fuzz 0.13.1 multi-sanitizer support
# would let us add ',undefined' here.
#
# --target x86_64-unknown-linux-gnu overrides cargo-fuzz 0.13's
# default of x86_64-unknown-linux-musl on Linux. The musl default
# links libc statically, which is incompatible with ASAN
# (sancov needs dynamic linking). Pinning to the gnu triple matches
# the host toolchain installed by dtolnay/rust-toolchain.
env:
TARGET: ${{ matrix.target }}
run: |
set +e
cargo fuzz run "$TARGET" \
--sanitizer address \
--target x86_64-unknown-linux-gnu \
-- -max_total_time=300 \
2>&1 | tee fuzz-output.log
EXIT=${PIPESTATUS[0]}
echo "exit_code=${EXIT}" >> "$GITHUB_OUTPUT"
exit "$EXIT"
- name: Upload crash artifact
if: failure() && steps.fuzz.outputs.exit_code != '0'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: fuzz-crash-${{ matrix.target }}-${{ github.run_id }}
path: fuzz/artifacts/${{ matrix.target }}/
retention-days: 30
if-no-files-found: warn
- name: Auto-file deduplicated issue (same-repo PRs only)
# Fork-PR workflows receive a read-only GITHUB_TOKEN, so issue
# creation would fail anyway. The artifact upload above remains the
# visible signal for those runs.
if: |
failure() &&
steps.fuzz.outputs.exit_code != '0' &&
github.event.pull_request.head.repo.full_name == github.repository
uses: ./.github/actions/fuzz-auto-issue
with:
target: ${{ matrix.target }}
libfuzzer-output: fuzz/fuzz-output.log
artifact-name: fuzz-crash-${{ matrix.target }}-${{ github.run_id }}
run-id: ${{ github.run_id }}
- name: Save working corpus (even on failure)
if: always()
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: fuzz/corpus/${{ matrix.target }}
key: fuzz-corpus-${{ matrix.target }}-${{ hashFiles('fuzz/Cargo.lock', format('fuzz/fuzz_targets/{0}.rs', matrix.target)) }}-${{ github.run_id }}