Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,4 @@ jobs:

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v4
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,4 @@ docs/_build/
site/

.spec-workflow/
.mcp.json
.mcp.json
54 changes: 54 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Pre-commit hooks for code quality
# Install: uv run pre-commit install
# Run manually: uv run pre-commit run --all-files
# Update hooks: uv run pre-commit autoupdate
# Skip hooks: git commit --no-verify

repos:
# Standard pre-commit hooks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
exclude: ^mkdocs\.yml$ # MkDocs uses Python-specific YAML tags
- id: check-toml
- id: check-added-large-files
args: ['--maxkb=1000'] # Prevent files >1MB
- id: check-merge-conflict
- id: check-case-conflict
- id: no-commit-to-branch
args: ['--branch=main', '--branch=dev'] # Prevent commits to protected branches

# Ruff - Fast linting and formatting (Rust-based)
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.4
hooks:
# Run the formatter
- id: ruff-format
types_or: [python, pyi]

# Run the linter with auto-fix
- id: ruff
types_or: [python, pyi]
args: [--fix]

# Ty - Fast type checking (Rust-based)
- repo: local
hooks:
- id: ty
name: ty type checker
entry: uv run ty check
language: system
types: [python]
pass_filenames: false # ty checks whole project

# Codespell - Catch common typos
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell
args:
- --ignore-words-list=nd,te,ue # Common false positives in scientific code
- --skip="*.ipynb,*.json,*.lock,*.svg"
137 changes: 128 additions & 9 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,19 @@ This project is intended to be a welcoming space for collaboration. We expect al
uv sync # Installs all dependencies including dev dependencies
```

4. **Verify your setup:**
4. **Install pre-commit hooks** (IMPORTANT):
```bash
uv run pre-commit install
```

This installs git hooks that automatically check code quality before each commit and **prevent accidental commits to protected branches** (`main` and `dev`).

5. **Verify your setup:**
```bash
uv run pytest # Run tests
uv run ruff check . # Check code quality
uv run ty check # Type check
uv run pre-commit run --all-files # Test pre-commit hooks
```

### Optional: Git Aliases for Easier Workflow
Expand All @@ -79,6 +87,76 @@ git sync # Updates local dev
git cleanup # Deletes merged feature branches
```

### Pre-commit Hooks: Your First Line of Defense

Pre-commit hooks run **automatically before each commit** to catch issues early.

**What's checked:**

1. **Branch protection** - Blocks commits to `main` and `dev` (forces feature branch workflow)
2. **Code formatting** - Auto-formats with ruff
3. **Linting** - Auto-fixes common issues with ruff
4. **Type checking** - Validates types with ty
5. **File hygiene** - Removes trailing whitespace, fixes line endings
6. **YAML/TOML validation** - Checks workflow files and pyproject.toml
7. **Spell checking** - Catches typos with codespell

**Normal workflow:**

```bash
git checkout -b feature/my-feature
# ... make changes ...
git add .
git commit -m "Add feature"

# Pre-commit runs automatically:
# ✅ All checks pass → commit succeeds
# ❌ Any check fails → commit blocked, files may be auto-fixed
```

**If hooks auto-fix files:**

```bash
git commit -m "Add feature"
# ruff-format............Failed
# - files were modified by this hook

# Ruff reformatted your code, re-add and commit:
git add .
git commit -m "Add feature"
# ✅ Passes this time
```

**Protection from mistakes:**

```bash
# ❌ Trying to commit on protected branch
git checkout main
git commit -m "oops"

# Output:
# no-commit-to-branch........Failed
# You're attempting to commit on branch 'main'
# Committing directly to 'main' is not allowed.

# ✅ Use feature branches instead
git checkout -b feature/my-fix
git commit -m "Add fix" # Works!
```

**Skip hooks temporarily (use sparingly!):**

```bash
git commit --no-verify # Bypasses pre-commit hooks
# WARNING: CI will still catch issues, and you can't push to main/dev anyway!
```

**Update hooks to latest versions:**

```bash
uv run pre-commit autoupdate
```

## Development Workflow

### Branch Strategy
Expand Down Expand Up @@ -133,13 +211,26 @@ Use these prefixes for your branches:
- Commit frequently (commit message quality doesn't matter - we squash merge)

3. **Run quality checks locally:**

**Option A: Let pre-commit handle it (recommended)**
```bash
git add .
git commit -m "Add feature"
# Pre-commit automatically runs: ruff format, ruff check, ty check
# You still need to run tests manually:
uv run pytest --cov=relperm
```

**Option B: Run checks manually before committing**
```bash
uv run ruff format . # Auto-format code
uv run ruff check --fix . # Fix linting issues
uv run ty check # Type check
uv run pytest --cov=relperm # Run tests with coverage
```

**Note:** Tests are NOT run by pre-commit hooks (too slow). Always run tests manually before pushing.

4. **Push and create PR to `dev`:**
```bash
git push -u origin feature/your-feature-name
Expand Down Expand Up @@ -187,7 +278,9 @@ Use these prefixes for your branches:

### Recovery: Accidentally Committed to Local Main/Dev

If you commit to local `main` or `dev` by mistake:
**Note:** Pre-commit hooks should prevent this! If you're seeing this scenario, make sure you installed pre-commit hooks with `uv run pre-commit install`.

If you somehow bypassed pre-commit hooks (or didn't install them) and committed to `main` or `dev`:

```bash
# 1. Check what commits you made
Expand Down Expand Up @@ -442,19 +535,36 @@ Documentation is automatically deployed to GitHub Pages on release.

### Before Creating a PR

1. **Run all quality checks locally:**
1. **Ensure pre-commit hooks are installed:**
```bash
uv run pre-commit install # If you haven't already
```

2. **Commit your changes** (pre-commit hooks run automatically):
```bash
git add .
git commit -m "Clear description of changes"
# Pre-commit runs: format, lint, type check, branch protection
```

3. **Run tests manually** (not covered by pre-commit):
```bash
uv run ruff format .
uv run ruff check --fix .
uv run ty check
uv run pytest --cov=relperm
```

2. **Ensure all tests pass** and **coverage is >90%**
4. **Ensure all tests pass** and **coverage is >90%**

3. **Update documentation** if you changed the API
5. **Update documentation** if you changed the API

4. **Add examples** to docstrings for new functions
6. **Add examples** to docstrings for new functions

**Alternative:** Run all checks manually before committing:
```bash
uv run ruff format .
uv run ruff check --fix .
uv run ty check
uv run pytest --cov=relperm
```

### Creating a PR

Expand All @@ -477,6 +587,9 @@ Documentation is automatically deployed to GitHub Pages on release.
### PR Review Process

- **Automated checks** will run: `test`, `lint`, `validate-source-branch`
- If you used pre-commit hooks, `lint` should already pass!
- `test` checks ensure coverage is >90%
- `validate-source-branch` confirms you're targeting the correct branch
- **All checks must pass** before merging
- **Maintainers will review** code quality, tests, and documentation
- **Address feedback** by pushing new commits to your branch
Expand Down Expand Up @@ -521,6 +634,12 @@ uv run ruff check --fix . # Lint and auto-fix
uv run ty check # Type check
uv run mkdocs serve # Preview docs locally

# Pre-commit hooks
uv run pre-commit install # Install git hooks (one-time setup)
uv run pre-commit run --all-files # Run all hooks on all files
uv run pre-commit autoupdate # Update hooks to latest versions
git commit --no-verify # Skip pre-commit hooks (emergency only)

# Git workflow
git checkout dev # Switch to dev
git pull origin dev # Sync with remote
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ pip install relperm
```python
import relperm
# Your usage examples here
```
```
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ build-backend = "uv_build"

[dependency-groups]
dev = [
"codespell>=2.4.1",
"mkdocs>=1.6.1",
"mkdocs-material>=9.7.1",
"mkdocstrings>=1.0.0",
"mkdocstrings-python>=2.0.1",
"pre-commit>=4.5.1",
"pymdown-extensions>=10.19.1",
"pytest>=8.4.2",
"ruff>=0.14.10",
Expand Down Expand Up @@ -67,4 +69,4 @@ python-version = "3.12"
[tool.ty.rules]
# "check" usually implies running all default rules, but you can be specific:
# For scientific code, we generally want strict typing on mathematical functions.
# If you find 'ty' too noisy, you can downgrade specific rules to "warn"
# If you find 'ty' too noisy, you can downgrade specific rules to "warn"
Loading