Thanks for your interest in contributing! This guide will help you get started.
- Fork the repository and clone your fork
- Follow the setup instructions in README.md (Docker or local development)
- Install the pre-commit hooks (see Pre-commit hooks below)
- Create a branch for your work:
git checkout -b your-branch-name
We use pre-commit to run lint, format, type, and secret-scanning checks on every commit. Install it once after cloning:
pip install pre-commit
pre-commit install
pre-commit install --hook-type pre-pushFrom then on, the hooks run automatically. To run them against every file in the repo (useful after pulling in large changes):
pre-commit run --all-filesThe hooks enforce the same rules as CI, so passing them locally means your PR will pass the automated checks.
See the README for full setup instructions. The quick version:
cp .env.example .env
# Edit .env if needed (defaults work for local dev with Docker PostgreSQL)
docker compose up postgres -d
python manage.py migrate
python manage.py runserverpytestWith coverage:
pytest --cov=apps --cov-report=term-missingWe use Ruff for linting and formatting, and mypy for type checking. Run these before submitting a PR:
ruff check . # lint
ruff format --check . # format check
mypy apps/ config/ providers/ tests/ --ignore-missing-importsTo auto-fix lint and formatting issues:
ruff check --fix .
ruff format .CI runs all of these checks automatically on every PR, plus a gitleaks secret scan. Never commit real API keys, tokens, or passwords. Put them in your local .env (which is gitignored) and reference them by name in .env.example.
- Keep PRs focused. One feature or fix per PR. Small PRs get reviewed faster.
- Write descriptive commit messages. Explain what and why, not just how.
- Add tests for new features or bug fixes when possible.
- Make sure CI passes. The PR must pass lint, typecheck, and test checks.
- Update documentation if your change affects setup, configuration, or user-facing behavior.
- Push your branch to your fork
- Open a pull request against
main - Fill out the PR template
- A maintainer listed in
.github/CODEOWNERSis auto-requested for review - Wait for review, we'll try to respond within a few days
- Address review feedback in new commits (don't force-push until after approval, so reviewers can see the diff)
- Once approved, a maintainer will squash-merge your PR into
main
apps/ # Django applications (accounts, composer, calendar, etc.)
providers/ # Social platform API integrations (one file per platform)
config/ # Django settings, URLs, WSGI/ASGI
templates/ # Django HTML templates
theme/ # Tailwind CSS theme (django-tailwind)
static/ # Static assets (JS, favicons)
tests/ # Test suite
Providers live in providers/ with one file per platform. To add a new one:
- Create
providers/your_platform.py - Implement the provider class following the pattern in existing providers (e.g.,
providers/bluesky.pyfor a simple example,providers/facebook.pyfor a full OAuth flow) - Key methods to implement:
get_authorization_url()- Build the OAuth redirect URLexchange_code()- Exchange the auth code for tokensrefresh_token()- Refresh expired tokenspublish()- Publish content to the platformget_comments()/reply_to_comment()- Inbox support (optional)
- Register the provider in the platform choices and connection flow
- Add the platform's required environment variables to
.env.example - Add setup instructions to the README under Platform Credentials
- Add tests in
tests/providers/
Use the bug report template on GitHub. Include:
- Steps to reproduce
- Expected vs actual behavior
- Your environment (Docker/local, OS, browser)
Use the feature request template on GitHub.
Do not open a public issue for security vulnerabilities. See SECURITY.md for responsible disclosure instructions.
By contributing, you agree that your contributions will be licensed under the AGPL-3.0 License.