Development¶
Guide for building, testing, and contributing to Signal Fish Server.
Prerequisites¶
- Rust 1.89.0 or later (see
rust-versioninCargo.toml) - No system libraries required for the default build
CI Tooling Parity¶
The devcontainer is expected to include the same core CLI tooling used by CI, pre-commit support scripts, and local test workflows, including:
yq(YAML code-block validation)taplo(TOML code-block validation)rg/ ripgrep (search tooling)fd(modern file discovery)- Docker CLI support in VS Code devcontainers
To keep rebuilds reliable on Windows + WSL + Docker Desktop and avoid known DNS failures in the feature install path:
.devcontainer/devcontainer.jsonkeepsdocker-outside-of-dockerconfigured with"moby": false..devcontainer/Dockerfileinstalls heavy cargo tools viacargo-binstall..devcontainer/post-create.shskipscargo check --all-featureswarm-up by default for faster startup. SetSIGNAL_FISH_WARM_CARGO_CHECK=1to enable it.
Validate parity at any time with:
Run full CI configuration validation (including tooling parity) with:
Building¶
Debug Build¶
Release Build¶
Optimized and stripped for production.
With Optional Features¶
# TLS support
cargo build --features tls
# Legacy full-mesh mode
cargo build --features legacy-fullmesh
# All features
cargo build --all-features
Running¶
Development¶
With Custom Config¶
# Using -c flag (not implemented - config.json is loaded by default)
# The server automatically looks for config.json in the working directory
cargo run
Note: The -c flag shown in some examples is not currently implemented. The server automatically loads
config.json from the working directory if it exists.
Validate Config¶
Print Resolved Config¶
Testing¶
Run All Tests¶
Test with All Features¶
Run Specific Test¶
Test with Output¶
Integration Tests¶
E2E Tests¶
Linting¶
Format Check¶
Apply Formatting¶
Clippy (Default)¶
Clippy (All Features)¶
Markdown Linting¶
Check markdown files for formatting issues, missing language identifiers, and inconsistencies:
Auto-fix markdown issues where possible:
Common markdown linting rules enforced by CI:
- MD040: All code blocks must have language identifiers (e.g.,
```bashnot just```) - MD046: Use fenced code blocks consistently
- MD013: Lines should not exceed 120 characters (except tables)
- MD044: Proper capitalization of technical terms (JavaScript, GitHub, WebSocket, etc.)
See .markdownlint.json for the complete rule configuration.
Spell Checking¶
Check for typos in code and documentation:
Technical terms that are commonly flagged as typos are configured in .typos.toml. If a legitimate
technical term is flagged, add it to the [default.extend-words] section.
Benchmarks¶
View results in target/criterion/report/index.html.
Code Coverage¶
Open coverage/index.html to view results.
Docker Development¶
Build Image¶
Build with Cache¶
docker build -t signal-fish-server --cache-from ghcr.io/ambiguous-interactive/signal-fish-server:latest .
Run Image¶
With Custom Config¶
Project Structure¶
signal-fish-server/
├── src/
│ ├── main.rs # Binary entry point
│ ├── lib.rs # Library crate root
│ ├── server.rs # EnhancedGameServer core
│ ├── auth/ # Authentication
│ ├── config/ # Configuration
│ ├── coordination/ # Room coordination
│ ├── database/ # Database trait + impl
│ ├── protocol/ # Message types
│ ├── security/ # TLS and crypto
│ ├── server/ # Room service logic
│ └── websocket/ # WebSocket handlers
├── tests/ # Integration tests
├── benches/ # Benchmarks
├── config.example.json # Example config
├── Cargo.toml
└── Dockerfile
Adding a New Feature¶
- Write tests first
- Implement the feature
- Run full test suite
- Lint and format
-
Update documentation
-
Add doc comments to public APIs
- Update CHANGELOG.md
- Update README.md if user-facing
Debug Logging¶
Set log level:
Trace level (very verbose):
Module-specific logging:
Profiling¶
CPU Profiling¶
Memory Profiling¶
Common Development Tasks¶
Add a Protocol Message¶
- Add enum variant to
ClientMessageorServerMessageinsrc/protocol/messages.rs - Implement serialization/deserialization
- Add handler in
src/server.rsorsrc/server/submodule - Add tests in
tests/integration_tests.rs - Update protocol documentation in
docs/protocol.md
Add a Configuration Option¶
- Add field to appropriate config struct in
src/config/ - Add default value in
src/config/defaults.rs - Add validation in
src/config/validation.rs - Update
config.example.json - Add tests for default, custom, and invalid values
Add a New Endpoint¶
- Add route in
src/websocket/routes.rs - Implement handler function
- Add tests in
tests/e2e_tests.rs - Update endpoint documentation
Testing Strategy¶
Unit Tests¶
Place in the same file as the code:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_room_code_generation() {
let code = generate_room_code(6);
assert_eq!(code.len(), 6);
}
}
Integration Tests¶
Place in tests/ directory:
#[tokio::test]
async fn test_create_and_join_room() {
let server = create_test_server().await;
// Test multi-step flows
}
E2E Tests¶
Test full WebSocket flows:
#[tokio::test]
async fn test_websocket_connection() {
let addr = spawn_test_server().await;
let ws = connect_websocket(&addr).await;
// Test complete session
}
MSRV and Toolchain Management¶
Minimum Supported Rust Version (MSRV)¶
The project MSRV is defined in Cargo.toml (rust-version = "1.89.0"). This is the oldest
Rust compiler version guaranteed to build the project.
Verifying MSRV Consistency¶
Before committing changes that update the MSRV, verify all configuration files are consistent:
This script validates that the following files all use the same Rust version:
Cargo.toml(source of truth)rust-toolchain.toml(developer toolchain)clippy.toml(MSRV-aware lints)Dockerfile(production build environment)
Updating MSRV¶
When a dependency requires a newer Rust version, follow the MSRV update checklist:
- Update all configuration files:
Cargo.toml:rust-version = "1.XX.0"rust-toolchain.toml:channel = "1.XX.0"clippy.toml:msrv = "1.XX.0"-
Dockerfile:FROM rust:1.XX-bookworm -
Verify consistency:
- Test with new MSRV:
- Update documentation:
- Update this file's Prerequisites section
- Update
CHANGELOG.md - Document reason for MSRV bump in commit message
See MSRV Management for comprehensive MSRV management guidance.
Continuous Integration¶
The project uses GitHub Actions for CI. All PRs must pass:
cargo fmt --check- Code formattingcargo clippy --all-targets --all-features -- -D warnings- Rust lintingcargo test --all-features- All testscargo build --release- Release build- MSRV verification - Validates MSRV consistency and builds with exact MSRV
- Markdown linting - Validates markdown files for formatting and best practices
- Spell checking - Checks for typos in code and documentation
- YAML validation - Validates workflow files and configuration
- Actionlint - Validates GitHub Actions workflow syntax
Running All CI Checks Locally¶
Before pushing, run all CI checks locally:
# Format check
cargo fmt --check
# Clippy
cargo clippy --all-targets --all-features -- -D warnings
# Tests
cargo test --all-features
# Markdown linting
./scripts/check-markdown.sh
# Spell checking (install with: cargo install typos-cli)
typos
# MSRV consistency
./scripts/check-msrv-consistency.sh
# Fast hook-equivalent policy checks over unstaged work
pwsh -NoLogo -NoProfile -NonInteractive -File scripts/hooks/pre-commit.ps1 -Worktree
pwsh -NoLogo -NoProfile -NonInteractive -File scripts/hooks/pre-push.ps1 -Worktree
# Canonical local preflight, including hook readiness, LLM policy checks, markdown,
# workflow hygiene, docs/changelog consistency, and policy test suites.
./scripts/run-local-ci.sh
Enable git hooks as a final last-resort guard:
Release Process¶
- Update version in
Cargo.toml - Update
CHANGELOG.md - Run full test suite:
cargo test --all-features - Build release:
cargo build --release - Tag release:
git tag v0.x.x - Push:
git push origin v0.x.x
Next Steps¶
- Library Usage - Embedding the server
- Architecture - System design