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: Cache pip packages uses: actions/cache@v4 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('api/requirements.txt') }} - 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: git.rlkdev.ru/rlk/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-test-container || true docker rm fastapi-test-container || true - name: Run new container run: | docker run -d \ --name fastapi-test-container \ -p 8080:8000 \ --restart unless-stopped \ git.rlkdev.ru/rlk/fastapi-app:latest - name: Wait for container to be ready run: | timeout=60 interval=2 elapsed=0 while [ $elapsed -lt $timeout ]; do if docker logs fastapi-test-container 2>&1 | grep -q "Application startup complete"; then echo "Application startup detected in logs" echo "Deployment successful!" exit 0 fi echo "Waiting for startup log... ($elapsed/$timeout sec)" sleep $interval elapsed=$((elapsed + interval)) done echo "Timeout: Application startup not detected in logs" docker logs fastapi-container exit 1 - name: Clean up dangling images run: | echo "Removing old dangling images..." docker image prune -f echo "Current images after cleanup:" docker images # Явный статус для 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