پروژه نهایی – workflow حرفهای
حالا همه دانش این دوره را در یک پروژه واقعی به کار میگیریم: ساخت یک Django REST API از صفر، با branching strategy، PR workflow، CI/CD، release management و deployment خودکار به سرور.
حالا همه دانش این دوره را در یک پروژه واقعی به کار میگیریم: ساخت یک Django REST API از صفر، با branching strategy، PR workflow، CI/CD، release management و deployment خودکار به سرور.
معرفی پروژه
یک API ساده برای مدیریت لیست خواندنی – book-tracker
- Django + DRF
- PostgreSQL
- Docker
- تست با pytest
- linting با ruff
- CI/CD کامل
- GitHub Pages برای documentation
- Release خودکار با semantic-release
گام ۱: راهاندازی Repository
# 1. ساخت ریپو در GitHub
gh repo create book-tracker
--public
--description "API for tracking books I've read"
--license MIT
--gitignore Python
--add-readme
# 2. clone
gh repo clone book-tracker
cd book-tracker
# 3. تنظیمات اولیه
git config user.name "Mohammad Ali"
git config user.email "you@example.com"
ساختار پروژه
mkdir -p .github/{workflows,ISSUE_TEMPLATE}
mkdir -p src/{api,books,users}
mkdir -p tests docs
touch
src/manage.py
src/requirements.txt
src/Dockerfile
docker-compose.yml
pyproject.toml
CHANGELOG.md
CONTRIBUTING.md
SECURITY.md
CODE_OF_CONDUCT.md
گام ۲: کد اولیه
requirements.txt
django==5.0.4
djangorestframework==3.15.0
psycopg[binary]==3.1.18
django-environ==0.11.2
gunicorn==21.2.0
requirements-dev.txt
-r requirements.txt
pytest==8.1.0
pytest-django==4.8.0
pytest-cov==5.0.0
ruff==0.4.0
pre-commit==3.7.0
pyproject.toml
[tool.ruff]
line-length = 100
target-version = "py312"
[tool.ruff.lint]
select = ["E", "F", "W", "I", "N", "B", "C4", "UP", "DJ"]
ignore = ["E501"]
[tool.pytest.ini_options]
DJANGO_SETTINGS_MODULE = "config.settings"
python_files = ["test_*.py", "*_test.py"]
addopts = "--cov=src --cov-report=term-missing"
Dockerfile
FROM python:3.12-slim
ENV PYTHONUNBUFFERED=1
PYTHONDONTWRITEBYTECODE=1
PIP_NO_CACHE_DIR=1
WORKDIR /app
COPY src/requirements.txt .
RUN pip install -r requirements.txt
COPY src/ .
EXPOSE 8000
CMD ["gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000"]
docker-compose.yml
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: booktracker
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- ./src:/app
ports:
- "8000:8000"
environment:
DATABASE_URL: postgres://postgres:postgres@db:5432/booktracker
DEBUG: "true"
depends_on:
- db
volumes:
pgdata:
Commit اولیه
git add .
git commit -m "feat: initial project structure"
git push origin main
گام ۳: Branching Strategy
برای این پروژه از GitHub Flow استفاده میکنیم:
main: deployable- هر فیچر:
feature/... - هر باگ:
fix/... - PR + CI + review قبل از merge
Branch Protection
# با gh CLI
gh api -X PUT
/repos/{owner}/{repo}/branches/main/protection
--input - <<EOF
{
"required_status_checks": {
"strict": true,
"contexts": ["test", "lint"]
},
"enforce_admins": false,
"required_pull_request_reviews": {
"required_approving_review_count": 1,
"dismiss_stale_reviews": true
},
"restrictions": null
}
EOF
گام ۴: CI – Test و Lint Workflow
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
cache-dependency-path: 'src/requirements*.txt'
- name: Install ruff
run: pip install ruff
- name: Lint
run: |
ruff check src/
ruff format --check src/
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: test
POSTGRES_DB: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s
strategy:
matrix:
python-version: ['3.11', '3.12']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install dependencies
working-directory: src
run: |
pip install -r requirements-dev.txt
- name: Run migrations
working-directory: src
env:
DATABASE_URL: postgres://postgres:test@localhost:5432/test
run: python manage.py migrate
- name: Run tests
working-directory: src
env:
DATABASE_URL: postgres://postgres:test@localhost:5432/test
run: pytest --cov=. --cov-report=xml
- name: Upload coverage
if: matrix.python-version == '3.12'
uses: codecov/codecov-action@v4
with:
files: src/coverage.xml
گام ۵: Build Docker Image
# .github/workflows/docker.yml
name: Docker
on:
push:
branches: [main]
tags: ['v*']
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=ref,event=branch
type=ref,event=tag
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,format=short
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
گام ۶: Deploy به سرور
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: production
url: https://api.example.com
steps:
- uses: actions/checkout@v4
- name: Setup SSH
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Add server to known_hosts
run: ssh-keyscan -H ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts
- name: Deploy
run: |
ssh ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} '
cd /var/www/book-tracker
docker compose pull
docker compose up -d --remove-orphans
docker compose exec -T web python manage.py migrate --noinput
docker compose exec -T web python manage.py collectstatic --noinput
'
- name: Health check
run: |
sleep 10
curl -f https://api.example.com/health || exit 1
- name: Notify Slack
if: always()
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "Deploy ${{ job.status }}: ${{ github.sha }}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Deploy ${{ job.status }}*nSha: `${{ github.sha }}`nBy: ${{ github.actor }}"
}
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
گام ۷: Release خودکار
با release-please از Google:
# .github/workflows/release-please.yml
name: Release Please
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
release-type: python
package-name: book-tracker
این workflow بر اساس Conventional Commits، خودکار:
- Release PR میسازد (آپدیت version + CHANGELOG)
- وقتی merge شود، release میسازد
- tag میزند
گام ۸: Issue Templates
# .github/ISSUE_TEMPLATE/bug.yml
name: 🐛 Bug Report
description: گزارش یک باگ
labels: ["bug", "needs-triage"]
body:
- type: textarea
attributes:
label: شرح باگ
validations:
required: true
- type: textarea
attributes:
label: مراحل بازتولید
validations:
required: true
- type: input
attributes:
label: نسخه
validations:
required: true
# .github/ISSUE_TEMPLATE/feature.yml
name: ✨ Feature Request
description: درخواست قابلیت جدید
labels: ["enhancement"]
body:
- type: textarea
attributes:
label: شرح
validations:
required: true
- type: textarea
attributes:
label: انگیزه
description: چرا این مفید است؟
گام ۹: PR Template
# .github/pull_request_template.md
## شرح
(شرح تغییرات)
## نوع تغییر
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation
## چکلیست
- [ ] تستها اضافه/بهروز شدهاند
- [ ] مستندات بهروز شده
- [ ] CHANGELOG بهروز شده (یا توسط release-please)
- [ ] لینت قبول میشود
- [ ] Self-review انجام شده
## Issues مرتبط
Closes #
گام ۱۰: CONTRIBUTING.md
# CONTRIBUTING.md
## نحوه مشارکت
1. Fork ریپو
2. Clone fork
3. ساخت branch: `git switch -c feature/your-feature`
4. تغییرات با [Conventional Commits](https://www.conventionalcommits.org/)
5. تستها: `pytest`
6. لینت: `ruff check src/`
7. Push و PR
## نامگذاری Branch
- `feature/...` - فیچر جدید
- `fix/...` - باگ
- `docs/...` - مستندات
- `chore/...` - maintenance
## Conventional Commits
- `feat:` فیچر جدید
- `fix:` رفع باگ
- `docs:` مستندات
- `refactor:` بازنویسی
- `test:` تست
- `chore:` maintenance
- `BREAKING CHANGE:` تغییر breaking
## راهاندازی محلی
```bash
docker compose up -d
docker compose exec web python manage.py migrate
docker compose exec web python manage.py createsuperuser
```
## تست
```bash
docker compose exec web pytest
```
گام ۱۱: SECURITY.md
# SECURITY.md
## نسخههای پشتیبانیشده
| Version | Supported |
| ------- | ------------------ |
| 1.x | :white_check_mark: |
## گزارش vulnerability
لطفاً مشکلات امنیتی را به ایمیل **security@example.com** بفرستید
بهجای issue عمومی.
ما در ۲۴ ساعت پاسخ میدهیم.
گام ۱۲: Dependabot
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: pip
directory: /src
schedule:
interval: weekly
commit-message:
prefix: "chore(deps)"
groups:
django:
patterns: ["django*"]
- package-ecosystem: docker
directory: /
schedule:
interval: monthly
- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly
گام ۱۳: GitHub Pages برای Docs
# .github/workflows/docs.yml
name: Docs
on:
push:
branches: [main]
paths: ['docs/**', 'mkdocs.yml']
permissions:
contents: read
pages: write
id-token: write
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- run: pip install mkdocs-material
- run: mkdocs build
- uses: actions/upload-pages-artifact@v3
with:
path: site/
- id: deployment
uses: actions/deploy-pages@v4
گام ۱۴: یک فیچر کامل
سناریو: قابلیت rating برای کتابها
# 1. issue باز کن
gh issue create
--title "Add rating field to books"
--body "Books should have a 1-5 star rating"
--label feature
# 2. branch
git switch -c feature/book-rating
# 3. توسعه
# (ویرایش models.py، serializers.py، tests/)
# 4. commit با Conventional Commits
git add .
git commit -m "feat(books): add 1-5 star rating field
Closes #5"
# 5. push
git push -u origin feature/book-rating
# 6. PR
gh pr create
--title "feat(books): add rating field"
--body "Closes #5"
--label feature
# 7. CI اجرا میشود (test + lint)
gh pr checks
# 8. منتظر review
# 9. اعمال feedback
git commit -am "fix: address review comments"
git push
# 10. merge (با squash)
gh pr merge --squash --delete-branch
# 11. release-please خودکار PR release میسازد
# 12. merge آن PR ⇒ tag و release خودکار
گام ۱۵: Hotfix
سناریو: باگ بحرانی در production
# 1. issue
gh issue create
--title "[CRITICAL] Login broken"
--label "bug,priority:critical"
# 2. fix
git switch main
git pull
git switch -c fix/critical-login
# fix...
git commit -am "fix(auth): handle null user in login"
# 3. PR fast-track
gh pr create
--title "fix(auth): critical login fix"
--body "Closes #X"
# 4. emergency review (با تأیید سریع)
# 5. merge
gh pr merge --squash --delete-branch
# 6. release-please patch release میسازد
# 7. deploy خودکار به prod
چکلیست پروژه حرفهای
| مورد | وضعیت |
|---|---|
| README جذاب با badges | ✓ |
| LICENSE | ✓ |
| CONTRIBUTING.md | ✓ |
| CODE_OF_CONDUCT.md | ✓ |
| SECURITY.md | ✓ |
| CHANGELOG.md (auto) | ✓ |
| .gitignore کامل | ✓ |
| Issue templates (YAML) | ✓ |
| PR template | ✓ |
| Branch protection | ✓ |
| CI: test + lint + matrix | ✓ |
| CD: deploy خودکار | ✓ |
| Docker build | ✓ |
| Dependabot | ✓ |
| Secret scanning | ✓ |
| Code scanning (CodeQL) | ✓ |
| Release خودکار | ✓ |
| Documentation روی Pages | ✓ |
| Conventional Commits | ✓ |
| 2FA | ✓ |
| Signed commits (اختیاری) | ↗ |
بعد از Launch
monitoring
- Sentry برای error tracking
- Prometheus + Grafana برای metrics
- Slack notifications برای alert
community
- “good first issue” برای contributorها
- Discussions برای سوالات
- Discord/Slack server
- پاسخ سریع به PR و issue
maintenance
- weekly: review Dependabot PRs
- monthly: release notes + announcement
- quarterly: strategic review
قدمهای بعدی
بعد از این دوره میتوانید روی این مباحث پیشرفته کار کنید:
- GitHub Packages: میزبانی pip/npm/maven packages
- GitHub Codespaces: VS Code در ابر
- Custom GitHub Apps: ساخت app برای marketplace
- GitHub Enterprise: self-hosted GitHub
- OAuth Apps: ادغام GitHub auth در سایت خود
- Reusable Actions: ساخت Action سفارشی
جمعبندی – پایان دوره
تبریک! 🎉 شما این دوره ۱۵ فصلی GitHub را به پایان رساندید. در این دوره آموختیم:
- Git پایه: init، add، commit، log، diff
- Branching: branch، merge، conflict resolution
- Remote: clone، push، pull، fetch، SSH
- Collaboration: Fork، PR، Code Review، Branch Protection
- Recovery: reset، revert، reflog، bisect
- Strategy: Git Flow، GitHub Flow، Trunk-Based
- Advanced: Rebase، Stash، Interactive Rebase، Squash
- Releases: Tag، GitHub Releases، SemVer، CHANGELOG
- Project Management: Issues، Labels، Milestones، Projects
- CI/CD: GitHub Actions با matrix، secrets، deploy
- Security: 2FA، Dependabot، Secret/Code Scanning، GPG
- Documentation: Pages، Wiki، MkDocs
- Automation: gh CLI، REST/GraphQL API، Webhooks
- پروژه واقعی end-to-end