176 lines
5.3 KiB
YAML
176 lines
5.3 KiB
YAML
name: CI/CD
|
||
|
||
on:
|
||
pull_request:
|
||
types: [opened, synchronize, reopened]
|
||
branches:
|
||
- main
|
||
- test
|
||
workflow_dispatch:
|
||
|
||
jobs:
|
||
test-backend:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Проверка кода
|
||
uses: actions/checkout@v4
|
||
|
||
- name: Настройка Python
|
||
uses: actions/setup-python@v5
|
||
with:
|
||
python-version: '3.11'
|
||
|
||
- name: Кэширование pip
|
||
uses: actions/cache@v4
|
||
with:
|
||
path: ~/.cache/pip
|
||
key: ${{ runner.os }}-pip-${{ hashFiles('api/requirements.txt') }}
|
||
restore-keys: |
|
||
${{ runner.os }}-pip-
|
||
|
||
- name: Установка зависимостей
|
||
run: |
|
||
cd api
|
||
pip install -r requirements.txt
|
||
|
||
- name: Подтверждение сборки
|
||
run: |
|
||
python -c "from api.main import app"
|
||
|
||
- name: Запуск тестов
|
||
run: |
|
||
pytest -q
|
||
|
||
test-frontend:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Проверка кода
|
||
uses: actions/checkout@v4
|
||
|
||
- name: Настройка Node.js
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: '20'
|
||
|
||
- name: Установка зависимостей
|
||
run: |
|
||
cd web
|
||
npm ci
|
||
|
||
- name: Сборка фронта
|
||
run: |
|
||
cd web
|
||
npm run build
|
||
|
||
build-and-deploy:
|
||
needs: test-backend
|
||
runs-on: ubuntu-latest
|
||
if: success() # Запускается только если тесты прошли успешно
|
||
|
||
steps:
|
||
- name: Checkout code
|
||
uses: actions/checkout@v4
|
||
|
||
- name: Set up Docker Buildx
|
||
uses: docker/setup-buildx-action@v3
|
||
|
||
- name: Log in to container registry
|
||
uses: docker/login-action@v3
|
||
with:
|
||
registry: git.rlkdev.ru # Замените на ваш Gitea registry
|
||
username: ${{ secrets.REGISTRY_USERNAME }}
|
||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||
|
||
- name: Cache Docker layers
|
||
uses: actions/cache@v4
|
||
with:
|
||
path: /tmp/.buildx-cache
|
||
key: ${{ runner.os }}-buildx-${{ hashFiles('api/requirements.txt') }}
|
||
restore-keys: |
|
||
${{ runner.os }}-buildx-
|
||
|
||
- name: Build Docker image
|
||
uses: docker/build-push-action@v5
|
||
with:
|
||
context: .
|
||
push: false
|
||
load: true
|
||
tags: fastapi-app:latest
|
||
cache-from: type=local,src=/tmp/.buildx-cache
|
||
cache-to: type=local,dest=/tmp/.buildx-cache,mode=max
|
||
|
||
- name: Stop and remove old container
|
||
run: |
|
||
docker stop fastapi-container || true
|
||
docker rm fastapi-container || true
|
||
|
||
- name: Run new container
|
||
run: |
|
||
docker run -d \
|
||
--name fastapi-container \
|
||
-p 8080:8000 \
|
||
--restart unless-stopped \
|
||
fastapi-app:latest
|
||
|
||
- name: Wait for container to be ready
|
||
run: |
|
||
for i in {1..30}; do
|
||
if curl -s http://localhost:8080/health > /dev/null; then
|
||
echo "Container is ready!"
|
||
exit 0
|
||
fi
|
||
echo "Waiting for container... ($i/30)"
|
||
sleep 2
|
||
done
|
||
echo "Container failed to start properly"
|
||
docker logs fastapi-container
|
||
exit 1
|
||
|
||
- name: Verify deployment
|
||
run: |
|
||
curl -f http://localhost:8080/ || exit 1
|
||
echo "Deployment successful!"
|
||
|
||
# Явный статус для PR
|
||
pr-status:
|
||
needs: [test-backend, test-frontend]
|
||
runs-on: ubuntu-latest
|
||
if: always() && github.event_name == 'pull_request'
|
||
steps:
|
||
- name: Проверка статуса и обновление PR
|
||
env:
|
||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
run: |
|
||
# Определяем общий статус проверок
|
||
if [[ "${{ needs.test-backend.result }}" == "success" ]] && \
|
||
[[ "${{ needs.test-frontend.result }}" == "success" ]]; then
|
||
STATE="success"
|
||
DESCRIPTION="✅ Все проверки прошли успешно"
|
||
EXIT_CODE=0
|
||
else
|
||
STATE="failure"
|
||
DESCRIPTION="❌ Некоторые проверки сломались"
|
||
EXIT_CODE=1
|
||
fi
|
||
|
||
# Формируем URL для API статусов
|
||
REPO="${{ github.repository }}"
|
||
SHA="${{ github.event.pull_request.head.sha }}"
|
||
API_URL="${{ github.api_url }}/repos/${REPO}/statuses/${SHA}"
|
||
|
||
# Отправляем статус в Gitea
|
||
curl -X POST "$API_URL" \
|
||
-H "Authorization: token $GITHUB_TOKEN" \
|
||
-H "Content-Type: application/json" \
|
||
-d "{
|
||
\"state\": \"$STATE\",
|
||
\"context\": \"CI/CD Pipeline / Overall Status\",
|
||
\"description\": \"$DESCRIPTION\",
|
||
\"target_url\": \"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\"
|
||
}"
|
||
|
||
echo "Status $STATE sent for commit $SHA"
|
||
|
||
# Выходим с соответствующим кодом, чтобы блокировать PR при неудаче
|
||
exit $EXIT_CODE
|