بنقرة واحدة
trunk-based-development
Follow trunk-based development practices with short-lived branches, frequent integration to main, feature flags, and continuous integration. Use when managing git workflow and releases.
القائمة
Follow trunk-based development practices with short-lived branches, frequent integration to main, feature flags, and continuous integration. Use when managing git workflow and releases.
Apply DDD tactical patterns (Entities, Value Objects, Aggregates, Domain Services, Repositories) and strategic design (Ubiquitous Language, Bounded Contexts). Use when modeling complex business logic.
Apply Clean Architecture layering and dependency rules (Domain, Application, Infrastructure, Presentation layers). Use when structuring applications or ensuring dependencies point inward.
Write clear, testable requirements using User Stories and Gherkin scenarios. Capture functional and non-functional requirements with proper acceptance criteria. Use when defining new features or documenting system behavior.
Enforce SOLID principles (Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion) in object-oriented design. Use when writing or reviewing classes and modules.
Follow TDD practices with Red-Green-Refactor cycle. Write tests before implementation, use AAA pattern, and ensure high-quality test coverage. Use when implementing features or fixing bugs.
| name | trunk-based-development |
| description | Follow trunk-based development practices with short-lived branches, frequent integration to main, feature flags, and continuous integration. Use when managing git workflow and releases. |
You are assisting with code that follows trunk-based development practices for rapid, continuous delivery.
One Main Branch: All developers work on a single "trunk" branch (main/master) with short-lived feature branches that merge back quickly (within 1-2 days).
For small, low-risk changes:
# Make change
git add .
git commit -m "Add validation for grade range"
git pull --rebase
git push origin main
When to commit directly:
For larger changes, use branches but merge within 1-2 days:
# Create short-lived branch
git checkout -b add-quota-rule
# Work for < 2 days
git add .
git commit -m "Add quota capacity validation"
git push origin add-quota-rule
# Create PR, get quick review, merge
Rules for feature branches:
Merge to main multiple times per day:
# Update from main frequently
git checkout main
git pull
git checkout add-quota-rule
git rebase main
# Fix any conflicts
git push origin add-quota-rule --force-with-lease
Target frequency:
Good branch names:
add-minimum-grade-rule
fix-quota-overflow
refactor-competence-calculation
Bad branch names:
dev, development, feature # Too generic
johns-work # Not descriptive
v2-rewrite # Too large/long-lived
Branch lifecycle:
1. Create from main
2. Work < 2 days
3. Keep up-to-date with main (rebase daily)
4. Create PR when ready
5. Quick review + CI
6. Merge to main
7. Delete branch immediately
When a feature takes longer than 2 days, use feature flags:
# Feature flag pattern
from config import feature_flags
class AdmissionEvaluationService:
def evaluate(self, application):
if feature_flags.is_enabled('new_quota_algorithm'):
return self._evaluate_with_new_algorithm(application)
else:
return self._evaluate_with_old_algorithm(application)
Feature flag types:
Control when features go live:
# config/feature_flags.py
FEATURE_FLAGS = {
'new_quota_system': {
'enabled': False, # Not ready for production
'description': 'New quota allocation algorithm'
}
}
A/B testing or gradual rollouts:
def is_enabled_for_user(feature: str, user_id: str) -> bool:
"""Enable for percentage of users."""
if feature == 'new_ui':
# Enable for 10% of users
return hash(user_id) % 100 < 10
return False
Control access by role:
def can_access_feature(feature: str, user_role: str) -> bool:
if feature == 'admin_quota_override':
return user_role in ['admin', 'superuser']
return True
Introduce abstraction, implement new version behind it:
# Step 1: Create abstraction (merge to main)
class QuotaAllocator(Protocol):
def allocate(self, students: List[Student]) -> AllocationResult:
...
# Step 2: Make existing code use abstraction (merge to main)
class OldQuotaAllocator(QuotaAllocator):
def allocate(self, students):
# Existing logic
pass
# Step 3: Add new implementation (merge to main, behind flag)
class NewQuotaAllocator(QuotaAllocator):
def allocate(self, students):
# New logic
pass
# Step 4: Switch implementations via config (merge to main)
def get_allocator() -> QuotaAllocator:
if feature_flags.is_enabled('new_quota'):
return NewQuotaAllocator()
return OldQuotaAllocator()
# Step 5: Eventually remove old implementation
Deploy new code but don't expose it:
def evaluate_admission(application):
# Production code path
result = old_evaluation(application)
# Dark launch: run new code but don't use result
if feature_flags.is_enabled('test_new_evaluator'):
new_result = new_evaluation(application)
log_comparison(result, new_result) # Compare results
return result
Break large features into small, independently valuable pieces:
Large Feature: "New Quota System"
Break down:
✓ Day 1: Add Quota entity (merge)
✓ Day 2: Add capacity validation (merge)
✓ Day 3: Add allocation algorithm (merge behind flag)
✓ Day 4: Add UI for quota management (merge behind flag)
✓ Day 5: Enable flag, deprecate old system
Commit small, logical units:
# Good: Small, focused commits
git commit -m "Add Grade value object"
git commit -m "Add grade validation rules"
git commit -m "Add tests for grade validation"
# Bad: Infrequent large commits
git commit -m "Implement entire grade system"
Follow conventional commits:
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat: New featurefix: Bug fixrefactor: Code refactoringtest: Add/update testsdocs: Documentationchore: MaintenanceExamples:
feat(quota): Add capacity validation for quota entity
Implement validation to ensure quota capacity is never negative
and filled count never exceeds capacity.
Refs: #123
---
fix(grades): Handle missing grade in competence calculation
Previously crashed when student was missing a grade.
Now returns 0 points for missing grades with a warning.
Fixes: #456
---
refactor(admission): Extract rule evaluation to domain service
Move evaluation logic from use case to domain service to follow
Clean Architecture and DDD principles.
Each commit should:
Keep PRs small for faster reviews:
Good PR sizes:
How to keep PRs small:
Target review time: < 2 hours
Reviewer checklist:
Auto-approve criteria:
## What
Brief description of the change
## Why
Business reason or issue reference
## How
Technical approach
## Testing
- [ ] Unit tests added/updated
- [ ] Integration tests pass
- [ ] Manual testing done
## Checklist
- [ ] Follows coding standards
- [ ] Documentation updated
- [ ] No breaking changes (or flagged)
- [ ] Ready to merge
## Screenshots (if UI changes)
[Add screenshots]
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install -e ".[dev]"
- name: Lint
run: |
ruff check .
mypy src/
- name: Test
run: |
pytest --cov=src --cov-report=xml
- name: Coverage check
run: |
coverage report --fail-under=80
Main branch deploys automatically to staging:
# .github/workflows/deploy-staging.yml
name: Deploy to Staging
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy to staging
run: ./scripts/deploy-staging.sh
Create release tags from main:
# When ready to release
git checkout main
git pull
git tag -a v1.2.0 -m "Release v1.2.0: Add quota management"
git push origin v1.2.0
Follow semver (MAJOR.MINOR.PATCH):
v1.0.0 → Initial release
v1.1.0 → Add new quota rules (feature)
v1.1.1 → Fix quota calculation bug (patch)
v2.0.0 → Change quota API (breaking change)
feature-branch (30 days old)
└── 500 commits behind main
└── Massive merge conflicts
add-quota-entity (1 day) → merged
add-quota-validation (1 day) → merged
add-quota-ui (1 day, behind flag) → merged
Day 1: Start feature
Day 5: First merge from main
Day 10: Try to merge to main → Conflicts!
Day 1: Merge from main, work, merge to main
Day 2: Merge from main, work, merge to main
PR: "Implement entire admission system"
Files changed: 50
Lines changed: 2000+
Review time: 3 days
PR: "Add Grade value object"
Files changed: 3
Lines changed: 120
Review time: 15 minutes
# Set up helpful aliases
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.sync '!git fetch origin && git rebase origin/main'
# Set up pull to rebase by default
git config --global pull.rebase true
In GitHub/GitLab, protect main:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- repo: https://github.com/astral-sh/ruff-pre-commit
hooks:
- id: ruff
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
hooks:
- id: mypy
# 1. Create short-lived branch
git checkout -b add-age-requirement-rule
# 2. Implement (TDD)
# - Write tests
# - Implement rule
# - Tests pass
# 3. Commit
git add .
git commit -m "feat(admission): Add age requirement rule
Add rule to validate student age meets minimum requirement
for specific programs.
Refs: #234"
# 4. Push and create PR
git push origin add-age-requirement-rule
# 5. Quick review → merge → delete branch
# Day 1: Domain model
git checkout -b quota-domain-model
# Implement Quota entity, value objects
git commit -m "feat(quota): Add Quota entity and value objects"
# PR → merge → delete branch
# Day 2: Validation
git checkout -b quota-validation
# Add capacity validation
git commit -m "feat(quota): Add capacity validation"
# PR → merge → delete branch
# Day 3: Allocation algorithm (incomplete)
git checkout -b quota-allocation
# Add new algorithm behind feature flag
git commit -m "feat(quota): Add new allocation algorithm (feature-flagged)"
# PR → merge → delete branch
# Day 4: UI (hidden)
git checkout -b quota-ui
# Add UI behind same feature flag
git commit -m "feat(quota): Add quota management UI (feature-flagged)"
# PR → merge → delete branch
# Day 5: Enable feature
git checkout -b enable-quota-feature
# Change feature flag to enabled
git commit -m "feat(quota): Enable new quota system"
# PR → merge → delete branch
When practicing trunk-based development: