Contributing

We welcome contributions to IssueDB! This guide will help you get started.

Getting Started

Prerequisites

  • Python 3.9 or higher

  • Git

  • pip

Development Setup

  1. Clone the repository:

    git clone https://github.com/yourusername/issuedb.git
    cd issuedb
    
  2. Create a virtual environment:

    python -m venv venv
    source venv/bin/activate  # On Windows: venv\Scripts\activate
    
  3. Install in development mode:

    pip install -e ".[dev]"
    
  4. Verify installation:

    issuedb-cli --help
    pytest
    

Development Workflow

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=issuedb --cov-report=html

# Run specific test file
pytest tests/test_repository.py

# Run specific test
pytest tests/test_repository.py::test_create_issue

Code Quality

We use several tools to maintain code quality:

Ruff (linting and formatting):

# Check for issues
ruff check .

# Auto-fix issues
ruff check --fix .

# Format code
ruff format .

Mypy (type checking):

mypy issuedb/

Run all checks:

ruff check . && mypy issuedb/ && pytest

Continuous Integration

Every push and every pull request against main is validated by GitHub Actions (.github/workflows/ci.yml). The pipeline mirrors the local checks above and must be green before a change is merged:

  • test — runs the full pytest suite on Python 3.9, 3.10, 3.11, 3.12, 3.13 and 3.14. The package is installed with its [web] extra so the Flask-backed Web UI/API tests are exercised rather than skipped.

  • lint & type-check — runs ruff check . and mypy issuedb with pinned tool versions, so a new linter release cannot break CI without a deliberate bump.

  • build & verify dist — builds the sdist and wheel with python -m build and validates the packaged metadata with twine check.

To run the same gates locally before pushing:

pip install -e ".[web]" pytest
ruff check . && mypy issuedb && pytest

Building Documentation

cd docs
pip install -r requirements.txt
sphinx-build -b html . _build

# View locally
python -m http.server -d _build 8000
# Open http://localhost:8000

Code Style

General Guidelines

  • Follow PEP 8 style guidelines

  • Use type hints for all function signatures

  • Write docstrings for public functions and classes

  • Keep functions focused and small

  • Prefer clarity over cleverness

Type Hints

All functions should have type hints:

from typing import Optional, List

def get_issue(issue_id: int) -> Optional[Issue]:
    """Get an issue by ID.

    Args:
        issue_id: The issue ID to retrieve

    Returns:
        Issue object if found, None otherwise
    """
    pass

Docstrings

Use Google-style docstrings:

def create_issue(title: str, priority: str = "medium") -> Issue:
    """Create a new issue.

    Args:
        title: The issue title (required)
        priority: Priority level (default: medium)

    Returns:
        The created Issue object with ID populated

    Raises:
        ValueError: If title is empty
    """
    pass

Testing

Test Structure

Tests are located in the tests/ directory:

tests/
├── __init__.py
├── conftest.py        # Shared fixtures
├── test_cli.py        # CLI tests
├── test_comments.py   # Comment functionality tests
├── test_models.py     # Model tests
└── test_repository.py # Repository tests

Writing Tests

import pytest
from issuedb.repository import IssueRepository
from issuedb.models import Issue

@pytest.fixture
def repo():
    """Create a fresh in-memory repository for each test."""
    return IssueRepository(":memory:")

def test_create_issue(repo):
    """Test creating a basic issue."""
    issue = repo.create_issue(Issue(title="Test issue"))

    assert issue.id is not None
    assert issue.title == "Test issue"
    assert issue.status.value == "open"

def test_create_issue_without_title(repo):
    """Test that creating issue without title raises error."""
    with pytest.raises(ValueError, match="Title is required"):
        repo.create_issue(Issue(title=""))

Test Coverage

We aim for high test coverage. Check coverage with:

pytest --cov=issuedb --cov-report=term-missing

# Generate HTML report
pytest --cov=issuedb --cov-report=html
open htmlcov/index.html

Pull Request Process

  1. Fork the repository on GitHub

  2. Create a feature branch:

    git checkout -b feature/your-feature-name
    
  3. Make your changes:

    • Write code

    • Add tests

    • Update documentation

  4. Run quality checks:

    ruff check . && mypy issuedb/ && pytest
    
  5. Commit your changes:

    git add .
    git commit -m "Add feature: description of changes"
    
  6. Push to your fork:

    git push origin feature/your-feature-name
    
  7. Create a Pull Request on GitHub

Pull Request Guidelines

  • Provide a clear description of the changes

  • Reference any related issues

  • Include tests for new functionality

  • Update documentation as needed

  • Keep changes focused and atomic

Commit Messages

Follow conventional commit format:

type: short description

Longer description if needed.

Fixes #123

Types:

  • feat: New feature

  • fix: Bug fix

  • docs: Documentation only

  • test: Adding tests

  • refactor: Code refactoring

  • chore: Maintenance tasks

Examples:

feat: add bulk close command

fix: handle empty title validation

docs: update CLI reference with new commands

test: add tests for comment deletion

Issue Guidelines

Reporting Bugs

When reporting bugs, please include:

  1. Python version: python --version

  2. IssueDB version: pip show issuedb

  3. Operating system

  4. Steps to reproduce

  5. Expected behavior

  6. Actual behavior

  7. Error messages (if any)

Feature Requests

For feature requests:

  1. Check existing issues first

  2. Describe the use case

  3. Explain why it would be useful

  4. Provide examples if possible

Release Process

(For maintainers)

Publishing to PyPI is automated by .github/workflows/release.yml, which triggers when a GitHub Release is published. It re-runs the test suite, builds the distribution, verifies the built version matches the release tag, and uploads to PyPI via OIDC Trusted Publishing (no API token is stored in the repository).

  1. Update the version in pyproject.toml and CHANGELOG.md and merge to main.

  2. Publish a GitHub Release whose tag is v<version> (for example v2.13.0). This creates the tag and starts the release workflow:

    gh release create v2.13.0 --title "v2.13.0" --notes "See CHANGELOG.md"
    
  3. Watch the Release workflow run to completion; it publishes the sdist and wheel to PyPI automatically.

One-time setup (required before the first automated release): register a PyPI Trusted Publisher for the issuedb project pointing at the rodmena-limited/issue-queue repository, workflow release.yml, and environment pypi; then create a matching pypi environment in the GitHub repository settings.

License

By contributing to IssueDB, you agree that your contributions will be licensed under the MIT License.

Questions?

  • Open an issue for questions

  • Check existing documentation

  • Review closed issues for similar problems

Thank you for contributing to IssueDB!