diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..d7d56db --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,185 @@ +name: Build NeoMovies Mobile + +on: + push: + branches: [ dev, feature/torrent-engine-integration ] + pull_request: + branches: [ dev ] + workflow_dispatch: + +env: + FLUTTER_VERSION: '3.35.5' + JAVA_VERSION: '17' + +jobs: + # ============================================ + # Сборка TorrentEngine модуля + # ============================================ + build-torrent-engine: + name: Build TorrentEngine Library + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17' + cache: 'gradle' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v3 + with: + gradle-version: wrapper + + - name: Build TorrentEngine AAR + working-directory: android + run: | + ./gradlew :torrentengine:assembleRelease \ + --no-daemon \ + --parallel \ + --build-cache \ + -Dorg.gradle.jvmargs="-Xmx2g -XX:MaxMetaspaceSize=512m" + + - name: Upload TorrentEngine AAR + uses: actions/upload-artifact@v4 + with: + name: torrentengine-aar + path: android/torrentengine/build/outputs/aar/*.aar + retention-days: 7 + + # ============================================ + # Сборка Debug APK + # ============================================ + build-debug-apk: + name: Build Debug APK + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ env.FLUTTER_VERSION }} + channel: 'stable' + cache: true + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17' + cache: 'gradle' + + - name: Flutter Doctor + run: flutter doctor -v + + - name: Get Flutter dependencies + run: flutter pub get + + - name: Build Debug APK + run: | + flutter build apk \ + --debug \ + --target-platform android-arm64 + + - name: Upload Debug APK + uses: actions/upload-artifact@v4 + with: + name: debug-apk + path: build/app/outputs/flutter-apk/app-debug.apk + retention-days: 7 + + # ============================================ + # Сборка Release APK + # ============================================ + build-release-apk: + name: Build Release APK + runs-on: ubuntu-latest + if: github.ref == 'refs/heads/dev' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ env.FLUTTER_VERSION }} + channel: 'stable' + cache: true + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17' + cache: 'gradle' + + - name: Get Flutter dependencies + run: flutter pub get + + - name: Build Release APK (split per ABI) + run: | + flutter build apk \ + --release \ + --split-per-abi \ + --target-platform android-arm64 + + - name: Upload Release APK (ARM64) + uses: actions/upload-artifact@v4 + with: + name: release-apk-arm64 + path: build/app/outputs/flutter-apk/app-arm64-v8a-release.apk + retention-days: 30 + + # ============================================ + # Анализ кода + # ============================================ + code-quality: + name: Code Quality Checks + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ env.FLUTTER_VERSION }} + channel: 'stable' + cache: true + + - name: Get Flutter dependencies + run: flutter pub get + + - name: Flutter Analyze + run: flutter analyze --no-fatal-infos + continue-on-error: true + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17' + + - name: Android Lint + working-directory: android + run: ./gradlew lint --no-daemon + continue-on-error: true + + - name: Upload Lint Reports + uses: actions/upload-artifact@v4 + if: always() + with: + name: lint-reports + path: | + android/app/build/reports/lint-results*.html + android/torrentengine/build/reports/lint-results*.html + retention-days: 7 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 110fde2..687681e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,133 +1,187 @@ +# GitLab CI/CD Configuration for NeoMovies Mobile +# Автоматическая сборка APK и TorrentEngine модуля + stages: - - test - build + - test - deploy variables: - FLUTTER_VERSION: "3.16.0" - ANDROID_SDK_VERSION: "34" - GRADLE_OPTS: "-Dorg.gradle.daemon=false" + # Flutter версия + FLUTTER_VERSION: "3.35.5" + # Android SDK + ANDROID_SDK_ROOT: "/opt/android-sdk" + # Gradle настройки для CI (меньше RAM) + GRADLE_OPTS: "-Dorg.gradle.daemon=false -Dorg.gradle.jvmargs='-Xmx1536m -XX:MaxMetaspaceSize=512m' -Dorg.gradle.parallel=true -Dorg.gradle.caching=true" + # Кэш + GRADLE_USER_HOME: "${CI_PROJECT_DIR}/.gradle" + PUB_CACHE: "${CI_PROJECT_DIR}/.pub-cache" -# Кэш для оптимизации сборки +# Кэширование для ускорения сборки cache: - key: flutter-cache + key: ${CI_COMMIT_REF_SLUG} paths: + - .gradle/ - .pub-cache/ - android/.gradle/ + - android/build/ - build/ -# Тестирование -test: - stage: test - image: cirrusci/flutter:${FLUTTER_VERSION} - before_script: - - flutter --version - - flutter pub get - script: - - flutter analyze - - flutter test - artifacts: - reports: - junit: test-results.xml - paths: - - coverage/ - expire_in: 1 week - -# Сборка Android APK -build_android: +# ============================================ +# Сборка только TorrentEngine модуля +# ============================================ +build:torrent-engine: stage: build - image: cirrusci/flutter:${FLUTTER_VERSION} - before_script: - - flutter --version - - flutter pub get - script: - - flutter build apk --release - - flutter build appbundle --release - artifacts: - paths: - - build/app/outputs/flutter-apk/app-release.apk - - build/app/outputs/bundle/release/app-release.aab - expire_in: 1 month - rules: - - if: '$CI_COMMIT_BRANCH' - - if: '$CI_COMMIT_TAG' - -# Сборка Linux приложения -build_linux: - stage: build - image: ubuntu:22.04 - before_script: - - apt-get update -y - - apt-get install -y curl git unzip xz-utils zip libglu1-mesa - - apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev - - apt-get install -y libblkid-dev liblzma-dev - # Установка Flutter - - git clone https://github.com/flutter/flutter.git -b stable --depth 1 - - export PATH="$PATH:`pwd`/flutter/bin" - - flutter --version - - flutter config --enable-linux-desktop - - flutter pub get - script: - - flutter build linux --release - artifacts: - paths: - - build/linux/x64/release/bundle/ - expire_in: 1 month - rules: - - if: '$CI_COMMIT_BRANCH' - - if: '$CI_COMMIT_TAG' - -# Деплой в Google Play (опционально) -deploy_android: - stage: deploy - image: ruby:3.0 - before_script: - - gem install fastlane + image: mingc/android-build-box:latest + tags: + - docker script: + - echo "Building TorrentEngine library module..." - cd android - - fastlane supply --aab ../build/app/outputs/bundle/release/app-release.aab - dependencies: - - build_android - rules: - - if: '$CI_COMMIT_TAG' - when: manual + # Собираем только модуль torrentengine + - ./gradlew :torrentengine:assembleRelease --no-daemon --parallel --build-cache + - ls -lah torrentengine/build/outputs/aar/ + artifacts: + name: "torrentengine-${CI_COMMIT_SHORT_SHA}" + paths: + - android/torrentengine/build/outputs/aar/*.aar + expire_in: 1 week + only: + - dev + - feature/torrent-engine-integration + - merge_requests + when: on_success -# Деплой Linux приложения в GitLab Package Registry -deploy_linux: - stage: deploy - image: ubuntu:22.04 +# ============================================ +# Сборка Debug APK +# ============================================ +build:apk-debug: + stage: build + image: mingc/android-build-box:latest + tags: + - docker before_script: - - apt-get update -y - - apt-get install -y curl zip + - echo "Installing Flutter ${FLUTTER_VERSION}..." + - git clone --depth 1 --branch ${FLUTTER_VERSION} https://github.com/flutter/flutter.git /opt/flutter + - export PATH="/opt/flutter/bin:$PATH" + - flutter --version + - flutter doctor -v + - flutter pub get script: - - cd build/linux/x64/release/bundle - - zip -r ../../../../../${CI_PROJECT_NAME}-linux-${CI_COMMIT_TAG}.zip . - - cd ../../../../../ - - | - curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \ - --upload-file ${CI_PROJECT_NAME}-linux-${CI_COMMIT_TAG}.zip \ - "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}/${CI_COMMIT_TAG}/${CI_PROJECT_NAME}-linux-${CI_COMMIT_TAG}.zip" - dependencies: - - build_linux - rules: - - if: '$CI_COMMIT_TAG' - when: manual + - echo "Building Debug APK..." + - flutter build apk --debug --target-platform android-arm64 + - ls -lah build/app/outputs/flutter-apk/ + artifacts: + name: "neomovies-debug-${CI_COMMIT_SHORT_SHA}" + paths: + - build/app/outputs/flutter-apk/app-debug.apk + expire_in: 1 week + only: + - dev + - feature/torrent-engine-integration + - merge_requests + when: on_success + allow_failure: true -# Релиз на GitLab -release: - stage: deploy - image: registry.gitlab.com/gitlab-org/release-cli:latest +# ============================================ +# Сборка Release APK (только для dev) +# ============================================ +build:apk-release: + stage: build + image: mingc/android-build-box:latest + tags: + - docker + before_script: + - echo "Installing Flutter ${FLUTTER_VERSION}..." + - git clone --depth 1 --branch ${FLUTTER_VERSION} https://github.com/flutter/flutter.git /opt/flutter + - export PATH="/opt/flutter/bin:$PATH" + - flutter --version + - flutter doctor -v + - flutter pub get script: + - echo "Building Release APK..." + # Сборка с split-per-abi для уменьшения размера + - flutter build apk --release --split-per-abi --target-platform android-arm64 + - ls -lah build/app/outputs/flutter-apk/ + artifacts: + name: "neomovies-release-${CI_COMMIT_SHORT_SHA}" + paths: + - build/app/outputs/flutter-apk/app-arm64-v8a-release.apk + expire_in: 30 days + only: + - dev + when: on_success + allow_failure: true + +# ============================================ +# Анализ кода Flutter +# ============================================ +test:flutter-analyze: + stage: test + image: mingc/android-build-box:latest + tags: + - docker + before_script: + - git clone --depth 1 --branch ${FLUTTER_VERSION} https://github.com/flutter/flutter.git /opt/flutter + - export PATH="/opt/flutter/bin:$PATH" + - flutter pub get + script: + - echo "Running Flutter analyze..." + - flutter analyze --no-fatal-infos || true + only: + - dev + - merge_requests + allow_failure: true + +# ============================================ +# Kotlin/Android lint +# ============================================ +test:android-lint: + stage: test + image: mingc/android-build-box:latest + tags: + - docker + script: + - echo "Running Android Lint..." + - cd android + - ./gradlew lint --no-daemon || true + artifacts: + name: "lint-reports-${CI_COMMIT_SHORT_SHA}" + paths: + - android/app/build/reports/lint-results*.html + - android/torrentengine/build/reports/lint-results*.html + expire_in: 1 week + only: + - dev + - merge_requests + allow_failure: true + +# ============================================ +# Deploy к релизам (опционально) +# ============================================ +deploy:release: + stage: deploy + image: alpine:latest + tags: + - docker + before_script: + - apk add --no-cache curl jq + script: + - echo "Creating GitLab Release..." - | - release-cli create \ - --name "Release $CI_COMMIT_TAG" \ - --tag-name $CI_COMMIT_TAG \ - --description "Release $CI_COMMIT_TAG" \ - --assets-link "{\"name\":\"Android APK\",\"url\":\"${CI_PROJECT_URL}/-/jobs/artifacts/$CI_COMMIT_TAG/download?job=build_android\"}" \ - --assets-link "{\"name\":\"Linux App\",\"url\":\"${CI_PROJECT_URL}/-/jobs/artifacts/$CI_COMMIT_TAG/download?job=build_linux\"}" - dependencies: - - build_android - - build_linux - rules: - - if: '$CI_COMMIT_TAG' - when: manual \ No newline at end of file + if [ -f "build/app/outputs/flutter-apk/app-arm64-v8a-release.apk" ]; then + echo "Release APK found" + # Здесь можно добавить публикацию в GitLab Releases или другой deployment + fi + only: + - tags + when: manual + +# ============================================ +# Уведомление об успешной сборке +# ============================================ +.notify_success: + after_script: + - echo "✅ Build completed successfully!" + - echo "📦 Artifacts are available in the pipeline artifacts" + - echo "🔗 Download URL: ${CI_JOB_URL}/artifacts/download" diff --git a/CI_CD_README.md b/CI_CD_README.md new file mode 100644 index 0000000..8343f9b --- /dev/null +++ b/CI_CD_README.md @@ -0,0 +1,276 @@ +# 🚀 CI/CD Configuration для NeoMovies Mobile + +## 📋 Обзор + +Автоматическая сборка APK и TorrentEngine модуля с оптимизацией использования RAM. + +--- + +## 🏗️ Конфигурации + +### 1. **GitLab CI/CD** (`.gitlab-ci.yml`) + +Основная конфигурация для GitLab: + +#### **Stages:** +- **build** - Сборка APK и AAR +- **test** - Анализ кода и тесты +- **deploy** - Публикация релизов + +#### **Jobs:** + +| Job | Описание | Артефакты | Ветки | +|-----|----------|-----------|-------| +| `build:torrent-engine` | Сборка TorrentEngine AAR | `*.aar` | dev, feature/*, MR | +| `build:apk-debug` | Сборка Debug APK | `app-debug.apk` | dev, feature/*, MR | +| `build:apk-release` | Сборка Release APK | `app-arm64-v8a-release.apk` | только dev | +| `test:flutter-analyze` | Анализ Dart кода | - | dev, MR | +| `test:android-lint` | Android Lint | HTML отчеты | dev, MR | +| `deploy:release` | Публикация релиза | - | только tags (manual) | + +### 2. **GitHub Actions** (`.github/workflows/build.yml`) + +Альтернативная конфигурация для GitHub: + +#### **Workflows:** + +| Workflow | Триггер | Описание | +|----------|---------|----------| +| `build-torrent-engine` | push, PR | Сборка AAR модуля | +| `build-debug-apk` | push, PR | Debug APK для тестирования | +| `build-release-apk` | push to dev | Release APK (split-per-abi) | +| `code-quality` | push, PR | Flutter analyze + Android Lint | + +--- + +## ⚙️ Оптимизация RAM + +### **gradle.properties** + +```properties +# Уменьшено с 4GB до 2GB +org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G + +# Kotlin daemon с ограничением +kotlin.daemon.jvmargs=-Xmx1G -XX:MaxMetaspaceSize=512m + +# Включены оптимизации +org.gradle.parallel=true +org.gradle.caching=true +org.gradle.configureondemand=true +``` + +### **CI переменные** + +```bash +# В CI используется еще меньше RAM +GRADLE_OPTS="-Xmx1536m -XX:MaxMetaspaceSize=512m" +``` + +--- + +## 📦 Артефакты + +### **TorrentEngine AAR:** +- Путь: `android/torrentengine/build/outputs/aar/` +- Файл: `torrentengine-release.aar` +- Срок хранения: 7 дней +- Размер: ~5-10 MB + +### **Debug APK:** +- Путь: `build/app/outputs/flutter-apk/` +- Файл: `app-debug.apk` +- Срок хранения: 7 дней +- Размер: ~50-80 MB + +### **Release APK:** +- Путь: `build/app/outputs/flutter-apk/` +- Файл: `app-arm64-v8a-release.apk` +- Срок хранения: 30 дней +- Размер: ~30-50 MB (split-per-abi) + +--- + +## 🚦 Триггеры сборки + +### **GitLab:** + +**Автоматически запускается при:** +- Push в `dev` ветку +- Push в `feature/torrent-engine-integration` +- Создание Merge Request +- Push тега (для deploy) + +**Ручной запуск:** +- Web UI → Pipelines → Run Pipeline +- Выбрать ветку и нажать "Run pipeline" + +### **GitHub:** + +**Автоматически запускается при:** +- Push в `dev` или `feature/torrent-engine-integration` +- Pull Request в `dev` + +**Ручной запуск:** +- Actions → Build NeoMovies Mobile → Run workflow + +--- + +## 🔧 Настройка GitLab Runner + +Для локального тестирования CI/CD: + +```bash +# 1. Установка GitLab Runner +curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash +sudo apt-get install gitlab-runner + +# 2. Регистрация Runner +sudo gitlab-runner register \ + --url https://gitlab.com/ \ + --registration-token YOUR_TOKEN \ + --executor docker \ + --docker-image mingc/android-build-box:latest \ + --tag-list docker,android + +# 3. Запуск +sudo gitlab-runner start +``` + +--- + +## 📊 Время сборки (примерно) + +| Job | Время | RAM | CPU | +|-----|-------|-----|-----| +| TorrentEngine | ~5-10 мин | 1.5GB | 2 cores | +| Debug APK | ~15-20 мин | 2GB | 2 cores | +| Release APK | ~20-30 мин | 2GB | 2 cores | +| Flutter Analyze | ~2-3 мин | 512MB | 1 core | +| Android Lint | ~5-8 мин | 1GB | 2 cores | + +--- + +## 🐳 Docker образы + +### **mingc/android-build-box:latest** + +Включает: +- Android SDK (latest) +- Flutter SDK +- Java 17 +- Gradle +- Git, curl, wget + +Размер: ~8GB + +--- + +## 🔍 Кэширование + +Для ускорения сборок используется кэширование: + +```yaml +cache: + paths: + - .gradle/ # Gradle dependencies + - .pub-cache/ # Flutter packages + - android/.gradle/ # Android build cache + - build/ # Flutter build cache +``` + +**Эффект:** +- Первая сборка: ~25 минут +- Последующие: ~10-15 минут (с кэшем) + +--- + +## 📝 Логи и отладка + +### **Просмотр логов GitLab:** + +1. Перейти в **CI/CD → Pipelines** +2. Выбрать pipeline +3. Кликнуть на job для просмотра логов + +### **Отладка локально:** + +```bash +# Тестирование сборки TorrentEngine +cd android +./gradlew :torrentengine:assembleRelease \ + --no-daemon \ + --parallel \ + --stacktrace + +# Тестирование Flutter APK +flutter build apk --debug --verbose +``` + +--- + +## 🚨 Troubleshooting + +### **Gradle daemon crashed:** + +**Проблема:** `Gradle build daemon disappeared unexpectedly` + +**Решение:** +```bash +# Увеличить RAM в gradle.properties +org.gradle.jvmargs=-Xmx3G + +# Или отключить daemon +./gradlew --no-daemon +``` + +### **Out of memory:** + +**Проблема:** `OutOfMemoryError: Java heap space` + +**Решение:** +```bash +# Увеличить heap в CI +GRADLE_OPTS="-Xmx2048m -XX:MaxMetaspaceSize=768m" +``` + +### **LibTorrent4j native libraries not found:** + +**Проблема:** Нативные библиотеки не найдены + +**Решение:** +- Убедиться что все архитектуры включены в `build.gradle.kts` +- Проверить `splits.abi` конфигурацию + +--- + +## 📚 Дополнительные ресурсы + +- [GitLab CI/CD Docs](https://docs.gitlab.com/ee/ci/) +- [GitHub Actions Docs](https://docs.github.com/actions) +- [Flutter CI/CD Guide](https://docs.flutter.dev/deployment/cd) +- [Gradle Performance](https://docs.gradle.org/current/userguide/performance.html) + +--- + +## 🎯 Следующие шаги + +1. **Настроить GitLab Runner** (если еще не настроен) +2. **Запушить изменения** в dev ветку +3. **Проверить Pipeline** в GitLab CI/CD +4. **Скачать артефакты** после успешной сборки +5. **Протестировать APK** на реальном устройстве + +--- + +## 📞 Поддержка + +При проблемах с CI/CD: +1. Проверьте логи pipeline +2. Убедитесь что Runner активен +3. Проверьте доступность Docker образа +4. Создайте issue с логами ошибки + +--- + +**Создано с ❤️ для NeoMovies Mobile** diff --git a/android/gradle.properties b/android/gradle.properties index 6d65f28..3c25290 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,3 +1,20 @@ -org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError +# Gradle JVM settings - optimized for limited RAM +org.gradle.jvmargs=-Xmx2G -XX:MaxMetaspaceSize=1G -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +org.gradle.daemon=true +org.gradle.parallel=true +org.gradle.caching=true +org.gradle.configureondemand=true + +# Android settings android.useAndroidX=true android.enableJetifier=true +android.enableR8.fullMode=false + +# Kotlin settings +kotlin.daemon.jvmargs=-Xmx1G -XX:MaxMetaspaceSize=512m +kotlin.incremental=true +kotlin.incremental.usePreciseJavaTracking=true + +# Build optimization +android.enableBuildCache=true +org.gradle.vfs.watch=false