Contributing to Rigatoni
Thank you for your interest in contributing to Rigatoni!
Table of contents
- TOC
Code of Conduct
Be respectful, inclusive, and professional in all interactions. We’re here to build great software together.
Getting Started
Prerequisites
- Rust 1.88+ - Install Rust
- Git - Install Git
- MongoDB - For testing (or use Docker)
- LocalStack - For S3 testing (optional)
Fork and Clone
- Fork the repository on GitHub
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/rigatoni.git
cd rigatoni
- Add upstream remote:
git remote add upstream https://github.com/valeriouberti/rigatoni.git
Development Workflow
1. Create a Branch
git checkout -b feature/your-feature-name
# or
git checkout -b fix/your-bug-fix
Branch Naming:
feature/- New featuresfix/- Bug fixesdocs/- Documentation changesrefactor/- Code refactoringtest/- Test additions/improvements
2. Make Changes
Write your code following our coding standards.
3. Run Tests
# Run all tests
cargo test --workspace --all-features
# Run specific crate tests
cargo test -p rigatoni-core --all-features
# Run with logging
RUST_LOG=debug cargo test
4. Run Quality Checks
We provide a pre-push script that runs all CI checks:
# Linux/macOS
./scripts/pre-push.sh
# Windows PowerShell
.\scripts\pre-push.ps1
This runs:
- Formatting checks
- Clippy linting
- Tests (default, all features, no features)
- Documentation build
- Security audit
5. Commit Changes
Follow Conventional Commits:
git add .
git commit -m "feat: add support for Kafka destination"
git commit -m "fix: resolve S3 upload timeout issue"
git commit -m "docs: update getting started guide"
Commit Message Format:
<type>: <description>
[optional body]
[optional footer]
Types:
feat- New featurefix- Bug fixdocs- Documentation onlystyle- Code style changes (formatting, etc.)refactor- Code refactoringtest- Adding testschore- Maintenance tasks
6. Push and Create PR
git push origin feature/your-feature-name
Then create a Pull Request on GitHub.
Pull Request Guidelines
PR Title
Follow the same format as commit messages:
feat: add Kafka destination support
fix: resolve S3 upload timeout
docs: improve getting started guide
PR Description
Provide a clear description:
## Summary
Brief description of what this PR does.
## Changes
- List of specific changes
- Another change
- Yet another change
## Testing
How you tested the changes:
- [ ] Unit tests added/updated
- [ ] Integration tests passing
- [ ] Manually tested with [describe scenario]
## Related Issues
Closes #123
Relates to #456
PR Checklist
Before submitting, ensure:
- Code follows project style
- Tests added for new functionality
- All tests passing
- Documentation updated
- Changelog updated (if applicable)
- No warnings from Clippy
- Code formatted with
rustfmt - Pre-push script passes
Coding Standards
Rust Style
Follow the Rust Style Guide:
# Format code
cargo fmt --all
# Check formatting
cargo fmt --all -- --check
Clippy Lints
Fix all Clippy warnings:
# Run Clippy
cargo clippy --workspace --all-features -- -D warnings
# Strict mode (what CI uses)
cargo clippy --workspace --all-features -- \
-D warnings \
-D clippy::all \
-D clippy::pedantic
Documentation
Document all public APIs:
/// Writes a batch of events to the destination.
///
/// # Arguments
///
/// * `events` - Slice of change events to write
///
/// # Errors
///
/// Returns `DestinationError` if the write fails.
///
/// # Examples
///
/// ```
/// # use rigatoni_core::destination::Destination;
/// # async fn example(destination: &mut impl Destination, events: &[ChangeEvent]) {
/// destination.write_batch(events).await.unwrap();
/// # }
/// ```
#[async_trait]
async fn write_batch(&mut self, events: &[ChangeEvent]) -> Result<(), DestinationError>;
Error Handling
Use thiserror for custom errors:
#[derive(Debug, thiserror::Error)]
pub enum MyError {
#[error("invalid configuration: {0}")]
InvalidConfig(String),
#[error("network error")]
Network(#[from] std::io::Error),
#[error("serialization failed: {0}")]
Serialization(#[from] serde_json::Error),
}
Testing
Write comprehensive tests:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic_functionality() {
// Arrange
let input = 42;
// Act
let result = process(input);
// Assert
assert_eq!(result, 84);
}
#[tokio::test]
async fn test_async_functionality() {
let result = async_process().await;
assert!(result.is_ok());
}
}
License Headers
All files must include the Apache-2.0 license header:
// Copyright 2025 Rigatoni Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
Testing
Unit Tests
Located in #[cfg(test)] modules:
# Run unit tests
cargo test --lib
# Run specific test
cargo test test_name
Integration Tests
Located in tests/ directory:
# Run integration tests
cargo test --test '*'
# Run specific integration test
cargo test --test s3_integration_test
With LocalStack
Start LocalStack:
cd rigatoni-destinations
docker-compose up -d
Run S3 integration tests:
cargo test --test s3_integration_test --features s3,json,gzip -- --ignored
Test Coverage
We aim for >80% test coverage:
# Install tarpaulin
cargo install cargo-tarpaulin
# Generate coverage report
cargo tarpaulin --workspace --all-features --out Html
Adding New Features
New Destination
- Create module:
rigatoni-destinations/src/newdest/ - Implement
Destinationtrait - Add feature flag in
Cargo.toml - Write tests
- Add documentation
- Add example
Example Structure:
rigatoni-destinations/src/newdest/
├── mod.rs # Public exports
├── destination.rs # Destination implementation
├── config.rs # Configuration
└── error.rs # Error types
New Source
- Create module:
rigatoni-core/src/sources/newsource/ - Implement source logic
- Add feature flag
- Write tests
- Add documentation
Documentation
API Documentation
Write comprehensive rustdoc comments:
# Generate docs
cargo doc --no-deps --all-features --open
User Documentation
Update markdown files in docs/:
docs/getting-started.md- Getting started guidedocs/architecture.md- Architecture docsdocs/guides/- Task-specific guides
Examples
Add examples to examples/ directory:
cargo run --example new_example --features required-features
Release Process
(For maintainers)
Version Bump
- Update version in
Cargo.toml:
[workspace.package]
version = "0.2.0"
-
Update
CHANGELOG.md -
Commit and tag:
git commit -am "chore: bump version to 0.2.0"
git tag -a v0.2.0 -m "Release v0.2.0"
git push --tags
Publishing
# Dry run
cargo publish --dry-run -p rigatoni-core
# Publish (in dependency order)
cargo publish -p rigatoni-core
# Wait 2-3 minutes for crates.io to index
cargo publish -p rigatoni-destinations
cargo publish -p rigatoni-stores
Getting Help
Communication Channels
- Issues - GitHub Issues
- Discussions - GitHub Discussions
- Email - valeriouberti@icloud.com
Issue Templates
Use the appropriate template when creating issues:
- Bug Report - For reporting bugs
- Feature Request - For proposing new features
- Question - For asking questions
Where to Start
Good first issues are labeled good first issue:
Common Tasks
Add a Dependency
- Add to
workspace.dependenciesin rootCargo.toml:
[workspace.dependencies]
new-crate = "1.0"
- Reference in member crate:
[dependencies]
new-crate = { workspace = true }
Add a Feature Flag
- Update member
Cargo.toml:
[features]
new-feature = ["dep:some-crate"]
[dependencies]
some-crate = { workspace = true, optional = true }
- Use conditional compilation:
#[cfg(feature = "new-feature")]
pub mod new_feature;
Update Dependencies
# Check outdated dependencies
cargo outdated
# Update within semver
cargo update
# Update to latest (may break)
cargo upgrade
Troubleshooting
Tests Failing
# Clean and rebuild
cargo clean
cargo test
# Check for outdated dependencies
cargo update
Clippy Errors
# Auto-fix where possible
cargo clippy --fix --workspace --all-features
Formatting Issues
# Auto-format
cargo fmt --all
Recognition
Contributors will be:
- Listed in
CONTRIBUTORS.md - Mentioned in release notes
- Given credit in commit messages with
Co-authored-by:
License
By contributing to Rigatoni, you agree that your contributions will be licensed under the Apache License 2.0.
Thank you for contributing to Rigatoni! 🍝
Questions? Open a discussion or issue.