Skip to content

Contributing1.x

Frontend and backend must share:

Terminal window
export CONFIG_PATH=/where/to/create/database/
export FRONTEND_BACKEND_API_KEY=$(head -c 32 /dev/urandom | hexdump -ve '1/1 "%.2x"')
export BACKEND_URL=http://localhost:5000

Optional: THREADPOOL_MIN_THREADS, THREADPOOL_MAX_THREADS.

Terminal window
# Terminal 1
./scripts/run-backend.sh
# Terminal 2
cd frontend && npm install && npm run dev

UI: http://localhost:5173 → proxies to backend :5000.

run-backend.sh defaults LOG_LEVEL=Debug and LOG_BUFFER_SIZE=2000 for local debugging. The Docker image sets LOG_LEVEL=warning; LOG_BUFFER_SIZE is unset and the backend defaults to 2000. The script also enables the contributor-only admin API reference locally: sign in and use http://localhost:5173/scalar/ through the frontend. The backend’s /openapi/admin.json endpoint requires x-api-key when accessed directly. Set ENABLE_API_DOCS=false to disable it; Docker keeps the reference disabled unless explicitly enabled.

After changing a frontend-used admin endpoint, refresh the committed contract with ./scripts/export-admin-openapi.sh and regenerate types with cd frontend && npm run generate:api.

Stream tracing is off by default — toggle it from Settings → Support, or export STREAM_TRACE_EVENTS=20000 for an always-on capture.

  1. Add Usenet + WebDAV credentials in Settings.
  2. Queue an .nzb, play via Explore or rclone against the frontend port.
  3. Dump stream traces with ./scripts/dump-stream-trace.sh.
Terminal window
cd frontend
npm run lint
npm run format:check
npm run typecheck
npm run build
npm test
npm run test:coverage
cd ..
dotnet test tests/NzbWebDAV.Tests/NzbWebDAV.Tests.csproj -c Release
dotnet test \
tests/NzbWebDAV.ArchitectureTests/NzbWebDAV.ArchitectureTests.csproj \
-c Debug

The backend checks also run the quality-ratchet scripts and dotnet format whitespace --verify-no-changes; see CONTRIBUTING.md for the exact commands.

Branch protection on main should require CI / Required quality gate (plus Documentation build and the three CodeQL language jobs). That aggregate check covers frontend lint/typecheck/build/tests, backend format/build/tests, PostgreSQL migrations, native yEnc jobs, quality ratchets, HTTP contracts, and the Docker runtime smoke when image inputs change.

Full details, local commands, and ratchet/allowlist rules: repository CONTRIBUTING.md and AGENTS.md.

Pull request CI compares deterministic fields from the streaming, SAB API and NNTP whole-path reports (transportRequests, transportBytes, SAB rowsReturned / totalCount / dbCommands) against backend.Benchmarks/Baselines/. Timing never blocks a PR.

If that gate fails because you intentionally changed transport or query shape, update the matching baseline JSON in the same PR (and any adjacent count constants in tests/NzbWebDAV.Tests/Streams/RepeatableStreamingBenchmarkCoverageTests.cs):

Terminal window
BENCH=backend.Benchmarks/NzbWebDAV.Benchmarks.csproj
BASE=backend.Benchmarks/Baselines
dotnet run --project $BENCH -c Release -- \
--streaming-report --json /tmp/streaming.json
dotnet run --project $BENCH -c Release -- \
--sab-api-report --json /tmp/sab-api.json
dotnet run --project $BENCH -c Release -- \
--nntp-whole-path-report --set quick --json /tmp/nntp-whole-path.json
python3 scripts/check-performance-baseline.py \
--candidates /tmp/streaming.json \
--write-baseline $BASE/streaming-baseline.json
python3 scripts/check-performance-baseline.py \
--candidates /tmp/sab-api.json \
--write-baseline $BASE/sab-api-baseline.json
python3 scripts/check-performance-baseline.py \
--candidates /tmp/nntp-whole-path.json \
--write-baseline $BASE/nntp-whole-path-baseline.json

Nightly Performance runs check latency / throughput / CPU against floored 3× envelopes. To refresh those envelopes: Actions → Performance → Run workflow → rebaseline. The workflow opens a PR and does not merge it. PRs created with GITHUB_TOKEN do not trigger CI — close/reopen (or push) to run checks.