Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions .github/workflows/fuzz.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
# Nightly fuzzing of the internet-facing parsers.
# Fuzzing of the internet-facing parsers: on every push to master that touches
# them, and by hand (Actions tab -> fuzz -> Run workflow, with a longer fuzztime).
#
# `go test ./...` only ever runs the SEED corpora of these targets - nothing in
# the repo actually fuzzes. This does, one target per job (Go permits only one
# -fuzz target per invocation), and caches the generated corpus so coverage
# compounds night over night instead of restarting from the seeds each time.
# compounds run over run instead of restarting from the seeds each time.
#
# Never on a timer: the repo can sit idle for months, and GitHub disables any
# workflow with a schedule after 60 days without activity - at which point it
# stops running on push too.
#
# None of these packages import the root package, so - unlike every job in
# ci.yml - this workflow needs no frontend/dist.
name: fuzz

on:
schedule:
- cron: "0 3 * * *"
push:
branches: [master]
paths:
- "internal/control/**"
- "internal/link/**"
- "internal/mc/**"
- "internal/relay/**"
- "go.mod"
- "go.sum"
- ".github/workflows/fuzz.yml"
workflow_dispatch:
inputs:
fuzztime:
Expand Down Expand Up @@ -52,8 +65,8 @@ jobs:
cache: false

# Go writes generated corpus entries under $GOCACHE/fuzz. Restoring them
# is what turns 8 nightly 5-minute runs into a corpus that grows, rather
# than 8 cold starts.
# is what turns each run's 5 minutes per target into a corpus that grows,
# rather than a cold start from the seeds every time.
- name: resolve GOCACHE
id: gocache
run: echo "dir=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
Expand Down
17 changes: 12 additions & 5 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ on:
push:
branches: [master]
pull_request:
schedule:
# Mondays 06:00 UTC - catches newly-disclosed CVEs in unchanged code.
- cron: "0 6 * * 1"
# Deliberately no schedule. The repo can sit idle for months, and GitHub
# disables any workflow with a schedule after 60 days without activity - and
# a disabled workflow skips push and pull_request too, so every gate here goes
# dark. To catch CVEs disclosed in unchanged code after a quiet spell, run it
# by hand (Actions tab -> security -> Run workflow).
workflow_dispatch:

permissions:
contents: read
Expand Down Expand Up @@ -89,7 +92,10 @@ jobs:
# embed target has to exist for the windows pass or every package fails
# to load.
- run: npm ci --prefix frontend && npm run build --prefix frontend
- run: go install golang.org/x/vuln/cmd/govulncheck@latest
# Pinned, never @latest: @latest raised its Go floor past go.mod's and the
# install failed on every run until the toolchain caught up. A pin behaves
# the same after months idle; bump it alongside go.mod's go line.
- run: go install golang.org/x/vuln/cmd/govulncheck@v1.9.0
# Reports only vulnerabilities actually reachable from our call graph.
# Twice, because reachability is per-GOOS: linux sees only the headless
# build (gui.go is !linux), so the shipped Windows build, Wails and all,
Expand Down Expand Up @@ -165,7 +171,8 @@ jobs:
- name: stub frontend/dist for go:embed
run: mkdir -p frontend/dist && touch frontend/dist/index.html
# Install for the HOST (no GOOS here, or we'd build a Windows gosec binary).
- run: go install github.com/securego/gosec/v2/cmd/gosec@latest
# Pinned for the same reason as govulncheck above.
- run: go install github.com/securego/gosec/v2/cmd/gosec@v2.30.0
# GOOS=windows on a linux runner is the trick: it analyses the build we
# actually ship (pipe ACL, service/elevation, netsh) — which the !windows
# build hides — while still emitting linux-style paths. A gosec run ON
Expand Down
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@ lower the floor to go green), `golangci-lint` (`.golangci.yml`), a TODO/FIXME ba
(plan jargon + attribution trailers anywhere in a PR — `docs/agent/naming.md`), and a
stale-`frontend/wailsjs` check. `.github/workflows/security.yml`: CodeQL, govulncheck,
gitleaks, dependency-review, npm audit (gosec/zizmor/Scorecard are advisory → Security
tab). `.github/workflows/fuzz.yml` fuzzes the parsers nightly;
tab). `.github/workflows/fuzz.yml` fuzzes the parsers on master pushes that touch them —
no workflow runs on a timer (GitHub disables scheduled ones in an idle repo);
`.github/workflows/release.yml` builds a tag into a **draft** release.
Must-never-happen at edit time → hook (`.claude/settings.json`: `frontend/wailsjs`
write-block, per-edit gofmt check). Doc accuracy → the `internal/doccheck` citation
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -474,8 +474,8 @@ handshake/VarInt/packet, login sniffer, offline responder, pairing code, sniff t
loopback e2e suite that is goroutine-leak-checked with `goleak` and enforces the
throughput/latency floor and per-transport twins described [above](#head-of-line-blocking-and-how-each-plane-answers-it).

`go test` runs the fuzz **seed corpora**; the targets are actually fuzzed nightly
([`fuzz.yml`](.github/workflows/fuzz.yml)). Every push also runs the race detector, the
`go test` runs the fuzz **seed corpora**; the targets are actually fuzzed on every push
to master that touches a parser ([`fuzz.yml`](.github/workflows/fuzz.yml)). Every push also runs the race detector, the
burst floor, CodeQL, and `govulncheck` — see [`ci.yml`](.github/workflows/ci.yml) and
[`security.yml`](.github/workflows/security.yml).

Expand Down
Loading
Loading