diff --git a/bdt.sh b/bdt.sh index 29ca4b3..cab9977 100755 --- a/bdt.sh +++ b/bdt.sh @@ -20,7 +20,7 @@ set -euo pipefail # CONFIGURACION #=============================================================================== -SCRIPT_VERSION="2.3.0" +SCRIPT_VERSION="2.4.0" SCRIPT_NAME="$(basename "$0")" # Directorios - resolver symlinks para encontrar la ruta real @@ -382,13 +382,16 @@ cmd_build() { } #=============================================================================== -# COMANDO: rebuild - Interactivo: elegir docker → build --no-cache → up -# La idea del shell: seleccionar CUÁL docker reconstruir SIN CACHÉ y levantarlo. +# COMANDO: rebuild - Interactivo: elegir docker → (origen del binario) → limpiar → build --no-cache → up +# La idea del shell: reconstruir un servicio sin caché y levantarlo, eligiendo el ORIGEN: +# Opción 1) Código nuevo por git pull + compilar acá (gradle bootJar para Java). +# Opción 2) JAR externo: compilado en tu PC y subido a la carpeta temporal (JAR_INBOX, def /tmp); +# el comando lo mueve a build/libs y reconstruye. #=============================================================================== cmd_rebuild() { banner - step "REBUILD" "Reconstruir un servicio SIN CACHÉ y levantarlo (--force-recreate)" + step "REBUILD / DEPLOY" "Reconstruir un servicio (sin caché) y levantarlo (--force-recreate)" echo "" # 1. Elegir servicio (lista numerada con estado del contenedor) @@ -404,7 +407,7 @@ cmd_rebuild() { done echo -e " ${WHITE}a${NC}) TODOS los servicios de aplicación" echo "" - echo -ne " ${O3}¿Qué docker reconstruir sin caché? (1-${#options[@]}, 'a'=todos, nombre, Enter=cancelar):${NC} " + echo -ne " ${O3}¿Qué docker reconstruir? (1-${#options[@]}, 'a'=todos, nombre, Enter=cancelar):${NC} " read -r choice [[ -z "$choice" ]] && { warn "Cancelado"; return 0; } @@ -418,41 +421,81 @@ cmd_rebuild() { fi [[ ${#targets[@]} -eq 0 ]] && { err "Opción inválida: ${choice}"; return 1; } - # 2. Servicios Java: el Dockerfile copia build/libs/*.jar — ofrecer recompilar el JAR - local recompile="" - for s in "${targets[@]}"; do - case "$s" in - gateway|service-bus) - echo -ne " ${O3}¿Recompilar el JAR (gradle bootJar) antes del build? (s/N):${NC} " - read -r recompile - break - ;; - esac - done + # 2. Origen del binario a desplegar — LAS DOS OPCIONES + echo "" + echo -e " ${O2}${BOLD}¿De dónde sale el binario a desplegar?${NC}" + echo -e " ${WHITE}1${NC}) ${WHITE}Código nuevo por git${NC} — git pull + compilar acá (gradle bootJar para Java)" + echo -e " ${WHITE}2${NC}) ${WHITE}JAR externo${NC} — compilado en tu PC y subido a la carpeta temporal" + echo -ne " ${O3}Origen (1/2) [1]:${NC} " + read -r src + src="${src:-1}" - # 3. Por cada target: (gradle) → docker build --no-cache → up --force-recreate → health + local inbox="${JAR_INBOX:-/tmp}" + [[ "$src" == "2" ]] && echo -e " ${GRAY}Carpeta temporal de JARs: ${inbox} (cambiala con JAR_INBOX en ~/.bdt/config)${NC}" + + # 3. ¿Limpiar Docker previo (contenedor + imagen) antes de compilar el docker? + echo -ne " ${O3}¿Limpiar Docker previo (rm contenedor + rmi imagen) antes del build? (S/n):${NC} " + read -r do_clean + do_clean="${do_clean:-s}" + + # 4. Por cada target: origen → limpiar → docker build --no-cache → up --force-recreate → health for s in "${targets[@]}"; do echo "" - step "REBUILD ${s}" "$(svc_desc "$s")" + step "DEPLOY ${s}" "$(svc_desc "$s")" + local dir; dir="$(repo_dir "$s")" - if [[ "$recompile" =~ ^[sSyY] ]]; then + if [[ "$src" == "2" ]]; then + # OPCIÓN 2 — mover el JAR externo desde la carpeta temporal → build/libs + case "$s" in + gateway|service-bus) ;; + *) warn "${s} no es Java; la opción 'JAR externo' aplica a gateway/service-bus. Salto."; continue ;; + esac + echo -ne " ${O3}Ruta del JAR para ${s} (Enter = más reciente en ${inbox}):${NC} " + read -r jar_path + [[ -z "$jar_path" ]] && jar_path="$(ls -t "${inbox}"/*.jar 2>/dev/null | grep -v -- '-plain.jar' | head -1)" + [[ -z "$jar_path" || ! -f "$jar_path" ]] && { err "No encontré JAR (${jar_path:-vacío}) en ${inbox}"; continue; } + info "Moviendo $(basename "$jar_path") → ${dir}/build/libs/" + mkdir -p "${dir}/build/libs" + rm -f "${dir}/build/libs"/*.jar + cp "$jar_path" "${dir}/build/libs/$(basename "$jar_path")" || { err "No se pudo copiar el JAR"; continue; } + ok "JAR colocado: ${dir}/build/libs/$(basename "$jar_path")" + else + # OPCIÓN 1 — git pull + compilar acá + if [[ -d "${dir}/.git" ]]; then + info "git pull en ${dir}..." + ( cd "$dir" && git pull --ff-only 2>&1 | tail -3 | while read -r l; do echo -e " ${GRAY}${l}${NC}"; done ) \ + || warn "git pull no fue limpio — continúo con el código presente" + else + warn "${dir} no es repo git — uso el código presente" + fi case "$s" in gateway|service-bus) - local jdir; jdir="$(repo_dir "$s")" - info "Compilando ${s} (bootJar, sin tests)..." - ( cd "$jdir" && ./gradlew clean bootJar -x test > "${LOG_DIR}/${s}-rebuild-gradle.log" 2>&1 ) \ - && ok "JAR: $(ls "${jdir}"/build/libs/*.jar 2>/dev/null | head -1)" \ + info "Compilando ${s} (gradle bootJar, sin tests)..." + ( cd "$dir" && ./gradlew clean bootJar -x test > "${LOG_DIR}/${s}-rebuild-gradle.log" 2>&1 ) \ + && ok "JAR: $(ls "${dir}"/build/libs/*.jar 2>/dev/null | grep -v -- '-plain.jar' | head -1)" \ || { err "Gradle falló (ver ${LOG_DIR}/${s}-rebuild-gradle.log)"; continue; } ;; + *) info "${s}: compila dentro del Docker build (multi-stage), nada que compilar acá" ;; esac fi + # Limpiar Docker previo + if [[ "$do_clean" =~ ^[sSyY] ]]; then + info "Limpiando Docker previo de ${s} (contenedor + imagen)..." + docker rm -f "$(docker_name "$s")" >/dev/null 2>&1 || true + docker rmi -f "bdt-${s}:latest" >/dev/null 2>&1 || true + ok "Contenedor e imagen previos eliminados" + fi + + # Docker build sin caché _docker_build_local "$s" nocache || { err "Build de ${s} falló — sigo con el resto"; continue; } + # Up info "Recreando contenedor ${s}..." ( cd "$INFRA_DIR" && $COMPOSE_CMD --profile apps --profile tools up -d --force-recreate "$s" 2>&1 \ | while read -r l; do echo -e " ${GRAY}${l}${NC}"; done ) + # Health local url; url="$(svc_health_url "$s")" if [[ -n "$url" ]]; then info "Esperando salud de ${s} (hasta 120s)..." @@ -1397,7 +1440,7 @@ cmd_menu() { while true; do banner echo -e " ${O1}${BOLD}0) CONSTRUIR SERVICIO${NC} ${GRAY}— asistente: git banco → build → docker → up${NC}" - echo -e " ${O1}${BOLD}n) REBUILD SIN CACHÉ${NC} ${GRAY}— elegir docker → build --no-cache → up --force-recreate${NC}" + echo -e " ${O1}${BOLD}n) REBUILD / DEPLOY${NC} ${GRAY}— elegir docker → [1] git pull+compilar ó [2] jar externo → limpiar → build --no-cache → up${NC}" echo "" echo -e " ${O2}${BOLD}SERVICIOS${NC} ${O3}${BOLD}MONITOREO${NC} ${O1}${BOLD}VERIFICACION${NC}" echo -e " ${GRAY}$(printf '%.0s─' {1..60})${NC}" @@ -1900,7 +1943,8 @@ cmd_help() { echo -e " ${O2}${BOLD}COMPILACIÓN${NC}" echo -e " ${WHITE}install${NC} Instalar dependencias + compilar todo" echo -e " ${WHITE}build${NC} [servicio|all] [--no-cache] Construir imágenes Docker (opcional sin caché)" - echo -e " ${WHITE}rebuild${NC} Interactivo: elegir docker → build --no-cache → up --force-recreate" + echo -e " ${WHITE}rebuild${NC} Interactivo: elegir docker → origen [1] git pull+compilar / [2] jar externo en /tmp" + echo -e " → limpiar docker → build --no-cache → up --force-recreate → health" echo "" echo -e " ${O2}${BOLD}SERVICIOS${NC}" echo -e " ${WHITE}up${NC} [all|infra|apps|tools|nombre] Levantar servicios"