Thank you for your interest in contributing! This guide covers everything you need to know to get set up and make a great contribution.
- Getting Started
- Development Setup
- Making Changes
- Running the Quality Checks
- Writing Tests
- Submitting a Pull Request
- Contributing a Curated Config
- Reporting Bugs
- Code of Conduct
- Fork the repository on GitHub.
- Clone your fork locally:
git clone git@github.com:<your-username>/ruff-sync.git cd ruff-sync
- Install uv — our package manager:
curl -LsSf https://astral.sh/uv/install.sh | sh - Sync dependencies:
uv run invoke deps
- Install pre-commit hooks:
uv run pre-commit install
The project uses a src layout. All source code lives in src/ruff_sync/. Development tasks are managed via Invoke in tasks.py.
| Task | Alias | Description |
|---|---|---|
uv run invoke lint |
Lint with Ruff (auto-fixes by default) | |
uv run invoke fmt |
Format with Ruff | |
uv run invoke type-check |
types |
Type-check with mypy |
uv run invoke deps |
sync |
Sync dependencies with uv |
uv run invoke new-case |
new-lifecycle-tomls |
Scaffold lifecycle TOML test fixtures |
uv run invoke docs |
Build or serve documentation | |
uv run invoke release |
Tag and create a GitHub release |
- Branch off
mainfor all new work:git checkout -b my-feature
- Keep commits focused: one logical change per commit is ideal.
- Follow code conventions (see below).
- Always add
from __future__ import annotationsas the first import in every Python file. - Use
import pathlib(notfrom pathlib import Path) andimport datetime as dt(notfrom datetime import ...). - Use
pathlibfor all path manipulation (enforced byPTHrules). - Always use
tomlkitfor reading or writing TOML — it preserves comments, whitespace, and formatting. - Prefer
NamedTuplefor multi-value return types. - Type hints everywhere; the project uses mypy in strict mode.
Before pushing, always run the full quality suite in this order:
# 1. Lint (auto-fixes where possible)
uv run ruff check . --fix
# 2. Format
uv run ruff format .
# 3. Type-check
uv run mypy .
# 4. Tests
uv run pytest -vvImportant
Do not add # noqa comments or suppress lint rules. Fix the underlying issue instead.
CI runs the same checks across Python 3.10–3.14, so make sure everything passes locally first.
All new behavioural changes and bug fixes must include tests. See the Testing Standards for a full guide, but the key rules are:
- No real filesystem or network calls: Use
pyfakefsfor filesystem andrespxfor HTTP mocking. - Async tests need
@pytest.mark.asyncio(strict mode is on). - TOML merge tests need both a structural check (comments/whitespace preserved) and a semantic check (actual values are correct).
- Every test file must end with:
if __name__ == "__main__": pytest.main([__file__, "-vv"])
For end-to-end merge testing, use the fixture triple pattern:
# Scaffold a new test case
uv run invoke new-case --name <case_name> --description "What this edge case tests"This creates three files in tests/lifecycle_tomls/: <case>_initial.toml, <case>_upstream.toml, and <case>_final.toml.
- Push your branch and open a PR against
main. - Fill in the PR description: what changed, why, and how to test it.
- Ensure all CI checks pass.
- If your change affects CLI behaviour (new flags, changed exit codes, new config keys, URL handling), update the agent skill at
.agents/skills/ruff-sync-usage/:SKILL.md— quick start, workflows, exit codes, gotchasreferences/configuration.md— config key referencereferences/troubleshooting.md— error scenariosreferences/ci-integration.md— CI/CD recipes
- A maintainer will review your PR — please respond to feedback promptly.
Tip
For significant changes, open an issue first to discuss the approach before investing time in an implementation.
We actively welcome community-contributed Ruff configurations! These live in the configs/ directory and are documented in the Pre-defined Configs Guide.
Join the discussion in Issue #83 before submitting a new config.
- Targeted at a clear use case (e.g.,
configs/cli-tools/ruff.toml). - Each rule or group of rules has an inline comment explaining why it's enabled.
- Has been tested against real-world projects in that domain.
- Create a new directory under
configs/(e.g.,configs/my-domain/). - Add a
ruff.tomlwith well-commented rules. - Optionally add a
README.mdin the directory explaining the config's goals. - Open a PR referencing Issue #83.
Please open an issue with:
- The
ruff-syncversion (ruff-sync --version). - The
ruffversion (ruff --version). - Your operating system and Python version.
- The command you ran and its full output.
- Your local
pyproject.toml(or relevant snippets).
Please be respectful and constructive in all project spaces.