Skip to main content

Introduction

Thank you for your interest in contributing to Bench! Contributing to open source means you’re helping make things better for not only yourself, but everyone else too. We appreciate you taking the initiative to contribute to the commons.
Great projects depend on good code quality and adhering to certain standards. Following these guidelines ensures that developers can quickly give feedback on your contribution and help make it better.

Development Setup

To contribute to Bench development, you’ll need to set up an editable installation.

Clone and Install

1

Clone the Repository

Clone the bench repository to your local machine:
git clone https://github.com/frappe/bench ~/bench-repo
cd ~/bench-repo
2

Install in Editable Mode

Install bench in editable mode using pip:
pip install -e ~/bench-repo
This creates a link to your local repository, so any changes you make are immediately reflected.
3

Verify Installation

Check that bench is using your development version:
bench src
This should display: $HOME/bench-repo

Editable Mode Warning

When running bench in editable mode, you’ll see this warning:
WARN: bench is installed in editable mode!

This is not the recommended mode of installation for production. 
Instead, install the package from PyPI with: `pip install frappe-bench`
This is expected during development. You can suppress it by setting the BENCH_DEVELOPER environment variable:
export BENCH_DEVELOPER=1

Switching Back to Production

When you’re done developing:
1

Uninstall Editable Version

pip uninstall frappe-bench
2

Install from PyPI

pip install -U frappe-bench
3

Verify

bench src
Should now show something like: /usr/local/lib/python3.12/dist-packages

Contribution Guidelines

Feedback Policy

We strive for a “Zero Pull Request Pending” policy:
  • If your PR meets requirements, it will be merged within a day
  • If it doesn’t meet requirements, it will be closed with feedback
  • Don’t worry if your PR is closed - fix the issues and re-open it!

Pull Request Requirements

Add test cases for your changes, even simple ones that just call the function.
# tests/test_my_feature.py
def test_my_new_command():
    result = my_command()
    assert result is not None
For UI changes, include screenshots or animated GIFs.
If your change involves user experience:
  • Add screenshots showing before/after
  • Include narration of the user flow
  • Provide animated GIFs for complex interactions
Update relevant documentation:
  • Command help text
  • README files
  • Code comments
  • API documentation
For design changes:
  • Explain the use case
  • Describe why your approach is better
  • If adding/replacing libraries, provide references
Try to keep pull requests to ~30 lines of code (excluding tests and config).For large features:
  • Break them into smaller parts
  • Submit incremental PRs
  • Use cascading pull requests
  • Hide incomplete features from users
Ensure all automated tests pass:
pytest tests/
Follow the existing code style:
  • Use tabs for indentation (matching existing codebase)
  • Consistent formatting
  • Meaningful variable names
  • Clear function/method names
Avoid breaking changes when possible. If necessary:
  • Provide migration path
  • Update documentation
  • Include deprecation warnings

Code Quality Standards

Naming Conventions

Commands:
@click.command('sync-data')  # Good: lowercase with hyphens
@click.command('syncData')   # Avoid: camelCase
@click.command('sd')         # Avoid: unclear abbreviations
Variables and Functions:
# Good
def setup_production_environment():
    site_config = get_site_config()
    
# Avoid
def setup_prod_env():
    cfg = get_cfg()

Indentation

Bench uses tabs for indentation (we know, but changing would lose history):
def example_function():
if condition:
→   →   do_something()
→   →   do_another_thing()

Documentation Strings

def my_function(param1, param2):
    """Short description of what the function does.
    
    Args:
        param1: Description of param1
        param2: Description of param2
        
    Returns:
        Description of return value
        
    Raises:
        ValueError: When invalid input is provided
    """
    pass

Testing

Running Tests

# Run all tests
pytest tests/

# Run specific test file
pytest tests/test_init.py

# Run with verbose output
pytest -v tests/

# Run with coverage
pytest --cov=bench tests/

Writing Tests

Tests are located in bench/tests/. Follow existing patterns:
import unittest
from bench.utils import get_bench_path

class TestBenchUtils(unittest.TestCase):
    def test_get_bench_path(self):
        """Test that get_bench_path returns valid path."""
        path = get_bench_path()
        self.assertIsNotNone(path)
        self.assertTrue(os.path.exists(path))

Git Workflow

1

Fork and Clone

Fork the repository on GitHub and clone your fork:
git clone https://github.com/YOUR_USERNAME/bench.git
cd bench
2

Create Feature Branch

Create a branch for your changes:
git checkout -b fix-issue-123
Use descriptive branch names:
  • fix-issue-123
  • add-new-command
  • improve-error-handling
3

Make Changes

Make your changes and commit them:
git add .
git commit -m "fix: resolve issue with bench update"
Use clear commit messages:
  • fix: description - Bug fixes
  • feat: description - New features
  • docs: description - Documentation
  • refactor: description - Code refactoring
  • test: description - Tests
4

Push and Create PR

Push your branch and create a pull request:
git push origin fix-issue-123
Then create a PR on GitHub with:
  • Clear title
  • Description of changes
  • Related issue number
  • Screenshots (if applicable)

Pull Request Template

Use this template for your PR description:
## Description
Brief description of what this PR does.

## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Documentation update
- [ ] Code refactoring

## Related Issue
Fixes #(issue number)

## Changes Made
- Change 1
- Change 2
- Change 3

## Testing
Describe how you tested your changes.

## Screenshots (if applicable)
Add screenshots here.

## Checklist
- [ ] Tests added/updated
- [ ] Documentation updated
- [ ] Code follows style guidelines
- [ ] All tests pass

Environment Variables for Development

Useful environment variables during development:
# Suppress editable install warning
export BENCH_DEVELOPER=1

# Enable verbose output
export BENCH_VERBOSE=1

# Disable UV package manager (use pip instead)
export BENCH_DISABLE_UV=1

# Skip certain checks in CI
export CI=1

Getting Help

Discussions

Ask questions and discuss ideas

GitHub Issues

Report bugs and request features

Code of Conduct

Community guidelines

Security

Report security vulnerabilities

Code Review Process

  1. Submission: You submit a pull request
  2. Initial Review: Maintainers review within 24-48 hours
  3. Feedback: You receive feedback on changes needed
  4. Iteration: Make requested changes and update PR
  5. Approval: Once approved, PR is merged
  6. Release: Changes included in next release

Recognition

Your contributions are valued! Contributors are:
  • Listed in the repository’s contributor graph
  • Mentioned in release notes (for significant contributions)
  • Part of the growing Frappe community
Thank you for contributing to Bench! 🎉

Build docs developers (and LLMs) love