Thanks for considering a contribution to Bump Service! This document covers the practical steps for getting a change built, tested, and submitted.
# Clone and enter the repo
git clone https://github.com/codevalley/bump.git
cd bump-service
# Build
cargo build
# Run the service locally (binds to localhost:8080 by default)
cargo runCopy sample.env to .env if you want to override matching defaults
locally — dotenv loads it automatically on startup. Every BUMP_*
variable is optional; unset ones fall back to the per-field defaults in
src/config.rs.
Run these locally — cargo build and cargo test mirror what CI
(.github/workflows/rust.yml) checks on every push and pull request against
main:
# Build
cargo build --verbose
# Run the full test suite (unit tests + tests/integration/)
cargo test --verbose
# Lint — address warnings before submitting
cargo clippy
# Format
cargo fmtCI currently runs only cargo build and cargo test; clippy and fmt
aren't enforced in the workflow yet, but please run them anyway — clean,
formatted code makes review faster.
- Unit tests live alongside the code they test (
#[cfg(test)] mod testsblocks insrc/, e.g.src/config.rs,src/queue/q_matching.rs). - Integration tests live in
tests/integration/and compile into a single Cargo test binary rooted attests/integration/main.rs. They exerciseMatchingServiceend-to-end (process_send/process_receive/process_bump) for matching correctness, concurrency, and known regressions — seetests/integration/bump_matching.rsandtests/integration/regressions.rs. Add new coverage here when you touch queue or matching behavior.
- The unified endpoint is
POST /bump/bump, notPOST /bump. Every route is nested underweb::scope("/bump")insrc/main.rs, and the handler itself is registered as#[post("/bump")]insrc/api.rs— so the two prefixes stack./bump/send,/bump/receive,/bump/health,/bump/timestamp, and/bump/weatherfollow the same pattern. - Wire format is snake_case, not camelCase. Request/response JSON fields
(
matching_data,custom_key,sender_id,receiver_id, etc.) use serde's default snake_case field names — there's no#[serde(rename_all = "camelCase")]anywhere insrc/models.rs. Don't sendmatchingDataorcustomKey; the server will reject or silently ignore them. - A plain timeout is an HTTP 408, not a 200 with
status: "timeout". Seesrc/error.rs—BumpError::Timeoutmaps toHttpResponse::RequestTimeout(). - Client-supplied
ttlis clamped to 30000ms (30s) and JSON request bodies are capped at 1 MB — seesrc/service.rsand theweb::JsonConfiglimit insrc/main.rs.
Open a GitHub issue with a clear, descriptive title and enough detail to
reproduce or evaluate the request: steps to reproduce, expected vs. actual
behavior, and relevant logs (RUST_LOG=debug gives more detail locally).
- Keep PRs focused; avoid bundling unrelated changes.
- Use the present tense and imperative mood in commit messages ("Add feature", not "Added feature").
- Make sure
cargo build,cargo test,cargo clippy, andcargo fmtare clean before requesting review.
Email codevalley@live.com with questions.