Welcome to Rxiv-Maker! We're thrilled that you're interested in contributing to our project. This guide will help you get started with contributing to Rxiv-Maker, whether you're fixing bugs, adding features, improving documentation, or helping in other ways.
We follow a local-first validation approach to ensure code quality while minimizing CI/CD complexity:
- Faster feedback: Catch issues in seconds, not minutes
- Reduced CI costs: GitHub Actions runs only essential checks on PRs
- Better security: Minimal external dependencies and API calls
- Developer experience: Fix issues before pushing
- Before submitting: Search existing issues to avoid duplicates
- Include: Detailed description, steps to reproduce, expected vs actual behavior
- Provide: System information, error logs, minimal example if possible
- Use cases: Explain why this feature would be valuable
- Scope: Keep proposals focused and well-defined
- Discussion: Start with GitHub Discussions for complex features
- Always welcome: Fix typos, improve clarity, add examples
- Types: README updates, API docs, tutorials, troubleshooting guides
- Standards: Follow our documentation style guide
- Bug fixes: Small, focused changes with tests
- New features: Discuss first via issues or discussions
- Refactoring: Improve code quality while maintaining functionality
Most contributors should use the standard development environment:
# Install dependencies
pip install -e ".[dev]"
pre-commit install
# Test changes
rxiv pdf ../manuscript-rxiv-maker/MANUSCRIPT/For contributors who prefer containerized environments:
# Use pre-built container for testing
docker run -v $(pwd):/workspace henriqueslab/rxiv-maker-base:latest rxiv pdfWhen releasing a new version, the Homebrew formula must be updated in the homebrew-formulas repository.
cd ../homebrew-formulas
just release rxiv-maker # Full workflow: update → test → commit → pushThis automatically:
- Fetches the latest version from PyPI
- Downloads and calculates SHA256 checksum
- Updates the formula file
- Tests the installation
- Commits with standardized message
- Pushes to remote
If just is not available, you can update the formula manually:
VERSION=X.Y.Z # Replace with new version
curl "https://pypi.org/pypi/rxiv-maker/$VERSION/json" | \
jq -r '.urls[] | select(.packagetype=="sdist") | "URL: \(.url)\nSHA256: \(.digests.sha256)"'Navigate to the homebrew-formulas repository and edit the formula:
cd ../homebrew-formulas # Use relative path from rxiv-maker directoryEdit Formula/rxiv-maker.rb:
- Update the
urlline with the new URL - Update the
sha256line with the new hash
brew uninstall rxiv-maker 2>/dev/null || true
brew install --build-from-source ./Formula/rxiv-maker.rb
brew test rxiv-maker
rxiv --version # Verify correct version
rxiv check-installation # Verify dependenciesbrew audit --strict --online rxiv-makergit add Formula/rxiv-maker.rb
git commit -m "rxiv-maker: update to version $VERSION"
git pushbrew uninstall rxiv-maker
brew install henriqueslab/formulas/rxiv-maker
rxiv --versionNote: The automated workflow using just is preferred for consistency and efficiency. See the homebrew-formulas repository for additional utility commands like just list, just check-updates, and just sha256
-
Fork and Clone
# Fork the repository on GitHub, then: git clone https://github.com/YOUR_USERNAME/rxiv-maker.git cd rxiv-maker git remote add upstream https://github.com/henriqueslab/rxiv-maker.git
-
Set Up Development Environment
Standard development setup for the best contributor experience:
- Installation: See installation documentation for your platform
- Development mode: Install rxiv-maker in editable mode:
pip install -e ".[dev]" - Pre-commit: Install hooks after setup:
pre-commit install
-
Install Pre-commit Hooks (MANDATORY)
# Install pre-commit if not already installed pip install pre-commit # Install the git hooks pre-commit install # Run once to verify setup pre-commit run --all-files
IMPORTANT: Pre-commit hooks are mandatory. CI will reject PRs that fail these checks.
-
Verify Setup
# Test your setup with modern CLI rxiv --version # Check CLI installation rxiv validate ../manuscript-rxiv-maker/MANUSCRIPT/ # Validate example rxiv pdf ../manuscript-rxiv-maker/MANUSCRIPT/ # Build PDF # Or use legacy commands MANUSCRIPT_PATH=../manuscript-rxiv-maker/MANUSCRIPT make pdf # Legacy make interface
-
Create a Branch
git checkout -b feature/your-feature-name # or git checkout -b fix/issue-number-description -
Make Your Changes
- Write clear, focused commits
- Add tests for new functionality
- Update documentation as needed
- Follow code style guidelines
-
Test Your Changes
# Quick development feedback (<1 min) nox -s "test(test_type='fast')" # Fast tests only # Full test suite (<10 min, matches CI) nox -s "test(test_type='full')" # Unit + integration tests (default) nox -s test # Shorthand for full test suite # Selective testing for focused development nox -s "test(test_type='unit')" # Unit tests only nox -s "test(test_type='integration')" # Integration tests only # Specialized testing nox -s "pdf" # PDF generation # Code quality checks nox -s lint # Linting (ruff + mypy) nox -s format # Auto-format code nox -s security # Security scanning (bandit, safety, pip-audit) # Build validation nox -s build # Package build + validation # Test with manuscripts using modern CLI rxiv validate ../manuscript-rxiv-maker/MANUSCRIPT/ # Validate manuscript rxiv pdf ../manuscript-rxiv-maker/MANUSCRIPT/ # Build PDF
-
Submit Your Contribution
git add . git commit -m "feat: add new feature description" git push origin feature/your-feature-name
- Tests pass locally (
nox -s "test(test_type='fast')"ornox -s test) - Code follows project style (
nox -s lintandnox -s format) - Security checks pass (
nox -s security) - Package builds successfully (
nox -s build) - Documentation updated if needed
- CHANGELOG.md updated for significant changes
- Pull request template filled out
- Title: Use conventional commit format (feat:, fix:, docs:, etc.)
- Description: Explain what and why, link to relevant issues
- Testing: Describe how you tested the changes
- Breaking Changes: Clearly document any breaking changes
- Maintainer Review: All PRs reviewed by maintainers
- CI Checks: All automated checks must pass
- Feedback: Address review comments promptly
- Merge: Maintainers will merge when ready
We use modern Python tooling for consistent code quality:
# All tools configured in pyproject.toml
pre-commit run --all-files # Runs all checksTools in use:
- Ruff: Linting and formatting (replaces Black, isort, flake8)
- MyPy: Type checking
- Pytest: Testing framework
- Type Hints: Use type hints for function signatures
- Docstrings: Google-style docstrings for public functions
- Error Handling: Proper exception handling with meaningful messages
- Testing: Write tests for new functionality
- Naming: Use descriptive variable and function names
from typing import Dict, List, Optional
import logging
def process_manuscript(
manuscript_path: str,
output_dir: str,
config: Optional[Dict[str, str]] = None
) -> bool:
"""Process a manuscript and generate LaTeX output.
Args:
manuscript_path: Path to the manuscript directory
output_dir: Directory where output files will be written
config: Optional configuration overrides
Returns:
True if processing succeeded, False otherwise
Raises:
FileNotFoundError: If manuscript directory doesn't exist
ValueError: If configuration is invalid
"""
logger = logging.getLogger(__name__)
if not Path(manuscript_path).exists():
raise FileNotFoundError(f"Manuscript directory not found: {manuscript_path}")
# Implementation details...
logger.info(f"Successfully processed manuscript: {manuscript_path}")
return Truetests/
├── unit/ # Unit tests for individual modules
├── integration/ # Integration tests for workflows
├── fixtures/ # Test data and fixtures
└── conftest.py # Pytest configuration
import pytest
from pathlib import Path
from rxiv_maker.processors import MarkdownProcessor
class TestMarkdownProcessor:
def test_process_basic_markdown(self):
"""Test basic markdown processing."""
processor = MarkdownProcessor()
result = processor.process("# Hello World")
assert "Hello World" in result
@pytest.mark.parametrize("input_text,expected", [
("# Title", "\\section{Title}"),
("## Subtitle", "\\subsection{Subtitle}"),
])
def test_heading_conversion(self, input_text, expected):
"""Test heading conversion with multiple cases."""
processor = MarkdownProcessor()
result = processor.process(input_text)
assert expected in result- Unit Tests: Test individual functions/classes in isolation
- Integration Tests: Test end-to-end workflows
- Regression Tests: Prevent previously fixed bugs from returning
- Performance Tests: Ensure changes don't degrade performance
- Code Documentation: Inline comments and docstrings
- API Documentation: Auto-generated from docstrings
- User Guides: Step-by-step tutorials and how-tos
- Reference: Complete feature documentation
- Clear and Concise: Use simple language, avoid jargon
- Examples: Include practical examples
- Structure: Use consistent formatting and organization
- Accuracy: Keep documentation synchronized with code
# Use sentence case for headings
## Code Examples
Always include language specification:
```python
def example_function():
"""Example with proper formatting."""
return "formatted result"- Use bullet points for unordered lists
- Use numbers for sequential steps
- Keep items parallel in structure
- Use
[descriptive text](url)format - Prefer relative links for internal documentation
## 🏷️ Issue and PR Labels
### Issue Labels
- `bug`: Something isn't working
- `enhancement`: New feature or request
- `documentation`: Improvements or additions to documentation
- `good first issue`: Good for newcomers
- `help wanted`: Extra attention is needed
- `question`: Further information is requested
### PR Labels
- `breaking change`: Introduces breaking changes
- `feature`: Adds new functionality
- `bugfix`: Fixes a bug
- `docs`: Documentation only changes
- `refactor`: Code refactoring
- `tests`: Adding or updating tests
## 🚀 Release Process
> 📋 **For maintainers**: See [RELEASING.md](RELEASING.md) for the complete release workflow including PyPI, Homebrew, Docker, and website documentation updates.
### Versioning
We follow [Semantic Versioning](https://semver.org/):
- **MAJOR**: Breaking changes
- **MINOR**: New features (backward compatible)
- **PATCH**: Bug fixes (backward compatible)
### Release Workflow (Summary)
1. **Update CHANGELOG.md**: Document all changes
2. **Version Bump**: Update version in relevant files
3. **Create Release**: GitHub release with notes
4. **PyPI Upload**: Automated via GitHub Actions
5. **Homebrew Formula**: Update in `../homebrew-formulas` repository
6. **Docker Images**: Verify `../docker-rxiv-maker` builds correctly
7. **Documentation**: Update website if needed
**Note**: Contributors don't need to worry about release mechanics. Maintainers handle all release processes using the detailed checklist in [RELEASING.md](RELEASING.md).
## 🎯 Project Priorities
### Current Focus Areas
1. **Stability**: Robust error handling and testing
2. **User Experience**: Better documentation and examples
3. **Performance**: Faster builds and processing
4. **Platform Support**: Cross-platform compatibility
### Long-term Goals
- Enhanced template system
- Real-time preview capabilities
- Plugin architecture
- Web-based editor interface
## ❓ Getting Help
### Communication Channels
- **GitHub Issues**: Bug reports and feature requests
- **GitHub Discussions**: Questions and general discussion
- **Email**: Contact maintainers for sensitive issues
### Response Times
- **Bug Reports**: 2-3 business days
- **Feature Requests**: 1 week
- **Pull Reviews**: 3-5 business days
- **Security Issues**: 24 hours
## 🙏 Recognition
### Contributors
All contributors are recognized in:
- GitHub contributors page
- CHANGELOG.md for significant contributions
- Special mentions in release notes
### Code of Conduct
This project follows our [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you agree to abide by its terms.
## 📞 Contact
- **Maintainers**: See [CODEOWNERS](.github/CODEOWNERS)
- **Security Issues**: Report via GitHub Security Advisories
- **General Questions**: Use GitHub Discussions
Thank you for contributing to Rxiv-Maker! Your efforts make scientific publishing more accessible and efficient for researchers worldwide. 🚀