| # Contributing to Mosaic | |
| Thank you for your interest in contributing to Mosaic! This document provides guidelines and instructions for contributing to the project. | |
| ## Table of Contents | |
| - [Getting Started](#getting-started) | |
| - [Development Setup](#development-setup) | |
| - [Code Style](#code-style) | |
| - [Testing](#testing) | |
| - [Submitting Changes](#submitting-changes) | |
| - [Reporting Issues](#reporting-issues) | |
| ## Getting Started | |
| 1. Fork the repository on GitHub | |
| 2. Clone your fork locally | |
| 3. Set up the development environment | |
| 4. Create a new branch for your changes | |
| 5. Make your changes | |
| 6. Test your changes | |
| 7. Submit a pull request | |
| ## Development Setup | |
| ### Prerequisites | |
| - Python 3.10 or higher | |
| - [uv](https://docs.astral.sh/uv/) package manager | |
| - NVIDIA GPU with CUDA support (for model inference) | |
| ### Installation | |
| 1. Clone the repository: | |
| ```bash | |
| git clone https://github.com/pathology-data-mining/mosaic.git | |
| cd mosaic | |
| ``` | |
| 2. Install dependencies including development tools: | |
| ```bash | |
| uv sync | |
| ``` | |
| This will install all dependencies, including development tools like pytest, pylint, and black. | |
| ### Running Tests | |
| Run all tests: | |
| ```bash | |
| pytest tests/ | |
| ``` | |
| Run tests with coverage report: | |
| ```bash | |
| pytest tests/ --cov=src/mosaic --cov-report=term-missing | |
| ``` | |
| Run a specific test file: | |
| ```bash | |
| pytest tests/inference/test_data.py -v | |
| ``` | |
| ### Code Quality | |
| #### Linting | |
| We use pylint for code linting. Run it with: | |
| ```bash | |
| pylint src/mosaic | |
| ``` | |
| #### Code Formatting | |
| We use black for code formatting. Format your code with: | |
| ```bash | |
| black src/mosaic tests/ | |
| ``` | |
| ## Code Style | |
| ### Python Style Guide | |
| - Follow [PEP 8](https://pep8.org/) style guidelines | |
| - Use meaningful variable and function names | |
| - Add docstrings to all public functions, classes, and modules | |
| - Keep functions focused and concise | |
| - Use type hints where appropriate | |
| ### Docstring Format | |
| Use Google-style docstrings: | |
| ```python | |
| def function_name(param1: str, param2: int) -> bool: | |
| """Brief description of the function. | |
| More detailed description if needed. | |
| Args: | |
| param1: Description of param1 | |
| param2: Description of param2 | |
| Returns: | |
| Description of return value | |
| Raises: | |
| ValueError: Description of when this error is raised | |
| """ | |
| pass | |
| ``` | |
| ### Commit Messages | |
| - Use clear and descriptive commit messages | |
| - Start with a verb in the imperative mood (e.g., "Add", "Fix", "Update") | |
| - Keep the first line under 72 characters | |
| - Provide additional context in the commit body if needed | |
| Example: | |
| ``` | |
| Add docstrings to inference module functions | |
| - Added comprehensive docstrings to all public functions | |
| - Included type hints for better code clarity | |
| - Updated existing docstrings to follow Google style | |
| ``` | |
| ## Testing | |
| ### Writing Tests | |
| - Write tests for all new features and bug fixes | |
| - Place tests in the appropriate directory under `tests/` | |
| - Use pytest fixtures for common setup code | |
| - Mock external dependencies (e.g., model loading, network requests) | |
| - Ensure tests can run without GPU access or large model downloads | |
| ### Test Structure | |
| ```python | |
| import pytest | |
| from mosaic.module import function_to_test | |
| def test_function_basic_case(): | |
| """Test basic functionality of the function.""" | |
| result = function_to_test(input_data) | |
| assert result == expected_output | |
| def test_function_edge_case(): | |
| """Test edge cases.""" | |
| with pytest.raises(ValueError): | |
| function_to_test(invalid_input) | |
| ``` | |
| ## Submitting Changes | |
| ### Pull Request Process | |
| 1. **Create a feature branch**: | |
| ```bash | |
| git checkout -b feature/your-feature-name | |
| ``` | |
| 2. **Make your changes**: | |
| - Write clear, focused commits | |
| - Add tests for new functionality | |
| - Update documentation as needed | |
| 3. **Ensure code quality**: | |
| ```bash | |
| black src/mosaic tests/ | |
| pylint src/mosaic | |
| pytest tests/ | |
| ``` | |
| 4. **Push to your fork**: | |
| ```bash | |
| git push origin feature/your-feature-name | |
| ``` | |
| 5. **Create a Pull Request**: | |
| - Go to the GitHub repository | |
| - Click "New Pull Request" | |
| - Select your branch | |
| - Provide a clear description of your changes | |
| - Reference any related issues | |
| ### Pull Request Guidelines | |
| - Keep pull requests focused on a single feature or fix | |
| - Update documentation for any changed functionality | |
| - Add or update tests as appropriate | |
| - Ensure all tests pass before submitting | |
| - Respond to review feedback promptly | |
| ## Reporting Issues | |
| ### Bug Reports | |
| When reporting a bug, please include: | |
| - A clear and descriptive title | |
| - Steps to reproduce the issue | |
| - Expected behavior | |
| - Actual behavior | |
| - System information (OS, Python version, GPU model) | |
| - Relevant log output or error messages | |
| - Minimal code example to reproduce the issue | |
| ### Feature Requests | |
| When suggesting a feature, please include: | |
| - A clear description of the feature | |
| - The use case and benefits | |
| - Any alternative solutions you've considered | |
| - Examples of how the feature would be used | |
| ### Issue Templates | |
| Please use the appropriate issue template when creating a new issue. | |
| ## Development Guidelines | |
| ### Module Organization | |
| - Keep modules focused on a single responsibility | |
| - Place UI-related code in `src/mosaic/ui/` | |
| - Place inference code in `src/mosaic/inference/` | |
| - Place analysis logic in `src/mosaic/analysis.py` | |
| - Avoid circular dependencies | |
| ### Adding New Features | |
| When adding new features: | |
| 1. Discuss the feature in an issue first | |
| 2. Follow the existing code structure | |
| 3. Add comprehensive tests | |
| 4. Update relevant documentation | |
| 5. Consider backward compatibility | |
| ### Dependencies | |
| - Avoid adding new dependencies unless necessary | |
| - Discuss new dependencies in an issue or pull request | |
| - Ensure dependencies are compatible with the project's license | |
| - Pin dependency versions in `pyproject.toml` | |
| ## GitHub Actions CI/CD | |
| ### Required Repository Secrets | |
| For the Docker build workflow to work properly in GitHub Actions, the following secrets must be configured in your repository settings (Settings → Secrets and variables → Actions): | |
| 1. **`SSH_PRIVATE_KEY`** (Required) | |
| - Your SSH private key that has access to the private repositories (paladin and Mussel) | |
| - Generate with: `ssh-keygen -t ed25519 -C "github-actions@mosaic"` | |
| - Add the public key to your GitHub account with repo access | |
| - Add the private key to GitHub secrets | |
| 2. **`DOCKER_HUB_USERNAME`** (Optional - only needed for Docker Hub pushes) | |
| - Your Docker Hub username | |
| - Required only if you want to push images to Docker Hub (on main branch) | |
| 3. **`DOCKER_HUB_TOKEN`** (Optional - only needed for Docker Hub pushes) | |
| - Your Docker Hub access token | |
| - Generate at: https://hub.docker.com/settings/security | |
| - Required only if you want to push images to Docker Hub (on main branch) | |
| ### CI/CD Workflows | |
| The project includes several GitHub Actions workflows: | |
| - **`tests.yml`** - Runs pytest test suite on every push/PR | |
| - **`code-quality.yml`** - Runs black and pylint checks | |
| - **`docker.yml`** - Builds and pushes Docker images: | |
| - Builds on every push to main/dev branches and PRs | |
| - Pushes to GitHub Container Registry (ghcr.io) for all branches | |
| - Pushes to Docker Hub (docker.io/mskmind/mosaic) only on main branch | |
| ### Docker Build Process | |
| The Docker build uses SSH forwarding to access private dependencies: | |
| ```bash | |
| # Local build (using build.sh) | |
| ./build.sh | |
| # Or using Make | |
| make docker-build | |
| ``` | |
| The GitHub Actions workflow automatically: | |
| 1. Sets up SSH agent with the private key | |
| 2. Configures Docker Buildx with SSH forwarding | |
| 3. Builds the image with access to private repositories | |
| 4. Pushes to GHCR and optionally Docker Hub | |
| ## Questions? | |
| If you have questions about contributing, please: | |
| - Check existing issues and pull requests | |
| - Open a new issue with your question | |
| - Join our community discussions (if available) | |
| Thank you for contributing to Mosaic! | |