Contributing

Contribution guide for the Pumpkin Hub project.

Welcome
All contributions are welcome, whether it's a bug fix, a new feature, a documentation improvement or a bug report. Please take a moment to read this guide before submitting your contribution.

Git Workflow

  1. Fork the repository on GitHub
  2. Clone your fork locally
  3. Create a branch from develop (never from master)
  4. Implement changes with atomic commits
  5. Push the branch and open a Pull Request targeting develop
# Workflow example
git clone https://github.com/YOUR-USERNAME/pumpkin-hub.git
cd pumpkin-hub
git checkout -b feature/my-feature develop

# ... development ...

git push origin feature/my-feature

Branches

BranchRole
masterStable production, tagged releases
developIntegration, PR base
feature/*New features
fix/*Bug fixes
docs/*Documentation improvements

Code Conventions

Rust (API)

TypeScript (Frontend)

General Principles

Commit Messages

Commit messages follow the Conventional Commits convention:

type(scope): short description

[optional body]

[optional footer]

Allowed Types

TypeDescription
featNew feature
fixBug fix
docsDocumentation only
styleFormatting, semicolons (no logic change)
refactorRefactoring without behavior change
testAdding or modifying tests
choreMaintenance tasks (CI, deps, config)

Common Scopes

api, frontend, docs, docker, ci, auth, plugins, search, dashboard, api-keys, notifications

Examples

feat(api): add plugin CRUD endpoints
fix(frontend): correct search input focus state
docs: update roadmap with Phase 2
chore(ci): add Rust cache to workflow

Pull Requests

Tip
For significant changes, open an issue first to discuss the approach before starting the implementation. This avoids wasted effort and enables early feedback.

Code Quality

Before submitting, make sure that:

Backend

# Formatting
cargo fmt --all -- --check

# Static analysis
cargo clippy -- -D warnings

# Tests
cargo test

# Coverage (LCOV output for SonarQube)
cargo tarpaulin --out lcov

Frontend

# Linting (zero warnings enforced)
npm run lint

# Type-checking
npx tsc --noEmit

# Build
npm run build

# Tests with coverage (hard gate: lines 80%, functions 80%, branches 75%)
npm run test:coverage
Important
CI blocks the merge if any of these checks fail. Coverage thresholds are enforced as hard gates — PRs that drop below the minimums will not pass CI. Run them locally before pushing to save time.
SonarQube
Both frontend and backend coverage reports are uploaded to SonarQube for unified code quality analysis. The combined report runs automatically after both CI stages complete.

Add a New Feature (API)

Procedure to add a new route module:

  1. Create the file api/src/routes/{feature}.rs
  2. Implement handlers using AppState and AppError types
  3. Declare the module in routes/mod.rs (mod {feature};)
  4. Merge routes into v1_routes()
  5. Write unit and/or integration tests
// api/src/routes/plugins.rs
use axum::{routing::get, Json, Router};
use crate::state::AppState;

pub fn routes() -> Router<AppState> {
    Router::new()
        .route("/plugins", get(list_plugins))
}

async fn list_plugins() -> Json<serde_json::Value> {
    // implementation
    todo!()
}
// api/src/routes/mod.rs
mod health;
mod plugins; // <-- add here

fn v1_routes() -> Router<AppState> {
    Router::new()
        .merge(health::routes())
        .merge(plugins::routes()) // <-- and here
}