-
Notifications
You must be signed in to change notification settings - Fork 25
140 lines (131 loc) · 5.4 KB
/
Copy pathci.yml
File metadata and controls
140 lines (131 loc) · 5.4 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
name: CI
on:
# PR-only. Every change reaches dev and master through a pull request, and
# the pull_request run tests the exact merge result — so one run gates each
# hop:
# • PR -> dev : gates feature/fix work landing on the integration branch
# • PR -> master : the required gate for a release (dev -> master, vX.Y.Z)
# No push triggers: a post-merge `push` run only re-tests what the PR run
# already validated (the redundant on-merge-to-dev run we were paying for).
# Direct pushes to a branch are not expected — the flow is PRs onto dev,
# then dev baked to master as a release.
pull_request:
branches: [master, dev]
jobs:
build-and-test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: debug
- os: ubuntu-latest
target: release
- os: macos-latest
target: debug
- os: macos-latest
target: release
steps:
- uses: actions/checkout@v4
- name: Build (${{ matrix.target }})
run: make ${{ matrix.target }}
# Tests build their own debug+ASan objects, so they only make sense after a
# debug build. Running `make test` after `make release` reuses the
# release-compiled src objects (no -DDEBUG), which omits DEBUG-only symbols
# like ray_check_null_invariant and fails to link. The release legs still
# verify the optimized build compiles + links; the debug legs run the tests.
- name: Test
if: matrix.target == 'debug'
run: make test
# Coverage-guided fuzz smoke pass over the untrusted-input decoders
# (parser, numeric scanners, wire-frame decoder). A healthy corpus finds
# nothing new in a minute, so any crash here is a genuine regression.
# Linux + clang only (the fuzzing runtime is not bundled on the macOS
# system toolchain). The working corpus is regenerated from the test
# suite each run and cached so coverage accretes across runs.
fuzz-smoke:
runs-on: ubuntu-latest
env:
# Hosted runner `-march=native` can expose transient CPU features that
# clang promotes to -Werror diagnostics; fuzzing does not need native ISA.
RAY_MARCH: x86-64
steps:
- uses: actions/checkout@v4
- name: Cache fuzz corpus
uses: actions/cache@v4
with:
path: fuzz/corpus
key: fuzz-corpus-${{ github.run_id }}
restore-keys: fuzz-corpus-
- name: Seed corpora
run: |
scripts/fuzz-seed-parse.sh
make debug # fuzz-seed-frames.sh drives a real server
scripts/fuzz-seed-frames.sh || true
- name: Fuzz smoke
run: make fuzz-smoke
- name: Upload crash artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: fuzz-crashes
path: |
crash-*
leak-*
timeout-*
oom-*
if-no-files-found: ignore
# ThreadSanitizer over the concurrency-sensitive suites (the lock-free
# pool/heap paths and the parallel operators). ASan and TSan are mutually
# exclusive, so this is a separate build flavour. TSAN_CORES=4 gives the
# work-stealing ring real contention to race against. Linux + clang only.
tsan:
runs-on: ubuntu-latest
env:
# Keep Clang off transient hosted-runner ISA features that become
# -Werror diagnostics before the TSan suites can run.
RAY_MARCH: x86-64
steps:
- uses: actions/checkout@v4
- name: TSan concurrency suites
run: |
for f in pool heap parallel stress; do
echo "::group::tsan -f $f"
make tsan-test TSAN_FILTER=$f || exit 1
echo "::endgroup::"
done
# Static analysis — ADVISORY (continue-on-error): the correctness-only
# check sets currently surface only false positives (GNU computed-goto
# label addresses, caller-guaranteed non-null params, defensive
# redundant-null-check heuristics), so this reports without gating.
# cppcheck runs whole-tree here (fast); the heavier clang-tidy pass
# (`make tidy`) runs locally and in the nightly workflow. Flip to a
# blocking gate once the baseline is annotated clean.
static-analysis:
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: Install cppcheck
run: sudo apt-get update && sudo apt-get install -y cppcheck
- name: cppcheck
run: make cppcheck
# Single stable check to require in branch protection, instead of the four
# brittle matrix names (which break if the matrix is renamed). `if: always()`
# makes this job run even when a matrix leg fails, and the explicit result
# check fails it — without that, a failed matrix would SKIP this job, and a
# skipped required check can be treated as passed, silently opening the gate.
# static-analysis is intentionally NOT in `needs` — it is advisory only.
ci-success:
needs: [build-and-test, fuzz-smoke, tsan]
if: always()
runs-on: ubuntu-latest
steps:
- name: Verify all required jobs passed
run: |
bt='${{ needs.build-and-test.result }}'
fz='${{ needs.fuzz-smoke.result }}'
ts='${{ needs.tsan.result }}'
echo "build-and-test: $bt fuzz-smoke: $fz tsan: $ts"
[ "$bt" = "success" ] && [ "$fz" = "success" ] && [ "$ts" = "success" ] || exit 1