Files
guilan-ace-backend/.github/workflows/backend.yml
Amirhossein Khalili ff99130938 test: migrate backend suites to pytest with module coverage gate
Split backend tests into unit and integration suites, add isolated fixtures and coverage enforcement, and update CI and test documentation. Cover current authentication, content, notification, payment, media, and admin flows; fix behaviors revealed by the new tests. Validate both suites and the per-module gate against local PostgreSQL.
2026-09-26 16:50:29 +03:30

115 lines
3.5 KiB
YAML

name: Backend CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 30
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_DB: app
POSTGRES_PASSWORD: password
POSTGRES_USER: app
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U app -d app"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
SECRET_KEY: github-ci-secret-key
DEBUG: "False"
DJANGO_SETTINGS_MODULE: config.settings.test
ALLOWED_HOSTS: localhost,127.0.0.1,testserver
DJANGO_HOST: http://localhost:8000
DB_ENGINE: django.db.backends.postgresql
DB_NAME: app
DB_USER: app
DB_PASSWORD: password
DB_HOST: localhost
DB_PORT: "5432"
TEST_DB_ENGINE: django.db.backends.postgresql
TEST_DB_NAME: app
TEST_DB_USER: app
TEST_DB_PASSWORD: password
TEST_DB_HOST: localhost
TEST_DB_PORT: "5432"
REDIS_PASSWORD: ""
REDIS_URL: redis://localhost:6379/0
CELERY_BROKER_URL: redis://localhost:6379/0
CELERY_RESULT_BACKEND: redis://localhost:6379/1
CORS_ALLOWED_ORIGINS: http://localhost:3000
FRONTEND_ROOT: http://localhost:3000
FRONTEND_CALLBACK_URL: http://localhost:3000/payments/result
JWT_SECRET_KEY: test-jwt-key
JWT_ALGORITHM: HS256
JWT_ACCESS_TOKEN_LIFETIME: "3600"
JWT_REFRESH_TOKEN_LIFETIME: "86400"
ZARINPAL_MERCHANT_ID: sandbox-merchant
ZARINPAL_USE_SANDBOX: "True"
ZARINPAL_CALLBACK_URL: http://localhost:8000/api/payments/callback
PYTHON_VERSION: "3.12"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: pip
cache-dependency-path: requirements.txt
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-test.txt
- name: Prepare environment file
run: cp .env.test .env
- name: Run migrations
run: python manage.py migrate --noinput
- name: Run unit and integration tests with coverage
run: |
coverage run --rcfile=.coveragerc -m pytest -m unit -q
coverage run --rcfile=.coveragerc --append -m pytest -m integration -q
coverage report -m
coverage json -o coverage.json
python scripts/check_coverage.py coverage.json --minimum 80
deploy:
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
timeout-minutes: 30
steps:
- name: Deploy backend services
uses: appleboy/ssh-action@v1.2.0
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
port: ${{ secrets.DEPLOY_PORT }}
script: |
set -e
cd "${{ secrets.DEPLOY_PATH }}/backend/guilan-ace-backend"
git fetch --prune origin
git checkout "${{ vars.BACKEND_BRANCH || 'main' }}"
git pull --ff-only origin "${{ vars.BACKEND_BRANCH || 'main' }}"
cd "${{ secrets.DEPLOY_PATH }}"
docker compose up -d --build web worker beat
docker image prune -f