Thanks for contributing! Here's how to get started:
- Open an issue to discuss the proposed change
- Create a branch from
main - Implement the change with tests
- Make sure
bundle exec rakepasses (lint + tests) - Open a pull request targeting
main
git clone git@github.com:fluence-eu/filterable-ruby.git
cd filterable-ruby
bin/setupRequires Ruby 3.2+.
bundle exec rake # default task: specs + rubocop
bundle exec rspec # specs only
bundle exec rubocop # lint only
bundle exec rubocop -A # auto-fix linting
bin/console # interactive promptThe test suite runs against an in-memory SQLite database — nothing to set up.
Coverage is enforced via SimpleCov (minimum_coverage 90); skip it locally with
SKIP_COVERAGE=true bundle exec rspec when iterating.
This project follows Conventional Commits.
<type>(<scope>): <description>
[body]
[footer(s)]
| Type | Description |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation only changes |
style |
Formatting changes (whitespace, commas, etc.) — no logic |
refactor |
Code change that neither fixes a bug nor adds a feature |
perf |
Performance improvement |
test |
Adding or updating tests |
build |
Changes to build system or dependencies |
ci |
CI/CD configuration changes |
chore |
Other changes that don't modify source or tests |
revert |
Revert a previous commit |
- Use imperative mood ("add", not "adds" or "added")
- No capital letter at the start
- No period at the end
- Maximum 72 characters
- Use bullet points with
-for multiple items - Explain why, not what (the diff speaks for itself)
Non-backward-compatible changes must be flagged with:
- A
!after the type/scope:feat(sortable)!: change sort param format - And/or a
BREAKING CHANGE:footer in the body
feat(datable): add `since` bound
fix(sortable): ignore undeclared attributes instead of raising
- a bogus `filters[sort]` term used to leak an arbitrary column
- whitelist against the declared sortable attributes
main— default branch. All feature branches are created from here, and all PRs target this branch.- Never push directly to
main— always create a feature branch and open a PR.
- Same format as commits:
<type>(<scope>): <description> - Under 72 characters
| Level | Criteria | Description requirements |
|---|---|---|
| Critical | Breaking change, security fix | Full description — summary, changes, impact, rollback, how to test |
| Major | New feature, significant refactor | Summary + changes + how to test |
| Minor | Small bug fix, config tweak, dependency bump | Summary + changes (1-2 lines each) |
| Trivial | Documentation, formatting, comment update | One-line summary is enough |
## Summary
<What and why in 2-3 sentences>
## Changes
- <change 1>
- <change 2>
## How to Test
1. <step 1>
2. <step 2>For Critical PRs, also add an ## Impact and a ## Rollback Plan section.
## Summary
<One sentence>
## Changes
- <change 1>A one-line summary in the PR body is sufficient.
- One topic per PR — don't mix unrelated changes
- All tests must pass (
bundle exec rake) - New code must include tests
- Never commit secrets or credentials
frozen_string_literal: trueon every Ruby file- Strings: single quotes (unless interpolation is needed)
- RuboCop: no rule disabling without justification
- YARD-style doc comments on public methods
- Version lives in
lib/filterable/version.rb— do not bump it except for a release
When using AI tools (Claude, Copilot, etc.) to generate commits or PRs:
- Classify first — determine if the change is critical, major, minor, or trivial
- Focus on the "why" — the diff already shows the "what"
- Skip boilerplate — don't add empty sections or placeholder text
The person opening the PR takes full responsibility for the code. Before submitting:
- I have read and understood every line of code in this PR
- I can explain why each change was made
- I have tested the changes locally
Do not add AI co-author lines (Co-Authored-By), "Generated with" footers, or
any AI attribution in commits or PR descriptions.
By contributing, you agree that your contributions will be licensed under the MIT License.