Contributing
Thanks for contributing! Here's how to get started:
- Open an issue to discuss the proposed change
- Fork the repo and create a branch from
main - Implement the change with tests
- Make sure
bundle exec fluence-ci allpasses - Open a pull request targeting
main
Setup
git clone git@github.com:fluence-eu/mosaic-sdk.git
cd mosaic-sdk
bin/setup
Requires Ruby 3.2+.
Development
Running tests and linting
bundle exec fluence-ci all # full catalog (lint + security + codequality + tests)
bundle exec fluence-ci lint # rubocop only
bundle exec fluence-ci tests # minitest only (auto-detected from test/test_helper.rb)
bundle exec rubocop -a # auto-fix linting (no fluence-ci equivalent)
Interactive console
APPCENTER_CLIENT_ID=your_id APPCENTER_CLIENT_SECRET=your_secret bin/console
Commit Convention
This project follows Conventional Commits.
Format
<type>(<scope>): <description>
[body]
[footer(s)]
Types
| 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 |
Scope
Optional — indicates the area of the project affected:
feat(clone): add create methodfix(nav): fix parameter mapping in createrefactor(base): extract build_instance logic
Description
- Imperative mood ("add", not "adds" or "added")
- No capital letter at the start
- No period at the end
- Maximum 72 characters
Body (optional)
- Use bullet points with
-for multiple items - Explain why, not what (the diff speaks for itself)
Breaking Changes
Non-backward-compatible changes must be flagged with:
- A
!after the type/scope:feat(nav)!: change create parameters - And/or a
BREAKING CHANGE:footer in the body
Examples
feat(clone): add create method
fix(nav): fix parameter mapping in create
- unit was not mapped to market_price_kind
- pricing_method was not mapped to market_price_type
refactor(base): extract CSV parsing logic
Move parsing functions into a dedicated concern
to improve reusability across services.
feat(nav)!: change create parameters
BREAKING CHANGE: pricing_method replaces the old type parameter,
clients must update their calls.
Branching Model
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.
Pull Request Convention
PR Title
- Same format as commits:
<type>(<scope>): <description> - Under 72 characters
PR Classification
| Level | Criteria | Description requirements |
|---|---|---|
| Critical | Breaking change, security fix, data migration | Full description — summary, changes, impact, rollback plan, how to test |
| Major | New feature, new endpoint, 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 |
PR Description by Level
Critical / Major
## 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:
## Impact
- <what parts of the system are affected>
## Rollback Plan
- <how to safely revert if something goes wrong>
Minor
## Summary
<One sentence>
## Changes
- <change 1>
Trivial
A one-line summary in the PR body is sufficient.
Rules
- One topic per PR — don't mix unrelated changes
- All tests must pass (
bundle exec fluence-ci all) - New code must include tests
- Never commit secrets or credentials
Architecture
lib/mosaic/sdk/
models/
base.rb # Abstract class: list, create, associations, lazy loading
bank.rb
dna.rb
clone.rb
nav.rb
client.rb # HTTP client (get, post, put, patch, delete)
configuration.rb # SDK configuration (client_id, client_secret, base_url)
version.rb
Baseprovideslistandcreate— models can overridecreatewithNotImplementedErrorto disable itBase::Instancehandles lazy loading and chainable associations viaself.association- Association chain:
Dna -> Clone -> Nav - Context propagated via
@extrahash (e.g.dna_id,clone_id)
Tests
- Framework: Minitest (
test/**/test_*.rb) - HTTP stubs via
ClientStubintest/test_helper.rb— no real HTTP requests - Minimum coverage: 95% overall, 70% per file
- All new code must be tested
- Coverage checked on PRs via undercover (diff-based)
Code Conventions
frozen_string_literal: trueon every Ruby file- Strings: single quotes (unless interpolation is needed)
- RuboCop: no rule disabling without justification
- Version in
lib/mosaic/sdk/version.rb— do not modify unless for an explicit release - YARD-style doc comments on all public methods
CI
GitHub Actions:
- main.yml — runs on every PR: RuboCop + Minitest + coverage check
- release.yml — version bump and changelog generation (workflow_dispatch)
- github-release.yml — creates GitHub releases from tags
- publish.yml — publishes the gem to GitHub Packages
AI-Assisted Contributions
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.
License
By contributing, you agree that your contributions will be licensed under the MIT License.