حول المحتوى:
دليل عملي لبناء خط نشر تلقائي باستخدام GitHub Actions لاختبار وبناء ونشر تطبيق Django.
إذا كنت تطور تطبيقات Django بانتظام، فغالباً أن عملية التشغيل محلياً، تشغيل الاختبارات، ثم رفع الكود يدوياً للسيرفر بدأت تصبح مرهقة وتستهلك وقتاً. هنا يأتي دور CI CD GitHub Actions لبناء خط نشر (Pipeline) آلي يختبر ويبني وينشر مشروعك تلقائياً مع كل تحديث للكود.
في هذا الدليل العملي من افهم صح سنقوم ببناء خط CI/CD كامل باستخدام GitHub Actions لمشروع Django، بداية من الإعدادات الأساسية، مروراً بتشغيل الاختبارات، وحتى نشر التطبيق تلقائياً على السيرفر أو أي منصة استضافة تدعم Git.
CI (تكامل مستمر) يعني أن كل تغيير في الكود يتم اختباره ودمجه بشكل مستمر مع الفرع الرئيسي. CD (نشر مستمر أو تسليم مستمر) يعني نشر هذه التغييرات تلقائياً إلى بيئة التشغيل (Production أو Staging) بعد نجاح الاختبارات.
GitHub Actions هو نظام CI/CD مدمج داخل GitHub يمكّنك من:
إذا كنت مهتماً بخطوط نشر أكثر تعقيداً مع AWS، يمكنك قراءة دليلنا: نشر مشروع Django على AWS باستخدام CI/CD عملي.
قبل أن نبدأ في كتابة ملف GitHub Actions، تأكد من:
requirements.txt أو pyproject.toml يحتوي على مكتبات المشروع.docker-compose.إذا كنت تستخدم Docker في نشر مشاريعك على VPS، يمكنك الاستفادة من: نشر مشاريع Django و FastAPI على VPS باستخدام Docker Compose خطوة بخطوة.
يفضل أن يكون مشروعك منظمًا كالتالي (كمثال شائع):
project-root/
├─ manage.py
├─ requirements.txt
├─ app/ أو core/ (المجلد الرئيسي للتطبيق)
├─ project_name/ (مجلد إعدادات Django)
│ ├─ settings.py
│ ├─ urls.py
│ └─ wsgi.py
└─ .github/
└─ workflows/
سنضيف داخل مجلد .github/workflows/ ملف ci-cd.yml أو أي اسم تختاره، ليحتوي على إعدادات CI CD GitHub Actions.
أي ملف GitHub Actions عبارة عن:
سنقوم ببناء خط بسيط مكوّن من:
أنشئ المسار التالي إن لم يكن موجوداً:
.github/workflows/django-ci-cd.yml وأضف الهيكل الأولي:
name: Django CI CD
on:
push:
branches: [ "main", "master" ]
pull_request:
branches: [ "main", "master" ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
بهذا الشكل نقول لـ GitHub Actions: عند أي push أو pull_request على فرع main أو master شغّل Job اسمه test.
داخل Job test نحتاج تثبيت Python وحزم المشروع:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
يمكنك تعديل إصدار Python حسب ما تستخدمه في مشروعك.
في بيئة CI، غالباً نستخدم SQLite بشكل افتراضي لأنها سهلة ولا تحتاج إعدادات. فقط تأكد أن settings.py يدعم هذا (غالباً الإعداد الافتراضي في Django).
الآن نضيف خطوة لتجهيز متغيرات البيئة وتشغيل الاختبارات:
- name: Run Django tests
env:
DJANGO_SETTINGS_MODULE: project_name.settings
run: |
python manage.py migrate --noinput
python manage.py test
استبدل project_name.settings باسم مشروعك الفعلي. هذه الخطوة:
migrate لتجهيز قاعدة البيانات.test لتشغيل اختبارات Django.لو كنت تستخدم pytest، يمكن تعديل خطوة الاختبار إلى:
- name: Run tests with pytest
env:
DJANGO_SETTINGS_MODULE: project_name.settings
run: |
python manage.py migrate --noinput
pytest
وللمزيد عن pytest، يمكنك مراجعة: اختبار الوحدات في بايثون باستخدام pytest: دليل عملي.
الآن بعد أن أصبح لدينا CI يعمل، نريد نشر مشروع Django تلقائياً على بيئة الإنتاج بعد كل push (أو بعد tag معين مثلاً). سنفترض سيناريو شائع: نشر إلى خادم VPS باستخدام SSH و Git أو Docker.
اذهب إلى:
أضف أسرار مثل:
SSH_HOST: عنوان السيرفر (مثلاً: your-server.com).SSH_USER: اسم المستخدم على السيرفر (مثلاً: ubuntu).SSH_KEY: المفتاح الخاص (Private Key) لـ SSH (يُنسخ محتوى الملف id_rsa).هذه الأسرار سنستخدمها داخل GitHub Actions للوصول الآمن إلى السيرفر ونشر الكود.
سنضيف Job جديد داخل نفس الملف اسمه مثلاً deploy، يعتمد على نجاح Job test:
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v4
السطر if: github.ref == 'refs/heads/main' يضمن أن النشر يتم فقط إذا كان الـ push على فرع main (يمكنك تغييره حسب سياسة النشر لديك).
نستخدم Action جاهزة مثل webfactory/ssh-agent لإضافة المفتاح الخاص وتشغيل أوامر SSH:
- name: Setup SSH
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SSH_KEY }}
- name: Add known hosts
run: |
ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
الآن يمكننا تنفيذ أوامر مباشرة على السيرفر عبر SSH.
نفترض أنك على السيرفر لديك:
/var/www/myproject.gunicorn تعمل كـ systemd service مثلاً gunicorn-myproject.نضيف خطوة تنفيذ أوامر SSH:
- name: Deploy to VPS
run: |
ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'EOF'
cd /var/www/myproject
git pull origin main
source venv/bin/activate
pip install -r requirements.txt
python manage.py migrate --noinput
python manage.py collectstatic --noinput
sudo systemctl restart gunicorn-myproject
sudo systemctl restart nginx
EOF
بهذه الأوامر:
gunicorn و nginx.يمكنك تعديل المسارات والأوامر حسب إعدادات سيرفرك.
إليك ملف متكامل يمكنك نسخه وتعديله وفقاً لمشروعك:
name: Django CI CD
on:
push:
branches: [ "main", "master" ]
pull_request:
branches: [ "main", "master" ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run Django tests
env:
DJANGO_SETTINGS_MODULE: project_name.settings
run: |
python manage.py migrate --noinput
python manage.py test
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup SSH
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SSH_KEY }}
- name: Add known hosts
run: |
ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
- name: Deploy to VPS
run: |
ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} << 'EOF'
cd /var/www/myproject
git pull origin main
source venv/bin/activate
pip install -r requirements.txt
python manage.py migrate --noinput
python manage.py collectstatic --noinput
sudo systemctl restart gunicorn-myproject
sudo systemctl restart nginx
EOF
تذكّر تعديل:
project_name.settings./var/www/myproject.gunicorn-myproject. في بيئة الإنتاج، غالباً تستخدم متغيرات بيئة حساسة مثل SECRET_KEY، بيانات قاعدة البيانات، مفاتيح OAuth2 وغيرها. لا يجب أن تُرفع هذه القيم إلى Git.
أشهر الطرق للتعامل معها في سياق CI/CD:
.env على السيرفر وحده (لا يُرفع إلى المستودع).إذا كنت تبني منظومة مصادقة مثل OAuth2 في مشروع Django أو FastAPI، راجع: تنفيذ OAuth2 في Django و FastAPI: دليل عملي كامل لتفهم حساسية إدارة المفاتيح والأسرار وما يرتبط بها في بيئات الإنتاج.
لمشاريع أكبر وأكثر تعقيداً، يمكنك تطوير خط CI/CD كالتالي:
flake8 أو black للتحقق من أسلوب الكود.ولأفكار أكثر حول أتمتة المهام للمطورين باستخدام GitHub Actions يمكنك الرجوع إلى: أتمتة مهام الروتين اليومي للمطورين باستخدام GitHub Actions.
dev حتى لا تعطل بيئة الإنتاج.settings.py.بناء خط CI CD GitHub Actions لمشروع Django لم يعد رفاهية، بل أصبح جزءاً أساسياً من أي عملية تطوير احترافية. بفضل GitHub Actions يمكنك:
ابدأ بالملف البسيط الذي عرضناه، ثم طوّره تدريجياً ليتناسب مع احتياجات مشروعك: أضف Docker، بيئات متعددة، اختبارات أمان، وتحليلات جودة الكود. ومع الوقت ستجد أن خط CI/CD الخاص بك أصبح جزءاً لا يتجزأ من بنية مشروعك، تماماً مثل كود Django نفسه.
دليل عملي لبناء خط نشر تلقائي باستخدام GitHub Actions لاختبار وبناء ونشر تطبيق Django.
مساحة اعلانية