Files
fn_registry/bash/functions/pipelines/capacitor_build_apk.sh
T
egutierrez 01042bc23c feat: add bash infra functions — Gitea, Android SDK, Mantine, Capacitor
Nuevas funciones bash: gestión Gitea (create_repo, list_repos, add_collaborator,
push_directory), install_android_sdk, install_mantine, frontend_doctor.
Pipelines: capacitor_build_apk y gitea_init_app.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 23:47:10 +02:00

209 lines
7.3 KiB
Bash

#!/usr/bin/env bash
# capacitor_build_apk
# -------------------
# Pipeline que convierte una web app buildeada en un APK de Android usando Capacitor.
# Asume que el Android SDK está instalado (via install_android_sdk o manualmente).
#
# USO:
# ./capacitor_build_apk.sh <web_app_dir> [--app-id com.example.app] [--app-name "My App"]
#
# ARGUMENTOS:
# web_app_dir Directorio de la web app (debe contener package.json)
# --app-id ID de la app Android (default: com.fnregistry.app)
# --app-name Nombre visible de la app (default: name de package.json)
#
# REQUISITOS:
# - Node.js + pnpm instalados en PATH
# - Java 17+ instalado en PATH
# - Android SDK: ANDROID_HOME seteado o $HOME/android-sdk/env.sh disponible
set -euo pipefail
# ---------------------------------------------------------------------------
# Parseo de argumentos
# ---------------------------------------------------------------------------
WEB_APP_DIR=""
APP_ID="com.fnregistry.app"
APP_NAME=""
while [[ $# -gt 0 ]]; do
case "$1" in
--app-id)
APP_ID="$2"
shift 2
;;
--app-name)
APP_NAME="$2"
shift 2
;;
-*)
echo "[capacitor_build_apk] ERROR: argumento desconocido: $1" >&2
echo "USO: $0 <web_app_dir> [--app-id com.example.app] [--app-name \"My App\"]" >&2
exit 1
;;
*)
WEB_APP_DIR="$1"
shift
;;
esac
done
if [[ -z "$WEB_APP_DIR" ]]; then
echo "[capacitor_build_apk] ERROR: web_app_dir es obligatorio." >&2
echo "USO: $0 <web_app_dir> [--app-id com.example.app] [--app-name \"My App\"]" >&2
exit 1
fi
# ---------------------------------------------------------------------------
# 1. Validación
# ---------------------------------------------------------------------------
echo "[capacitor_build_apk] Validando entorno..."
# Verificar que web_app_dir existe y tiene package.json
if [[ ! -d "$WEB_APP_DIR" ]]; then
echo "[capacitor_build_apk] ERROR: directorio no existe: $WEB_APP_DIR" >&2
exit 1
fi
if [[ ! -f "$WEB_APP_DIR/package.json" ]]; then
echo "[capacitor_build_apk] ERROR: no se encontró package.json en $WEB_APP_DIR" >&2
exit 1
fi
# Resolver app name desde package.json si no se pasó
if [[ -z "$APP_NAME" ]]; then
APP_NAME=$(node -e "const p = require('$WEB_APP_DIR/package.json'); process.stdout.write(p.name || 'app');" 2>/dev/null || echo "app")
echo "[capacitor_build_apk] App name detectado desde package.json: $APP_NAME"
fi
# Verificar ANDROID_HOME o sourcea env.sh
if [[ -z "${ANDROID_HOME:-}" ]]; then
ANDROID_ENV="$HOME/android-sdk/env.sh"
if [[ -f "$ANDROID_ENV" ]]; then
echo "[capacitor_build_apk] ANDROID_HOME no seteado, sourceando $ANDROID_ENV ..."
# shellcheck source=/dev/null
source "$ANDROID_ENV"
else
echo "[capacitor_build_apk] ERROR: ANDROID_HOME no está seteado y no se encontró $ANDROID_ENV" >&2
echo " Instala el SDK con install_android_sdk o setea ANDROID_HOME manualmente." >&2
exit 1
fi
fi
echo "[capacitor_build_apk] ANDROID_HOME: $ANDROID_HOME"
# Verificar Java 17+
if ! command -v java &>/dev/null; then
echo "[capacitor_build_apk] ERROR: java no está en PATH." >&2
exit 1
fi
JAVA_VERSION=$(java -version 2>&1 | head -1 | grep -oP '(?<=version ")([0-9]+)' | head -1 || echo "0")
if [[ "$JAVA_VERSION" -lt 17 ]]; then
echo "[capacitor_build_apk] ERROR: se requiere Java 17+. Versión detectada: $JAVA_VERSION" >&2
exit 1
fi
echo "[capacitor_build_apk] Java $JAVA_VERSION detectado."
# ---------------------------------------------------------------------------
# 2. Build web (si no existe dist/)
# ---------------------------------------------------------------------------
if [[ ! -d "$WEB_APP_DIR/dist" ]]; then
echo "[capacitor_build_apk] No se encontró dist/, ejecutando pnpm build..."
(cd "$WEB_APP_DIR" && pnpm build)
echo "[capacitor_build_apk] Build web completado."
else
echo "[capacitor_build_apk] dist/ ya existe, omitiendo build web."
fi
# ---------------------------------------------------------------------------
# 3. Init Capacitor (si no existe capacitor.config.ts)
# ---------------------------------------------------------------------------
if [[ ! -f "$WEB_APP_DIR/capacitor.config.ts" ]]; then
echo "[capacitor_build_apk] Instalando dependencias de Capacitor..."
(cd "$WEB_APP_DIR" && npm install @capacitor/core @capacitor/cli @capacitor/android)
echo "[capacitor_build_apk] Generando capacitor.config.ts..."
cat > "$WEB_APP_DIR/capacitor.config.ts" <<CAPCONFIG
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: '${APP_ID}',
appName: '${APP_NAME}',
webDir: 'dist',
server: { androidScheme: 'https' }
};
export default config;
CAPCONFIG
echo "[capacitor_build_apk] capacitor.config.ts generado."
else
echo "[capacitor_build_apk] capacitor.config.ts ya existe, omitiendo init."
fi
# ---------------------------------------------------------------------------
# 4. Add Android (si no existe el directorio android/)
# ---------------------------------------------------------------------------
if [[ ! -d "$WEB_APP_DIR/android" ]]; then
echo "[capacitor_build_apk] Añadiendo plataforma Android..."
(cd "$WEB_APP_DIR" && npx cap add android)
echo "[capacitor_build_apk] Plataforma Android añadida."
else
echo "[capacitor_build_apk] Directorio android/ ya existe, omitiendo cap add."
fi
# ---------------------------------------------------------------------------
# 5. Sync
# ---------------------------------------------------------------------------
echo "[capacitor_build_apk] Sincronizando assets web con Android..."
(cd "$WEB_APP_DIR" && npx cap sync android)
echo "[capacitor_build_apk] Sync completado."
# ---------------------------------------------------------------------------
# 6. Build APK
# ---------------------------------------------------------------------------
echo "[capacitor_build_apk] Compilando APK con Gradle..."
if ! (cd "$WEB_APP_DIR/android" && ./gradlew assembleDebug); then
echo "[capacitor_build_apk] ERROR: Gradle falló. Revisa los logs anteriores." >&2
exit 1
fi
APK_SOURCE="$WEB_APP_DIR/android/app/build/outputs/apk/debug/app-debug.apk"
if [[ ! -f "$APK_SOURCE" ]]; then
echo "[capacitor_build_apk] ERROR: Gradle terminó sin error pero no se encontró el APK en $APK_SOURCE" >&2
exit 1
fi
# ---------------------------------------------------------------------------
# 7. Copia APK al directorio raíz
# ---------------------------------------------------------------------------
APK_DEST="$WEB_APP_DIR/${APP_NAME}.apk"
cp "$APK_SOURCE" "$APK_DEST"
# ---------------------------------------------------------------------------
# 8. Resultado
# ---------------------------------------------------------------------------
APK_SIZE_BYTES=$(stat -c%s "$APK_DEST" 2>/dev/null || stat -f%z "$APK_DEST" 2>/dev/null || echo "0")
APK_SIZE_MB=$(awk "BEGIN {printf \"%.1f\", $APK_SIZE_BYTES/1048576}")
echo ""
echo "---------------------------------------------------------------------"
echo "APK generado: $APK_DEST"
echo "Tamaño: ${APK_SIZE_MB} MB"
echo ""
echo "Para instalar en un dispositivo conectado por USB:"
echo " adb install '$APK_DEST'"
echo "---------------------------------------------------------------------"