Skip to content

Latest commit

 

History

History
151 lines (104 loc) · 5.17 KB

File metadata and controls

151 lines (104 loc) · 5.17 KB

Contributing to RustMail

Thank you for your interest in contributing to RustMail! This document provides guidelines and instructions for contributing.

Getting Started

Prerequisites

Development Setup

git clone https://github.com/rustmailapp/rustmail.git
cd rustmail

# Install UI dependencies
cd ui && pnpm install && cd ..

# Build everything
make build

# Or run in development mode (auto-reload)
make dev

Useful Commands

Command Description
make dev Run backend + frontend in dev mode
make build Production build (UI + Rust)
make test Run all Rust tests
make lint Clippy + TypeScript type check
make fmt Format Rust + TypeScript code
make check Cargo check + TypeScript check
make clean Remove build artifacts

Reporting Bugs

Before filing a bug report, please check existing issues. Then use the Bug Report template — it will guide you through the required information.

Submitting Changes

Branch Naming

  • feat/short-description — New features
  • fix/short-description — Bug fixes
  • refactor/short-description — Code restructuring
  • docs/short-description — Documentation changes

Code Style

Rust:

  • Run cargo fmt before committing
  • Zero clippy warnings: cargo clippy --all-targets -- -D warnings
  • No unwrap() in library crates (crates/rustmail-smtp, crates/rustmail-storage, crates/rustmail-api)
  • unwrap() is acceptable in tests and rustmail-server (the binary)
  • Error handling: thiserror in libraries, anyhow in the binary
  • Async everywhere — no blocking calls on the tokio runtime

TypeScript (UI):

  • Run pnpm exec prettier --write . before committing
  • Type checking must pass: pnpm exec tsc -b

Commit Messages

Write atomic commits with descriptive messages:

feat: add webhook retry with exponential backoff

fix: prevent FTS5 injection via unsanitized search input

refactor: extract SMTP session handling into dedicated module

docs: add reverse proxy deployment guide

Pull Request Process

  1. Fork the repository and create your branch from master
  2. Make your changes with tests where applicable
  3. Ensure all checks pass: make lint && make test
  4. Open a pull request with a clear description of the change
  5. Link any related issues

What Makes a Good PR

  • One logical change per pull request
  • Tests for new functionality
  • No unrelated formatting or refactoring changes
  • Clear description of why the change is needed

Adding a User-Facing Feature

When a PR introduces a new user-visible feature (CLI flag, API endpoint, UI capability), tick each item that applies:

  • Row added to the features table in README.md
  • Feature page under docs/features/ (or relevant subsection)
  • docs/api.yaml updated if the feature exposes an HTTP endpoint
  • docs/configuration/cli-flags.md updated if a CLI flag changed
  • Feature card added to rustmailapp/rustmail-www (homepage grid) if it's a headline capability
  • Commit message uses the feat: Conventional Commit prefix so it shows up in the release changelog

Releasing

Releases use cargo-release. Workspace config lives in Cargo.toml under [workspace.metadata.release].

master is protected (required status checks) and cannot be pushed to directly, so the flow is:

# 1. From a clean master, run the version bump.
#    Bumps workspace version, refreshes Cargo.lock, commits as "chore: Release",
#    creates tag v<new>, attempts to push (which will be rejected by branch protection).
cargo release patch --execute --no-confirm

# 2. Move the local commit onto a branch and reset master.
git branch chore/bump-<new>
git tag -d v<new>
git reset --hard origin/master
git push -u origin chore/bump-<new>

# 3. Open a PR, wait for CI, merge.
gh pr create --base master --head chore/bump-<new> --title "chore: bump version to <new>"

# 4. After merge, tag the merge commit and push the tag.
git fetch
git tag v<new> origin/master
git push origin v<new>

The tag push triggers .github/workflows/release.yml, which builds multi-platform binaries, Docker images, and a GitHub Release with a changelog auto-generated from conventional commits since the previous tag.

Use cargo release minor or cargo release major for non-patch bumps. All workspace crates have publish = false; cargo-release skips crates.io automatically.

Architecture

See the Architecture page for crate layout, data flow, and design decisions.

Dependencies

Adding a new dependency requires justification. Prefer:

  • Well-maintained crates (recent activity, >100 stars or part of a known ecosystem)
  • Crates with minimal transitive dependencies

License

By contributing to RustMail, you agree that your contributions will be licensed under the MIT or Apache 2.0 license, at the user's choice.