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: Установка зависимостей 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: Build Docker image id: build uses: docker/build-push-action@v5 with: context: . push: false load: true tags: fastapi-app:latest cache-from: type=gha cache-to: type=gha,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