diff --git a/.gitea/workflows/main.yml b/.gitea/workflows/main.yml index 986a349..1369b03 100644 --- a/.gitea/workflows/main.yml +++ b/.gitea/workflows/main.yml @@ -1,4 +1,4 @@ -name: 'Deploy quoter Microservice on push' +name: 'Deploy quoter' on: [push] @@ -10,256 +10,53 @@ jobs: image: redis:7-alpine ports: - 6379:6379 - options: >- - --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 + options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 + steps: - - name: Cloning repo - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Install Rust + - name: Setup Rust run: | - echo "🦀 Устанавливаем Rust toolchain..." - - # Проверяем, есть ли уже Rust - if command -v rustc >/dev/null 2>&1; then - echo "✅ Rust уже установлен: $(rustc --version)" - - # Обновляем до stable если нужно - rustup default stable || echo "⚠️ Не удалось установить stable toolchain" - - # Добавляем компоненты - rustup component add rustfmt || echo "⚠️ Не удалось добавить rustfmt" - rustup component add clippy || echo "⚠️ Не удалось добавить clippy" - else - echo "📦 Устанавливаем Rust с нуля..." - - # Используем официальный установщик - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal --no-modify-path - - # Добавляем в PATH - echo "$HOME/.cargo/bin" >> $GITHUB_PATH - export PATH="$HOME/.cargo/bin:$PATH" - - # Устанавливаем компоненты - rustup component add rustfmt || echo "⚠️ Не удалось установить rustfmt" - rustup component add clippy || echo "⚠️ Не удалось установить clippy" - fi - - # Финальная проверка + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal + echo "$HOME/.cargo/bin" >> $GITHUB_PATH export PATH="$HOME/.cargo/bin:$PATH" - rustc --version || echo "⚠️ rustc недоступен" - cargo --version || echo "⚠️ cargo недоступен" - rustfmt --version || echo "⚠️ rustfmt недоступен" - cargo clippy --version || echo "⚠️ clippy недоступен" + rustup component add rustfmt clippy - - name: Cache Cargo dependencies + - name: Cache Cargo uses: actions/cache@v3 with: path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ + ~/.cargo/registry/ target/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo- - - name: Prepare Environment + - name: Quality Checks run: | export PATH="$HOME/.cargo/bin:$PATH" - rustc --version - cargo --version - echo "🦀 Rust environment готов" + cargo fmt --check + cargo clippy --all-targets -- -D warnings - - name: Install Dependencies - run: | - echo "📦 Устанавливаем зависимости Rust..." - export PATH="$HOME/.cargo/bin:$PATH" - cargo fetch - - - name: Run linting - run: | - echo "🔍 Запускаем проверки качества кода..." - - # Убеждаемся что cargo доступен - export PATH="$HOME/.cargo/bin:$PATH" - - # Cargo fmt check - echo "🎨 Проверяем форматирование с помощью rustfmt..." - if command -v rustfmt >/dev/null 2>&1; then - cargo fmt --all -- --check || echo "⚠️ Проблемы с форматированием, но продолжаем" - else - echo "⚠️ rustfmt недоступен, пропускаем проверку форматирования" - fi - - # Clippy linting - echo "📝 Проверяем код с помощью clippy..." - if cargo clippy --version >/dev/null 2>&1; then - cargo clippy --all-targets --all-features -- -D warnings || echo "⚠️ Clippy warnings найдены, но продолжаем" - else - echo "⚠️ clippy недоступен, пропускаем проверку" - fi - - - name: Run type checking - continue-on-error: true - run: | - echo "🏷️ Проверяем типы с помощью Rust compiler..." - export PATH="$HOME/.cargo/bin:$PATH" - echo "📊 Доступная память:" - free -h - - # Проверяем доступную память - AVAILABLE_MEM=$(free -m | awk 'NR==2{printf "%.0f", $7}') - echo "📊 Доступно памяти: ${AVAILABLE_MEM}MB" - - # Если памяти меньше 1GB, используем минимальную проверку - if [ "$AVAILABLE_MEM" -lt 1000 ]; then - echo "⚠️ Недостаточно памяти для полной проверки (${AVAILABLE_MEM}MB < 1000MB), используем быструю проверку" - cargo check --release || echo "⚠️ Проблемы с проверкой типов" - echo "✅ Быстрая проверка типов завершена" - else - echo "🔍 Полная проверка типов..." - cargo check --all-targets --all-features || echo "⚠️ Проблемы с проверкой типов" - echo "✅ Полная проверка типов завершена" - fi - - - name: Build Release - run: | - echo "🏗️ Собираем release версию..." - export PATH="$HOME/.cargo/bin:$PATH" - cargo build --release || echo "⚠️ Проблемы со сборкой" - echo "✅ Release сборка завершена" - - - name: Run Tests + - name: Build & Test env: - RUST_LOG: "info" REDIS_URL: "redis://localhost:6379" run: | - echo "🧪 Запускаем тесты..." export PATH="$HOME/.cargo/bin:$PATH" - - # Проверяем доступность Redis - echo "🔍 Проверяем Redis..." - if timeout 5 bash -c 'echo > /dev/tcp/localhost/6379' 2>/dev/null; then - echo "✅ Redis доступен на localhost:6379" - else - echo "⚠️ Redis недоступен, но продолжаем тесты" - fi - - # Запускаем unit тесты (не требуют Redis) - echo "🧪 Запускаем unit тесты..." - cargo test --lib --verbose || echo "⚠️ Unit тесты завершились с ошибками" - - # Запускаем интеграционные тесты (могут требовать Redis) - echo "🧪 Запускаем интеграционные тесты..." - cargo test --test '*' --verbose || echo "⚠️ Интеграционные тесты завершились с ошибками" - - echo "✅ Тесты завершены" - continue-on-error: true + cargo build --release + cargo test --all - - name: Generate Coverage Report - continue-on-error: true + - name: Setup SSH run: | - echo "📊 Генерируем отчет о покрытии..." - export PATH="$HOME/.cargo/bin:$PATH" - - # Устанавливаем grcov если есть память - AVAILABLE_MEM=$(free -m | awk 'NR==2{printf "%.0f", $7}') - if [ "$AVAILABLE_MEM" -gt 1500 ]; then - cargo install grcov || echo "⚠️ Не удалось установить grcov" - - # Запускаем тесты с профилированием - CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' LLVM_PROFILE_FILE='cargo-test-%p-%m.profraw' cargo test || echo "⚠️ Тесты с покрытием завершились с ошибками" - - # Генерируем отчет - grcov . --binary-path ./target/debug/deps/ -s . -t lcov --branch --ignore-not-existing --ignore '../*' --ignore "/*" -o target/lcov.info || echo "⚠️ Не удалось сгенерировать отчет о покрытии" - - echo "✅ Отчет о покрытии готов" - else - echo "⚠️ Недостаточно памяти для генерации покрытия (${AVAILABLE_MEM}MB < 1500MB)" - fi - - - name: Security Audit - continue-on-error: true - run: | - echo "🔒 Проверяем безопасность зависимостей..." - export PATH="$HOME/.cargo/bin:$PATH" - cargo install cargo-audit || echo "⚠️ Не удалось установить cargo-audit" - cargo audit || echo "⚠️ Найдены уязвимости в зависимостях" - - - name: Restore Git Repository - if: always() - run: | - echo "🔧 Восстанавливаем git репозиторий для деплоя..." - # Проверяем состояние git - git status || echo "⚠️ Git репозиторий поврежден, восстанавливаем..." - - # Если git поврежден, переинициализируем - if [ ! -d ".git" ] || [ ! -f ".git/HEAD" ]; then - echo "🔄 Переинициализируем git репозиторий..." - git init - git remote add origin https://github.com/${{ github.repository }}.git - git fetch origin - git checkout ${{ github.ref_name }} - fi - - # Проверяем финальное состояние - git status - echo "✅ Git репозиторий готов для деплоя" - - - name: Get Repo Name - id: repo_name - run: echo "::set-output name=repo::$(echo ${GITHUB_REPOSITORY##*/})" - - - name: Get Branch Name - id: branch_name - run: echo "::set-output name=branch::$(echo ${GITHUB_REF##*/})" - - - name: Verify Git Before Deploy - run: | - echo "🔍 Проверяем git перед деплоем..." - git status - git log --oneline -5 - echo "✅ Git репозиторий готов" - - - name: Setup SSH for Deploy - run: | - echo "🔑 Настраиваем SSH для деплоя quoter микросервиса..." - - # Создаем SSH директорию mkdir -p ~/.ssh chmod 700 ~/.ssh - - # Добавляем приватный ключ (с сохранением переносов строк) printf '%s' "${{ secrets.STAGING_PRIVATE_KEY }}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa - - # Добавляем v3.dscrs.site в known_hosts ssh-keyscan -H v3.dscrs.site >> ~/.ssh/known_hosts - - # Запускаем ssh-agent и добавляем ключ eval $(ssh-agent -s) ssh-add ~/.ssh/id_rsa - - echo "✅ SSH настроен для v3.dscrs.site" - - name: Push to dokku + - name: Deploy run: | - echo "🚀 Деплоим quoter микросервис на v3.dscrs.site..." - - # Добавляем dokku remote для quoter микросервиса git remote add dokku ssh://dokku@v3.dscrs.site:22/quoter || git remote set-url dokku ssh://dokku@v3.dscrs.site:22/quoter - - # Проверяем remote - git remote -v - - # Деплоим текущую ветку git push dokku dev:main -f - - echo "✅ Деплой quoter микросервиса на dev завершен" \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b80185..8555f5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,18 @@ ## [0.6.10] - 2025-10-04 -### 🚀 CI/CD: Fixed SSH Key Loading -- **✅ Исправлена загрузка SSH ключа в CI**: Убран лишний `\n` в конце - - Изменено `printf '%s\n'` → `printf '%s'` в `.gitea/workflows/main.yml` - - Теперь ключ записывается точно как в секрете, без добавления символов - - Решает ошибку "Error loading key: error in libcrypto" - - Формат ключа остаётся валидным для OpenSSH +### 🚀 CI/CD: Optimization (YAGNI + DRY) +- **🪓 Упрощён CI pipeline**: 265 строк → 56 строк (-80%) + - Удалены избыточные проверки (`continue-on-error`, условные блоки памяти) + - Убраны неиспользуемые шаги: Coverage Report, Security Audit, Git Restore + - Объединены шаги: Install+Prepare → Setup Rust, Linting+TypeCheck → Quality Checks + - Удалены echo-логи (CI показывает команды автоматически) + - Minimal Rust profile вместо полного (быстрее установка) + - Упрощён кэш: только registry + target (без bin/git/index) + - Прямой `cargo test --all` вместо раздельных unit/integration + - Убраны проверки rustfmt/clippy availability (fail fast) + - Удалены get_repo_name/get_branch_name (не используются) +- **✅ Исправлена загрузка SSH ключа**: `printf '%s'` без лишнего `\n` + - Решает "Error loading key: error in libcrypto" ### 🔒 FIX: JWT Token Grace Period - **✅ Добавлен grace period для истекших токенов**: 60 секунд