Initial commit: local_machine docs and scripts

This commit is contained in:
ahauimix
2026-03-14 20:03:57 +03:00
commit a39ef89125
85 changed files with 14500 additions and 0 deletions

View File

@@ -0,0 +1,679 @@
# 🏗️ Сборка AAB/APK из России — Полное руководство
> **Дата создания:** 2026-02-28
> **Проблема:** Java TLS заблокирован российским DPI → Gradle не может скачать зависимости
> **Решение:** Maven proxy на прод-сервере + SSH-туннель + обход SDK auto-download
> **Время сборки:** ~1.5 мин (AAB), ~46 сек (APK после AAB)
>
> **📖 См. также:** [SETUP_AND_BUILD_GUIDE.md](./SETUP_AND_BUILD_GUIDE.md) — общее руководство по установке и сборке (для работы не из России)
---
## 📋 Содержание
1. [Суть проблемы](#-суть-проблемы)
2. [Предварительные требования](#-предварительные-требования)
3. [Шаг 1: Maven proxy на прод-сервере](#-шаг-1-maven-proxy-на-прод-сервере)
4. [Шаг 2: SSH-туннель](#-шаг-2-ssh-туннель)
5. [Шаг 3: Сборка AAB](#-шаг-3-сборка-aab)
6. [Шаг 4: Сборка APK для эмулятора](#-шаг-4-сборка-apk-для-эмулятора)
7. [Шаг 5: Установка в эмулятор](#-шаг-5-установка-в-эмулятор)
8. [Быстрый скрипт «всё одной командой»](#-быстрый-скрипт-всё-одной-командой)
9. [DOs & DON'Ts](#-dos--donts)
10. [Конфигурация Gradle (что изменено и почему)](#-конфигурация-gradle-что-изменено-и-почему)
11. [Troubleshooting](#-troubleshooting)
12. [Версионирование](#-версионирование)
---
## 🔍 Суть проблемы
### Почему Gradle не работает из России напрямую
```
Gradle → Java TLS → dl.google.com / repo1.maven.org
DPI (Deep Packet Inspection) блокирует TLS handshake
Java получает: "Remote host terminated the handshake"
```
**Ключевой факт:** `curl` работает нормально (macOS LibreSSL), а Java — нет (JSSE TLS implementation). DPI по-разному обрабатывает TLS Client Hello от разных реализаций.
### Решение: Maven proxy
```
Gradle → HTTP (127.0.0.1:8765) → SSH-туннель → Прод-сервер (python proxy)
HTTPS → dl.google.com
HTTPS → repo1.maven.org
HTTPS → plugins.gradle.org
```
Java работает по **HTTP** (без TLS) до localhost. Прод-сервер в Digital Ocean скачивает по **HTTPS** без DPI.
---
## ✅ Предварительные требования
> **📖 Перед началом:** Убедитесь, что выполнены базовые требования из [SETUP_AND_BUILD_GUIDE.md](./SETUP_AND_BUILD_GUIDE.md):
> - Java OpenJDK 21+ установлен
> - Android SDK установлен (через Android Studio GUI)
> - Build Tools установлены
> - Эмулятор настроен (см. [EMULATOR_STARTUP_GUIDE.md](./EMULATOR_STARTUP_GUIDE.md))
### Локальная машина (macOS)
| Компонент | Версия | Путь |
|-----------|--------|------|
| Java (OpenJDK) | 21.0.9 | `/opt/homebrew/opt/openjdk@21` |
| Android SDK | API 34-36 | `$HOME/Library/Android/sdk` |
| Build Tools | 35.0.1 | `$HOME/Library/Android/sdk/build-tools/35.0.1` |
| Gradle Wrapper | 8.11.1 | `frontend/android/gradle/wrapper/` |
| AGP | 8.7.2 | `frontend/android/build.gradle` |
| Capacitor | 7.4.x | `frontend/package.json` |
### Прод-сервер
| Компонент | Значение |
|-----------|----------|
| SSH хост | `hunab-prod` (209.38.32.21) |
| Python | 3.12+ (предустановлен) |
| Порт proxy | 8765 (localhost) |
### Проверка готовности
```bash
# Java
/opt/homebrew/opt/openjdk@21/bin/java -version
# → openjdk version "21.0.9"
# Android SDK
ls $HOME/Library/Android/sdk/platforms/
# → android-34 android-35 android-36
# Build Tools
ls $HOME/Library/Android/sdk/build-tools/
# → 35.0.1 36.1.0 (34.0.0 и 35.0.0 УДАЛЕНЫ — были пустые!)
# SSH к проду
ssh hunab-prod "echo OK"
# → OK
```
---
## 🔧 Шаг 1: Maven proxy на прод-сервере
### 1.1 Скопировать скрипт прокси на прод
Создать файл `/tmp/maven-proxy.py` локально:
```bash
cat > /tmp/maven-proxy.py << 'PYEOF'
#!/usr/bin/env python3
"""Многопоточный Maven reverse proxy для Gradle.
Обходит Java TLS/DPI блокировку при сборке Android из РФ.
Поддерживает GET и HEAD запросы (Gradle использует оба).
"""
import http.server, socketserver, urllib.request, ssl, sys
REPOS = {
'/google/': 'https://dl.google.com/dl/android/maven2/',
'/central/': 'https://repo1.maven.org/maven2/',
'/gradle/': 'https://plugins.gradle.org/m2/',
}
class H(http.server.BaseHTTPRequestHandler):
def _p(self, m='GET'):
for pfx, base in REPOS.items():
if self.path.startswith(pfx):
url = base + self.path[len(pfx):]
try:
r = urllib.request.urlopen(
urllib.request.Request(url, headers={'User-Agent':'Gradle'}, method=m),
timeout=300,
context=ssl.create_default_context()
)
d = r.read() if m=='GET' else b''
self.send_response(200)
self.send_header('Content-Type', r.headers.get('Content-Type','application/octet-stream'))
self.send_header('Content-Length', r.headers.get('Content-Length',str(len(d))))
self.end_headers()
if m=='GET': self.wfile.write(d)
except urllib.error.HTTPError as e:
self.send_response(e.code); self.end_headers()
except Exception as e:
sys.stderr.write(f"ERR {m} {url}: {e}\n"); sys.stderr.flush()
self.send_response(502); self.end_headers()
return
self.send_response(404); self.end_headers()
def do_GET(self): self._p('GET')
def do_HEAD(self): self._p('HEAD')
def log_message(self, fmt, *a):
sys.stderr.write(f"{a[0]}\n"); sys.stderr.flush()
class S(socketserver.ThreadingMixIn, http.server.HTTPServer):
daemon_threads = True; allow_reuse_address = True
if __name__ == '__main__':
print("Maven proxy v2 on :8765 (threaded+logging)")
sys.stdout.flush()
S(('127.0.0.1',8765),H).serve_forever()
PYEOF
```
Скопировать на прод:
```bash
scp /tmp/maven-proxy.py hunab-prod:/tmp/maven-proxy.py
```
### 1.2 Запустить прокси на проде
```bash
# Убить предыдущий экземпляр (НЕЛЬЗЯ использовать pkill -f maven-proxy — убьёт SSH сессию!)
ssh hunab-prod "ps aux | grep maven-proxy | grep python | grep -v grep | awk '{print \$2}' | xargs -r kill"
sleep 1
# Запустить
ssh hunab-prod "nohup python3 /tmp/maven-proxy.py > /tmp/maven-proxy.log 2>&1 & echo PID=\$!"
```
### 1.3 Проверить прокси на проде
```bash
ssh hunab-prod "curl -s -I http://127.0.0.1:8765/google/com/android/tools/build/gradle/8.7.2/gradle-8.7.2.pom | head -2"
# Ожидаемый ответ:
# HTTP/1.0 200 OK
# Server: BaseHTTP/0.6 Python/3.12.7
```
---
## 🔧 Шаг 2: SSH-туннель
### 2.1 Создать туннель
```bash
# Убить старые туннели
pkill -f "ssh.*-L.*8765" 2>/dev/null
# Новый туннель (фоновый режим)
ssh -f -N -L 8765:127.0.0.1:8765 hunab-prod
```
### 2.2 Проверить туннель локально
```bash
curl -s -I http://127.0.0.1:8765/google/com/android/tools/build/gradle/8.7.2/gradle-8.7.2.pom | head -2
# Ожидаемый ответ:
# HTTP/1.0 200 OK
# Server: BaseHTTP/0.6 Python/3.12.7
```
**⚠️ Если ответ пустой или "Connection refused"** — прокси на проде не запущен или туннель не работает. Повторите шаги 1.2 и 2.1.
---
## 🔧 Шаг 3: Сборка AAB
### 3.1 Установка переменных окружения
```bash
export JAVA_HOME=/opt/homebrew/opt/openjdk@21
export PATH="$JAVA_HOME/bin:$PATH"
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/platform-tools
```
### 3.2 Сборка фронтенда (если не собран)
```bash
cd /Users/eternal/code/hunabapp-dev/frontend
pnpm build
```
### 3.3 Синхронизация Capacitor (если не сделано)
```bash
cd /Users/eternal/code/hunabapp-dev/frontend
npx cap sync android
```
### 3.4 Сборка AAB
```bash
cd /Users/eternal/code/hunabapp-dev/frontend/android
./gradlew clean bundleRelease --no-daemon --console=plain
```
**Ожидаемое время:** ~1 мин 20 сек
### 3.5 Результат
```bash
ls -lh ./app/build/outputs/bundle/release/app-release.aab
# → 37M app-release.aab
```
### 3.6 Копирование в temp/
```bash
VERSION_NAME=$(grep 'versionName' ./app/build.gradle | grep -oE '"[^"]*"' | tr -d '"')
VERSION_CODE=$(grep 'versionCode' ./app/build.gradle | grep -oE '[0-9]+')
mkdir -p /Users/eternal/code/hunabapp-dev/temp/android
cp ./app/build/outputs/bundle/release/app-release.aab \
/Users/eternal/code/hunabapp-dev/temp/android/hunab-app-v${VERSION_NAME}-v${VERSION_CODE}-release.aab
echo "📦 AAB: temp/android/hunab-app-v${VERSION_NAME}-v${VERSION_CODE}-release.aab"
```
---
## 🔧 Шаг 4: Сборка APK для эмулятора
> **AAB нельзя установить в эмулятор напрямую** — нужен APK.
```bash
cd /Users/eternal/code/hunabapp-dev/frontend/android
./gradlew assembleRelease --no-daemon --console=plain
```
**Ожидаемое время:** ~46 сек (после AAB сборки — кэш уже разогрет)
Результат:
```bash
cp ./app/build/outputs/apk/release/app-release.apk \
/Users/eternal/code/hunabapp-dev/temp/android/hunab-app-v${VERSION_NAME}-release.apk
```
---
## 🔧 Шаг 5: Установка в эмулятор
### 5.1 Запуск эмулятора
```bash
# Список доступных AVD
$ANDROID_HOME/emulator/emulator -list-avds
# → Pixel_5_API_35
# Запуск (в фоне)
$ANDROID_HOME/emulator/emulator -avd Pixel_5_API_35 -no-snapshot-load -no-snapshot-save &
# Ожидание загрузки (30-60 сек)
adb wait-for-device
adb shell getprop sys.boot_completed
# → 1 (когда загружено)
```
### 5.2 Установка APK
```bash
adb install -r /Users/eternal/code/hunabapp-dev/temp/android/hunab-app-v${VERSION_NAME}-release.apk
```
### 5.3 Запуск приложения
```bash
adb shell am start -n com.hunab.app/.MainActivity
```
---
## 🚀 Быстрый скрипт «всё одной командой»
> **Предполагает:** прокси уже запущен и SSH-туннель активен (шаги 1-2).
```bash
#!/bin/bash
set -e
# === Настройка ===
export JAVA_HOME=/opt/homebrew/opt/openjdk@21
export PATH="$JAVA_HOME/bin:$PATH"
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator
PROJECT_ROOT="/Users/eternal/code/hunabapp-dev"
# === Проверка прокси ===
echo "🔍 Проверяю Maven proxy..."
if ! curl -s -I http://127.0.0.1:8765/google/com/android/tools/build/gradle/8.7.2/gradle-8.7.2.pom | grep -q "200 OK"; then
echo "❌ Maven proxy не работает! Запустите шаги 1-2 из BUILD_AAB_FROM_RUSSIA_GUIDE.md"
exit 1
fi
echo "✅ Proxy OK"
# === Сборка фронтенда ===
echo "🔨 Сборка фронтенда..."
cd "$PROJECT_ROOT/frontend"
pnpm build
# === Capacitor sync ===
echo "🔄 Capacitor sync..."
npx cap sync android
# === Версия ===
cd android
VERSION_NAME=$(grep 'versionName' ./app/build.gradle | grep -oE '"[^"]*"' | tr -d '"')
VERSION_CODE=$(grep 'versionCode' ./app/build.gradle | grep -oE '[0-9]+')
echo "📊 Version: $VERSION_NAME (code: $VERSION_CODE)"
# === AAB ===
echo "📦 Сборка AAB..."
./gradlew clean bundleRelease --no-daemon --console=plain
mkdir -p "$PROJECT_ROOT/temp/android"
cp ./app/build/outputs/bundle/release/app-release.aab \
"$PROJECT_ROOT/temp/android/hunab-app-v${VERSION_NAME}-v${VERSION_CODE}-release.aab"
echo "✅ AAB: temp/android/hunab-app-v${VERSION_NAME}-v${VERSION_CODE}-release.aab"
# === APK (для эмулятора) ===
echo "📱 Сборка APK..."
./gradlew assembleRelease --no-daemon --console=plain
cp ./app/build/outputs/apk/release/app-release.apk \
"$PROJECT_ROOT/temp/android/hunab-app-v${VERSION_NAME}-release.apk"
# === Эмулятор ===
echo "📲 Установка в эмулятор..."
if adb devices 2>/dev/null | grep -q "device$"; then
adb install -r "$PROJECT_ROOT/temp/android/hunab-app-v${VERSION_NAME}-release.apk"
adb shell am start -n com.hunab.app/.MainActivity
echo "🎮 Приложение запущено!"
else
echo "⚠️ Эмулятор не запущен. Запустите вручную и повторите установку."
fi
ls -lh "$PROJECT_ROOT/temp/android/"
echo ""
echo "✅✅✅ ГОТОВО!"
```
---
## 🚫 DOs & DON'Ts
### ✅ DO (ДЕЛАЙ)
| # | Правило | Почему |
|---|---------|--------|
| 1 | **Используй Maven proxy через SSH-туннель** | Java TLS заблокирован DPI в РФ |
| 2 | **ТОЛЬКО прокси repos в build.gradle** (без `google()`, `mavenCentral()`) | Прямые HTTPS repos зависают навсегда |
| 3 | **`allowInsecureProtocol = true`** для proxy repos | Прокси работает по HTTP, Gradle 8+ блокирует HTTP по умолчанию |
| 4 | **`android.builder.sdkDownload=false`** в gradle.properties | SDK auto-download зависает на TLS |
| 5 | **`compileSdkVersion = 36`** в variables.gradle | android-36 — base SDK, корректно установлен |
| 6 | **`buildToolsVersion "35.0.1"`** явно в app/build.gradle | 34.0.0 и 35.0.0 не установлены (пустые папки были удалены) |
| 7 | **Global buildToolsVersion override** через `subprojects{}` в root build.gradle | Capacitor модули тоже требуют build tools |
| 8 | **`android.suppressUnsupportedCompileSdk=36`** в gradle.properties | Убирает warning от AGP 8.7.2 |
| 9 | **`-Djdk.tls.client.protocols=TLSv1.2`** в org.gradle.jvmargs | Частично помогает с DPI для прямых Java TLS |
| 10 | **`IsBaseSdk=true`** в source.properties platforms | Gradle не находит extension SDK без манифеста |
| 11 | **`ThreadingMixIn`** в Python proxy | Gradle делает десятки параллельных запросов |
| 12 | **HEAD + GET** в proxy | Gradle использует HEAD для проверки существования артефактов |
| 13 | **Фоновая сборка** при запуске из Cursor | `./gradlew` через Cursor tool таймаутится через ~2 мин |
| 14 | **Убивай pkill через `ps aux | grep | awk | xargs kill`** | Безопасный способ |
### ❌ DON'T (НЕ ДЕЛАЙ)
| # | Правило | Почему |
|---|---------|--------|
| 1 | **НЕ оставляй `google()` / `mavenCentral()` в repositories** | Gradle попробует их → зависнет на TLS handshake на НЕОПРЕДЕЛЁННОЕ время |
| 2 | **НЕ используй `pkill -f maven-proxy`** через SSH | Паттерн совпадает с самой SSH командой → убивает SSH сессию (exit 255) |
| 3 | **НЕ используй однопоточный Python HTTP server** | Gradle делает 10-50 параллельных запросов → очередь → таймаут |
| 4 | **НЕ используй SOCKS proxy для Gradle** (`socksProxyHost`) | Java TLS через SOCKS тоже блокируется DPI |
| 5 | **НЕ пытайся скачать Gradle cache на проде и скопировать** | Кэш привязан к хэшам и абсолютным путям — не переносим |
| 6 | **НЕ устанавливай Android SDK через sdkmanager из РФ** | Тот же TLS блок. Устанавливай через Android Studio GUI (у студии свои настройки) |
| 7 | **НЕ удаляй `android.builder.sdkDownload=false`** | Gradle будет пытаться скачать SDK манифесты → зависнет |
| 8 | **НЕ используй `compileSdkVersion = 35`** | Установленный android-35 — extension SDK, Gradle без манифеста не может его найти |
| 9 | **НЕ забывай `buildToolsVersion` в subprojects** | Capacitor-android и другие модули тоже требуют build tools |
| 10 | **НЕ создавай APK для Google Play** | Google Play требует только AAB формат |
| 11 | **НЕ оставляй пустые build-tools директории** | Gradle пытается их использовать → "Build Tools not found" |
| 12 | **НЕ запускай Gradle через tool call Cursor напрямую** | Таймаут ~2 мин; запускай в фоне через `nohup ... &` |
---
## ⚙️ Конфигурация Gradle (что изменено и почему)
### `frontend/android/build.gradle` (корневой)
```groovy
buildscript {
repositories {
// ТОЛЬКО прокси — прямые repos заблокированы DPI
maven { url 'http://127.0.0.1:8765/google/'; allowInsecureProtocol = true }
maven { url 'http://127.0.0.1:8765/central/'; allowInsecureProtocol = true }
maven { url 'http://127.0.0.1:8765/gradle/'; allowInsecureProtocol = true }
}
dependencies {
classpath 'com.android.tools.build:gradle:8.7.2'
classpath 'com.google.gms:google-services:4.4.2'
}
}
allprojects {
repositories {
// ТОЛЬКО прокси
maven { url 'http://127.0.0.1:8765/google/'; allowInsecureProtocol = true }
maven { url 'http://127.0.0.1:8765/central/'; allowInsecureProtocol = true }
maven { url 'http://127.0.0.1:8765/gradle/'; allowInsecureProtocol = true }
}
}
// Глобальный override buildToolsVersion для ВСЕХ модулей
subprojects {
afterEvaluate { project ->
if (project.hasProperty('android')) {
project.android.buildToolsVersion = "35.0.1"
}
}
}
```
**Почему:**
- `allowInsecureProtocol = true` — Gradle 8+ блокирует HTTP repos по умолчанию
- Три прокси: Google Maven, Maven Central, Gradle Plugin Portal
- `subprojects { afterEvaluate }` — Capacitor модули не указывают buildToolsVersion явно, AGP 8.7.2 по умолчанию ищет 34.0.0 (не установлен)
### `frontend/android/gradle.properties`
```properties
org.gradle.jvmargs=-Xmx1536m -Djdk.tls.client.protocols=TLSv1.2
android.useAndroidX=true
android.builder.sdkDownload=false
android.suppressUnsupportedCompileSdk=36
```
**Почему:**
- `-Djdk.tls.client.protocols=TLSv1.2` — принудительный TLS 1.2 (частично обходит DPI)
- `sdkDownload=false` — блокирует авто-загрузку SDK (зависает на TLS)
- `suppressUnsupportedCompileSdk=36` — AGP 8.7.2 не знает о SDK 36, подавляем warning
### `frontend/android/variables.gradle`
```groovy
ext {
compileSdkVersion = 36 // Было 35! android-35 — extension SDK, не находится без манифеста
targetSdkVersion = 35 // Оставляем 35 для совместимости с Google Play
// ...
}
```
**Почему:**
- `android-35` установлен как extension SDK (path: `platforms;android-35-ext15`) — Gradle без сетевого манифеста не может его распознать как `android-35`
- `android-36` установлен как base SDK (path: `platforms;android-36`, `IsBaseSdk=true`) — работает
- `targetSdkVersion` остаётся 35 — это то, что Google Play учитывает
### `frontend/android/app/build.gradle`
```groovy
android {
compileSdk rootProject.ext.compileSdkVersion
buildToolsVersion "35.0.1" // Добавлено явно
// ...
}
```
### SDK Platform Patches
**`$HOME/Library/Android/sdk/platforms/android-35/source.properties`:**
```properties
AndroidVersion.IsBaseSdk=true # Было false — Gradle не находил SDK без манифеста
```
**`$HOME/Library/Android/sdk/platforms/android-35/package.xml`:**
```xml
<localPackage path="platforms;android-35" ...> <!-- Было: platforms;android-35-ext15 -->
```
> ⚠️ Аналогичные изменения для android-34
---
## 🔧 Troubleshooting
### Проблема: «Still waiting for package manifests to be fetched remotely»
**Причина:** `android.builder.sdkDownload=true` (или не задан) → Gradle пытается скачать манифесты по HTTPS → DPI блокирует.
**Решение:**
```properties
# gradle.properties
android.builder.sdkDownload=false
```
### Проблема: «Failed to find target with hash string 'android-35'»
**Причина:** Установленный SDK — extension SDK (`IsBaseSdk=false`, path `android-35-ext15`), а Gradle ищет base SDK `android-35`.
**Решение варианты:**
1. Использовать `compileSdkVersion = 36` (android-36 = base SDK) ← **текущее решение**
2. Или патчить `source.properties`: `IsBaseSdk=true` + `package.xml`: `path="platforms;android-35"`
### Проблема: «Failed to find Build Tools revision 34.0.0»
**Причина:** AGP 8.7.2 по умолчанию требует build-tools 34.0.0. При `sdkDownload=false` не может скачать.
**Решение:** Явно указать установленную версию в `app/build.gradle` и глобально через `subprojects` в root `build.gradle`:
```groovy
buildToolsVersion "35.0.1"
```
### Проблема: Gradle зависает, прокси лог пустой (0 строк)
**Причина:** Gradle обращается к `google()` / `mavenCentral()` напрямую, минуя прокси.
**Решение:** Убрать `google()` и `mavenCentral()` из repositories. Оставить ТОЛЬКО proxy URLs.
### Проблема: SSH exit code 255 при pkill
**Причина:** `pkill -f maven-proxy` совпадает с самой SSH командой и убивает сессию.
**Решение:**
```bash
ssh hunab-prod "ps aux | grep maven-proxy | grep python | grep -v grep | awk '{print \$2}' | xargs -r kill"
```
### Проблема: Cursor tool timeout при сборке
**Причина:** Gradle билд занимает ~1.5 мин, Cursor tool таймаутится через ~2 мин.
**Решение:** Запускать в фоне:
```bash
nohup bash -c '
cd /path/to/frontend/android
./gradlew bundleRelease --no-daemon --console=plain 2>&1 | tee /tmp/aab-build.log
' &>/dev/null &
# Мониторинг
tail -f /tmp/aab-build.log
```
### Проблема: Однопоточный proxy таймаутится
**Причина:** Python `http.server.HTTPServer` обрабатывает 1 запрос за раз. Gradle делает 10-50 параллельных запросов.
**Решение:** `ThreadingMixIn`:
```python
class S(socketserver.ThreadingMixIn, http.server.HTTPServer):
daemon_threads = True
allow_reuse_address = True
```
### Проблема: Proxy возвращает 404 на HEAD запросы
**Причина:** `BaseHTTPRequestHandler` по умолчанию не имеет `do_HEAD`.
**Решение:** Добавить `do_HEAD`:
```python
def do_HEAD(self): self._p('HEAD')
```
---
## 📊 Версионирование
### Текущая версия (2026-02-28)
| Параметр | Значение |
|----------|----------|
| versionName | 1.3.8 |
| versionCode | 10308 |
| compileSdkVersion | 36 |
| targetSdkVersion | 35 |
| minSdkVersion | 23 |
| buildToolsVersion | 35.0.1 |
| AGP | 8.7.2 |
| Gradle | 8.11.1 |
| Java | OpenJDK 21.0.9 |
| Capacitor | 7.4.x |
### Для Google Play
- **AAB файл:** `temp/android/hunab-app-v1.3.8-v10308-release.aab`
- **Размер:** ~37 MB
- **Подписан:** `hunab-app.keystore` (release signing config)
- **Формат:** AAB (NEVER APK for Google Play!)
- **versionCode** должен быть **больше** предыдущего релиза!
### Перед новым релизом
1. Обновить `versionCode` и `versionName` в `frontend/android/app/build.gradle`
2. Собрать фронтенд (`pnpm build`)
3. `npx cap sync android`
4. Следовать шагам 1-4 этого руководства
---
## 📁 Связанные файлы
| Файл | Назначение |
|------|------------|
| `frontend/android/build.gradle` | Корневой Gradle — repos, plugins, subprojects override |
| `frontend/android/app/build.gradle` | App модуль — version, signing, buildTools |
| `frontend/android/gradle.properties` | JVM args, SDK download, TLS, suppressWarnings |
| `frontend/android/variables.gradle` | compileSdk, targetSdk, dependency versions |
| `docs/android/guides/SETUP_AND_BUILD_GUIDE.md` | **Общее руководство по установке и сборке** (для работы не из России) |
| `docs/android/guides/EMULATOR_STARTUP_GUIDE.md` | **Полное руководство по запуску эмулятора** |
| `docs/android/TROUBLESHOOTING.md` | Общий troubleshooting (включая другие проблемы) |
| `docs/android/MOBILE_BUILD_REGULATIONS.md` | Регламент сборки мобильного приложения |
| `scripts/android/quick-build-and-launch.sh` | Старый скрипт быстрой сборки (требует адаптации под proxy) |
---
> **Последнее обновление:** 2026-02-28
> **Автор:** Aura (Cursor AI Agent)
> **Проверено:** Успешная сборка AAB v1.3.8 (BUILD SUCCESSFUL in 1m 21s, 112 tasks)