This guide covers the development workflow for contributing to PropManager, including Git practices, code review, and deployment.
- Git Workflow
- Branch Strategy
- Making Changes
- Commit Guidelines
- Pull Requests
- Code Review
- Continuous Integration
- Deployment
PropManager uses a simplified Git workflow based on feature branches.
master (production-ready)
│
├── feature/new-feature
│ └── commits...
│
├── fix/bug-fix
│ └── commits...
│
└── docs/update-readme
└── commits...
- master is always deployable - Never push broken code to master
- Feature branches are short-lived - Merge frequently to avoid conflicts
- Pull requests are required - No direct commits to master
- Tests must pass - All PRs require passing CI checks
Use descriptive prefixes:
| Prefix | Purpose | Example |
|---|---|---|
feature/ |
New functionality | feature/tenant-rewards |
fix/ |
Bug fixes | fix/invoice-calculation |
docs/ |
Documentation | docs/api-reference |
refactor/ |
Code restructuring | refactor/payment-service |
test/ |
Test additions | test/billing-edge-cases |
chore/ |
Maintenance | chore/update-dependencies |
- Use lowercase letters
- Separate words with hyphens
- Keep names concise but descriptive
- Include ticket number if applicable:
feature/PM-123-tenant-rewards
# Update master
git checkout master
git pull origin master
# Create feature branch
git checkout -b feature/your-feature-name- Create branch from latest master
- Write code with small, focused commits
- Test locally - run tests and manual verification
- Create PR when ready for review
- Address feedback from code review
- Merge after approval
Before creating a PR:
# Run all tests
python manage.py test
# Run linting
flake8
# Format code
black .
isort .
# Check for common issues
python manage.py checkIf master has changed while you're working:
# Option 1: Rebase (preferred for clean history)
git fetch origin
git rebase origin/master
# Option 2: Merge (if conflicts are complex)
git fetch origin
git merge origin/master<type>: <short description>
<optional body>
<optional footer>
| Type | Description |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation changes |
style |
Formatting (no code change) |
refactor |
Code restructuring |
test |
Adding or updating tests |
chore |
Maintenance tasks |
perf |
Performance improvements |
Good examples:
feat: Add streak-based tenant rewards
Implements reward calculation for consecutive on-time payments.
Rewards are granted at 3, 6, and 12-month milestones.
Closes #45
fix: Correct late fee calculation for partial payments
Late fees were being applied to full invoice amount instead of
remaining balance. Now correctly calculates based on unpaid amount.
refactor: Extract payment processing into service class
Moves payment logic from views to dedicated PaymentService class
for better testability and reuse.
Bad examples:
# Too vague
fix: Fixed bug
# No context
update stuff
# Multiple changes in one commit
Add rewards, fix billing, update docs
Each commit should:
- Represent one logical change
- Be independently reversible
- Pass all tests
- Have a clear purpose
Split large changes:
# Instead of one large commit, make several:
git add apps/billing/models.py
git commit -m "feat: Add PropertyBillingConfig model"
git add apps/billing/tasks.py
git commit -m "feat: Add late fee calculation task"
git add apps/billing/tests/
git commit -m "test: Add late fee calculation tests"-
Push your branch:
git push -u origin feature/your-feature
-
Open PR on GitHub
-
Fill in the template:
## Description
Brief description of what this PR does.
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Documentation
- [ ] Refactoring
- [ ] Other (describe)
## How Has This Been Tested?
Describe the tests you ran.
## Related Issues
Closes #123
## Checklist
- [ ] My code follows the project style guidelines
- [ ] I have added tests for my changes
- [ ] All new and existing tests pass
- [ ] I have updated documentation as needed
- [ ] My changes don't introduce security vulnerabilities- Keep PRs focused - One feature or fix per PR
- Write clear descriptions - Explain what and why
- Include screenshots - For UI changes
- Link related issues - Use "Closes #123" syntax
- Request specific reviewers - Tag relevant team members
| Size | Lines Changed | Review Time |
|---|---|---|
| Small | < 100 | Quick review |
| Medium | 100-300 | Standard review |
| Large | 300-500 | Split if possible |
| Very Large | > 500 | Should be split |
Large PRs are harder to review and more likely to have issues. Split into smaller, logical PRs when possible.
- Check functionality - Does the code work as intended?
- Review tests - Are changes properly tested?
- Check style - Does it follow project conventions?
- Security review - Any potential vulnerabilities?
- Performance - Any obvious performance issues?
Be constructive:
# Good
Consider using select_related() here to avoid N+1 queries.
This pattern is used elsewhere in apps/leases/views.py:45.
# Bad
This is wrong.
Ask questions:
# Good
I'm not sure I understand the use case for this.
Could you explain when this condition would be true?
# Bad
What is this?
- Code compiles and tests pass
- Logic is correct and handles edge cases
- Error handling is appropriate
- No security vulnerabilities introduced
- Code follows project style
- Tests cover new functionality
- Documentation is updated
- Respond to all comments - Don't leave things unresolved
- Explain your decisions - Provide context when asked
- Make requested changes - Or discuss alternatives
- Re-request review - After making changes
- Be open to feedback - Code review improves everyone
PropManager uses GitHub Actions for CI:
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- run: pip install -r requirements.txt
- run: python manage.py test
- run: flake8All PRs must pass:
| Check | Description |
|---|---|
| Tests | All tests pass |
| Linting | No flake8 errors |
| Formatting | Black formatting check |
| Migrations | No missing migrations |
Before pushing, run the same checks locally:
# Full CI check
python manage.py test
flake8
black --check .
python manage.py makemigrations --check --dry-runfeature branch → PR → code review → merge to master → deploy
- All tests pass
- Migrations are included
- Environment variables documented
- Deployment notes in PR
- Rollback plan considered
- Merge PR to master
- Deploy using your deployment method
- Run migrations in production
- Verify functionality
- Monitor for errors
- Check application logs
- Verify critical functionality
- Monitor error tracking
- Test user-facing features
If issues are found:
# Revert the merge commit
git revert <merge-commit-sha>
git push origin master
# Redeploy previous version
# Roll back migrations if necessary
python manage.py migrate app_name <previous_migration>- Pull latest changes each morning
- Work in small increments
- Commit frequently
- Push at end of day (for backup)
- Keep branches short-lived
- Communicate with team
- Rebase frequently
- Split large changes
- Keep PRs small
- Write clear descriptions
- Tag appropriate reviewers
- Respond quickly to feedback
- Getting Started - Development setup
- Background Tasks - Django-Q2 guide
- Contributing - Contribution guidelines