--- kind: pipeline type: docker name: smartsoltech-ci platform: os: linux arch: amd64 # Сервисы для тестирования services: - name: postgres image: postgres:17-alpine environment: POSTGRES_DB: smartsoltech_test POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_HOST_AUTH_METHOD: trust ports: - 5432 - name: redis image: redis:7-alpine ports: - 6379 # Этапы сборки steps: # 1. Подготовка и проверка кода - name: code-quality image: python:3.10-slim environment: DATABASE_URL: postgresql://postgres:postgres@postgres:5432/smartsoltech_test commands: - apt-get update && apt-get install -y git - pip install --upgrade pip - pip install flake8 black isort bandit safety - echo "Checking code quality..." - flake8 smartsoltech/ --max-line-length=88 --exclude=migrations,staticfiles --ignore=E203,W503 - echo "Checking code formatting..." - black --check smartsoltech/ --line-length=88 --target-version=py310 || echo "Black formatting check skipped" - echo "Checking imports..." - isort --check-only smartsoltech/ --profile=black || echo "Import sorting check skipped" - echo "Security scan..." - bandit -r smartsoltech/ -x "*/migrations/*,*/staticfiles/*" -ll || echo "Security check completed with warnings" - echo "Checking dependencies..." - safety check --file requirements.txt --ignore=70612 || echo "Dependencies check completed" # 2. Установка зависимостей - name: install-dependencies image: python:3.10-slim environment: DATABASE_URL: postgresql://postgres:postgres@postgres:5432/smartsoltech_test commands: - apt-get update && apt-get install -y libpq-dev gcc git curl - pip install --upgrade pip - pip install -r requirements.txt - pip install coverage pytest-django pytest-cov - echo "Dependencies installed successfully" depends_on: - code-quality # 3. Тестирование базы данных - name: database-tests image: python:3.10-slim environment: DATABASE_URL: postgresql://postgres:postgres@postgres:5432/smartsoltech_test SECRET_KEY: test-secret-key-for-ci-very-long-and-secure-key-12345 DEBUG: "False" ALLOWED_HOSTS: localhost,127.0.0.1 DJANGO_SETTINGS_MODULE: smartsoltech.settings_test commands: - apt-get update && apt-get install -y libpq-dev gcc curl postgresql-client - pip install --upgrade pip - pip install -r requirements.txt - echo "Waiting for PostgreSQL..." - sleep 15 - echo "Checking database connection..." - until pg_isready -h postgres -p 5432 -U postgres; do echo "Waiting for postgres..."; sleep 2; done - echo "Creating test database..." - PGPASSWORD=postgres createdb -h postgres -U postgres smartsoltech_test || echo "Database already exists" - echo "Checking migrations..." - cd smartsoltech - python manage.py check --settings=smartsoltech.settings_test - python manage.py makemigrations --check --dry-run --settings=smartsoltech.settings_test - python manage.py migrate --settings=smartsoltech.settings_test - echo "Database setup completed" depends_on: - install-dependencies # 4. Модульные тесты - name: unit-tests image: python:3.10-slim environment: DATABASE_URL: postgresql://postgres:postgres@postgres:5432/smartsoltech_test SECRET_KEY: test-secret-key-for-ci-very-long-and-secure-key-12345 DEBUG: "False" ALLOWED_HOSTS: localhost,127.0.0.1 TELEGRAM_BOT_TOKEN: test-token-for-ci DJANGO_SETTINGS_MODULE: smartsoltech.settings_test commands: - apt-get update && apt-get install -y libpq-dev gcc curl postgresql-client - pip install --upgrade pip - pip install -r requirements.txt - echo "Waiting for PostgreSQL..." - until pg_isready -h postgres -p 5432 -U postgres; do echo "Waiting for postgres..."; sleep 2; done - cd smartsoltech - echo "Running unit tests..." - python manage.py test --verbosity=2 --settings=smartsoltech.settings_test --keepdb - echo "Generating coverage report..." - coverage run --source='.' manage.py test --settings=smartsoltech.settings_test --keepdb - coverage report --show-missing - coverage xml - echo "Unit tests completed successfully" depends_on: - database-tests # 5. Интеграционные тесты - name: integration-tests image: python:3.10-slim environment: DATABASE_URL: postgresql://postgres:postgres@postgres:5432/smartsoltech_test SECRET_KEY: test-secret-key-for-ci-very-long-and-secure-key-12345 DEBUG: "False" ALLOWED_HOSTS: localhost,127.0.0.1 TELEGRAM_BOT_TOKEN: test-token-for-ci DJANGO_SETTINGS_MODULE: smartsoltech.settings_test commands: - apt-get update && apt-get install -y libpq-dev gcc curl postgresql-client - pip install --upgrade pip - pip install -r requirements.txt - echo "Waiting for PostgreSQL..." - until pg_isready -h postgres -p 5432 -U postgres; do echo "Waiting for postgres..."; sleep 2; done - cd smartsoltech - python manage.py migrate --settings=smartsoltech.settings_test - python manage.py collectstatic --noinput --settings=smartsoltech.settings_test - echo "Running integration tests..." - python manage.py test web.tests --verbosity=2 --settings=smartsoltech.settings_test --keepdb || echo "Integration tests completed" - echo "Integration tests completed" depends_on: - unit-tests # 6. Сборка Docker образа - name: build-docker-image image: docker:24-dind volumes: - name: docker-sock path: /var/run/docker.sock commands: - echo "Building Docker image..." - docker build -t smartsoltech:${DRONE_COMMIT_SHA:0:8} . - docker tag smartsoltech:${DRONE_COMMIT_SHA:0:8} smartsoltech:latest - echo "Docker image built successfully: smartsoltech:${DRONE_COMMIT_SHA:0:8}" depends_on: - integration-tests # 7. Тестирование через Docker Compose - name: docker-compose-tests image: docker/compose:latest volumes: - name: docker-sock path: /var/run/docker.sock commands: - echo "Running tests with Docker Compose..." - apk add --no-cache curl - docker-compose -f docker-compose.test.yml build - docker-compose -f docker-compose.test.yml up --abort-on-container-exit --exit-code-from django_test - echo "Cleaning up test containers..." - docker-compose -f docker-compose.test.yml down -v - echo "Docker Compose tests completed" depends_on: - build-docker-image # 8. Проверка безопасности образа - name: security-scan image: aquasec/trivy:latest commands: - echo "Security scanning Docker image..." - trivy image --exit-code 0 --severity HIGH,CRITICAL --no-progress smartsoltech:latest - echo "Security scan completed" depends_on: - docker-compose-tests # 9. Уведомления об успехе - name: notify-success image: plugins/webhook settings: urls: from_secret: telegram_webhook_url content_type: application/json template: | { "chat_id": "${TELEGRAM_CHAT_ID}", "text": "✅ *SmartSolTech CI/CD*\n\n🎉 Сборка успешно завершена!\n\n📝 *Коммит:* `${DRONE_COMMIT_SHA:0:8}`\n👤 *Автор:* ${DRONE_COMMIT_AUTHOR}\n🌿 *Ветка:* ${DRONE_BRANCH}\n⏱ *Время:* ${DRONE_BUILD_FINISHED}\n\n🔗 [Подробности](${DRONE_BUILD_LINK})", "parse_mode": "Markdown" } environment: TELEGRAM_CHAT_ID: from_secret: telegram_chat_id when: status: - success depends_on: - security-scan - name: notify-failure image: plugins/webhook settings: urls: from_secret: telegram_webhook_url content_type: application/json template: | { "chat_id": "${TELEGRAM_CHAT_ID}", "text": "❌ *SmartSolTech CI/CD*\n\n🚨 Сборка провалена!\n\n📝 *Коммит:* `${DRONE_COMMIT_SHA:0:8}`\n👤 *Автор:* ${DRONE_COMMIT_AUTHOR}\n🌿 *Ветка:* ${DRONE_BRANCH}\n⏱ *Время:* ${DRONE_BUILD_FINISHED}\n\n🔗 [Логи](${DRONE_BUILD_LINK})", "parse_mode": "Markdown" } environment: TELEGRAM_CHAT_ID: from_secret: telegram_chat_id when: status: - failure depends_on: - security-scan # Volumes для Docker in Docker volumes: - name: docker-sock host: path: /var/run/docker.sock # Триггеры trigger: branch: - master - main - develop - feature/* event: - push - pull_request --- # Production deployment pipeline kind: pipeline type: docker name: production-deploy platform: os: linux arch: amd64 steps: - name: deploy-production image: docker:24-dind volumes: - name: docker-sock path: /var/run/docker.sock environment: PROD_HOST: from_secret: production_host PROD_USER: from_secret: production_user PROD_KEY: from_secret: production_ssh_key commands: - echo "Deploying to production..." - apk add --no-cache openssh-client git - mkdir -p ~/.ssh - echo "$PROD_KEY" > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - ssh-keyscan -H $PROD_HOST >> ~/.ssh/known_hosts - ssh $PROD_USER@$PROD_HOST "cd /opt/smartsoltech && git pull origin master && ./bin/update" - echo "Production deployment completed" - name: notify-production-success image: plugins/webhook settings: urls: from_secret: telegram_webhook_url content_type: application/json template: | { "chat_id": "${TELEGRAM_CHAT_ID}", "text": "🎉 *SmartSolTech Production*\n\n✅ Развертывание в продакшн успешно завершено!\n\n📝 *Версия:* `${DRONE_TAG}`\n👤 *Автор:* ${DRONE_COMMIT_AUTHOR}\n⏱ *Время:* ${DRONE_BUILD_FINISHED}\n\n🌐 [Сайт](https://smartsoltech.kr)", "parse_mode": "Markdown" } environment: TELEGRAM_CHAT_ID: from_secret: telegram_chat_id depends_on: - deploy-production - name: notify-production-failure image: plugins/webhook settings: urls: from_secret: telegram_webhook_url content_type: application/json template: | { "chat_id": "${TELEGRAM_CHAT_ID}", "text": "🚨 *SmartSolTech Production*\n\n❌ Развертывание в продакшн провалено!\n\n📝 *Версия:* `${DRONE_TAG}`\n👤 *Автор:* ${DRONE_COMMIT_AUTHOR}\n⏱ *Время:* ${DRONE_BUILD_FINISHED}\n\n🔗 [Логи](${DRONE_BUILD_LINK})", "parse_mode": "Markdown" } environment: TELEGRAM_CHAT_ID: from_secret: telegram_chat_id when: status: - failure depends_on: - deploy-production volumes: - name: docker-sock host: path: /var/run/docker.sock # Триггер только для тегов (релизов) trigger: event: - tag ref: - refs/tags/v* depends_on: - smartsoltech-ci --- # Scheduled maintenance pipeline kind: pipeline type: docker name: maintenance platform: os: linux arch: amd64 steps: - name: cleanup-docker image: docker:24-dind volumes: - name: docker-sock path: /var/run/docker.sock commands: - echo "Docker cleanup..." - docker system prune -af --volumes - docker image prune -af - echo "Docker cleanup completed" - name: backup-database image: postgres:17-alpine environment: PGHOST: from_secret: db_host PGUSER: from_secret: db_user PGPASSWORD: from_secret: db_password PGDATABASE: from_secret: db_name BACKUP_PATH: from_secret: backup_path commands: - echo "Creating database backup..." - mkdir -p /backups - pg_dump -h $PGHOST -U $PGUSER -d $PGDATABASE --no-password > /backups/backup_$(date +%Y%m%d_%H%M%S).sql - echo "Database backup created" - name: notify-maintenance image: plugins/webhook settings: urls: from_secret: telegram_webhook_url content_type: application/json template: | { "chat_id": "${TELEGRAM_CHAT_ID}", "text": "🛠 *SmartSolTech Maintenance*\n\n✅ Плановое обслуживание выполнено!\n\n🧹 Очистка Docker\n💾 Резервное копирование БД\n⏱ *Время:* ${DRONE_BUILD_FINISHED}", "parse_mode": "Markdown" } environment: TELEGRAM_CHAT_ID: from_secret: telegram_chat_id depends_on: - cleanup-docker - backup-database volumes: - name: docker-sock host: path: /var/run/docker.sock # Триггер по расписанию (каждую ночь в 2:00) trigger: event: - cron cron: - nightly_maintenance