From 7b9baa3488dcf8fa2fe2522b6a2d48cbdd3691d2 Mon Sep 17 00:00:00 2001 From: Luis Eduardo Perez Date: Wed, 29 Jul 2026 10:27:09 -0400 Subject: [PATCH] chore: sync bdt.sh v2.7.0 (monorepo @ e06c6bb) --- bdt.sh | 401 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 361 insertions(+), 40 deletions(-) diff --git a/bdt.sh b/bdt.sh index f2b19ca..a187043 100755 --- a/bdt.sh +++ b/bdt.sh @@ -20,7 +20,7 @@ set -euo pipefail # CONFIGURACION #=============================================================================== -SCRIPT_VERSION="2.5.0" +SCRIPT_VERSION="2.7.0" SCRIPT_NAME="$(basename "$0")" # Directorios - resolver symlinks para encontrar la ruta real @@ -37,6 +37,30 @@ _resolve_root() { } BDT_ROOT="${BDT_ROOT:-$(_resolve_root)}" +# Repo del shell (proyecto aparte: BDT/bdt-cli). En el server vive bajo la raíz de plataforma. +_resolve_bdt_cli_dir() { + if [[ -n "${BDT_CLI_DIR:-}" ]]; then + echo "$BDT_CLI_DIR"; return + fi + if [[ -d "${BDT_ROOT}/bdt-cli/.git" ]]; then + echo "${BDT_ROOT}/bdt-cli"; return + fi + if [[ -d "$(dirname "$BDT_ROOT")/bdt-cli/.git" ]]; then + echo "$(dirname "$BDT_ROOT")/bdt-cli"; return + fi + echo "${BDT_ROOT}/bdt-cli" +} +BDT_CLI_DIR="$(_resolve_bdt_cli_dir)" + +# Script a instalar como comando global: preferir el clon bdt-cli sobre la copia suelta en BDT_ROOT. +_bdt_cli_script() { + if [[ -f "${BDT_CLI_DIR}/bdt.sh" ]]; then + echo "${BDT_CLI_DIR}/bdt.sh" + else + echo "${BDT_ROOT}/bdt.sh" + fi +} + # Si existe ~/.bdt/project-root, usarlo como override if [[ -f "${HOME}/.bdt/project-root" ]]; then _saved_root="$(cat "${HOME}/.bdt/project-root")" @@ -63,7 +87,30 @@ SERVICEBUS_DIR="${BDT_ROOT}/backend/service-bus" APIBANK_DIR="${BDT_ROOT}/backend/apiBank" DATABASE_DIR="${BDT_ROOT}/database" LOG_DIR="${BDT_ROOT}/logs" -mkdir -p "${LOG_DIR}" + +# Logs escribibles: /opt/bdt-platform/logs suele ser root:root si alguna vez corrió con sudo. +_init_log_dir() { + if mkdir -p "${LOG_DIR}" 2>/dev/null && [[ -w "${LOG_DIR}" ]]; then + return 0 + fi + if [[ -d "${LOG_DIR}" && ! -w "${LOG_DIR}" ]]; then + sudo chown "$(id -un):$(id -gn)" "${LOG_DIR}" 2>/dev/null && [[ -w "${LOG_DIR}" ]] && return 0 + sudo chmod 775 "${LOG_DIR}" 2>/dev/null && [[ -w "${LOG_DIR}" ]] && return 0 + fi + LOG_DIR="${HOME}/.bdt/logs" + mkdir -p "${LOG_DIR}" +} +_init_log_dir + +# Ruta de log escribible (archivos viejos root:root rompen el redirect >) +_log_path() { + local name="$1" + local f="${LOG_DIR}/${name}" + if [[ -e "$f" && ! -w "$f" ]]; then + rm -f "$f" 2>/dev/null || sudo rm -f "$f" 2>/dev/null || true + fi + echo "$f" +} # GitLab GITLAB_URL="${GITLAB_URL:-http://gitlab.bicentenariobu.com.ve}" @@ -134,8 +181,8 @@ svc_port() { svc_health_url() { case "$1" in - gateway) echo "http://localhost:58050/actuator/health" ;; - service-bus) echo "http://localhost:58060/actuator/health" ;; + gateway) echo "http://localhost:58050/api/actuator/health" ;; + service-bus) echo "http://localhost:58060/api/actuator/health" ;; canales-admin-web) echo "http://localhost:58180/api/health" ;; canales-worker) echo "http://localhost:59091/health" ;; frontend) echo "http://localhost:59002" ;; @@ -176,6 +223,14 @@ else COMPOSE_CMD="docker compose" fi +# Compose files (override del banco suele existir en infrastructure/) +COMPOSE_FILES=(-f docker-compose.yml) +[[ -f "${INFRA_DIR}/docker-compose.override.yml" ]] && COMPOSE_FILES+=(-f docker-compose.override.yml) + +_run_compose() { + ( cd "$INFRA_DIR" && $COMPOSE_CMD "${COMPOSE_FILES[@]}" "$@" ) +} + # Servicios (lookup via funciones svc_port, svc_health_url, docker_name arriba) #=============================================================================== @@ -351,11 +406,12 @@ _docker_build_local() { fi [[ -n "$dockerfile" ]] && args+=(-f "$dockerfile_path") args+=("$dir") - if docker build "${args[@]}" > "${LOG_DIR}/${svc}-docker-build.log" 2>&1; then + local logfile="$(_log_path "${svc}-docker-build.log")" + if docker build "${args[@]}" > "$logfile" 2>&1; then ok "bdt-${svc}: imagen construida" else - err "bdt-${svc}: build falló (ver ${LOG_DIR}/${svc}-docker-build.log)" - tail -15 "${LOG_DIR}/${svc}-docker-build.log" | while read -r l; do echo -e " ${GRAY}${l}${NC}"; done + err "bdt-${svc}: build falló (ver ${logfile})" + tail -15 "$logfile" | while read -r l; do echo -e " ${GRAY}${l}${NC}"; done return 1 fi } @@ -452,13 +508,10 @@ cmd_rebuild() { 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" ]] && jar_path="$(_latest_jar_in_inbox)" [[ -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")" + _stage_jar_to_build_libs "$dir" "$jar_path" || continue else # OPCIÓN 1 — git pull + compilar acá if [[ -d "${dir}/.git" ]]; then @@ -587,6 +640,42 @@ cmd_jar_deploy() { ok "Deploy de ${svc} enviado a ${server}. Verificá salud con: ${GRAY}bdt logs ${svc} 100${NC} (o el health del server)." } +#=============================================================================== +# Helpers JAR externo (JAR_INBOX, default /tmp) +#=============================================================================== + +_jar_inbox() { + echo "${JAR_INBOX:-/tmp}" +} + +_latest_jar_in_inbox() { + local inbox="$(_jar_inbox)" + ls -t "${inbox}"/*.jar 2>/dev/null | grep -v -- '-plain.jar' | head -1 +} + +_stage_jar_to_build_libs() { + local dir="$1" jar_path="$2" + local dest_dir="${dir}/build/libs" dest_name + dest_name="$(basename "$jar_path")" + + if mkdir -p "$dest_dir" 2>/dev/null \ + && rm -f "${dest_dir}"/*.jar 2>/dev/null \ + && cp "$jar_path" "${dest_dir}/${dest_name}" 2>/dev/null; then + ok "Colocado en ${dest_dir}/${dest_name}" + return 0 + fi + # build/libs a veces queda root:root tras sudo ./gradlew + if sudo mkdir -p "$dest_dir" \ + && sudo rm -f "${dest_dir}"/*.jar \ + && sudo cp "$jar_path" "${dest_dir}/${dest_name}"; then + sudo chown "$(id -un):$(id -gn)" "${dest_dir}/${dest_name}" 2>/dev/null || true + ok "Colocado en ${dest_dir}/${dest_name} (vía sudo)" + return 0 + fi + err "No se pudo copiar el JAR a ${dest_dir}" + return 1 +} + #=============================================================================== # COMANDO: deploy-jar - No interactivo: mover un JAR externo → build/libs → build → up # Versión scriptable de la "Opción 2" de rebuild (sirve para CI o uso directo). @@ -618,20 +707,21 @@ cmd_deploy_jar() { local dir; dir="$(repo_dir "$svc")" [[ -z "$dir" ]] && { err "Servicio desconocido: ${svc}"; return 1; } - local inbox="${JAR_INBOX:-/tmp}" + local inbox="$(_jar_inbox)" step "DEPLOY-JAR ${svc}" "$(svc_desc "$svc") — jar externo → build${nocache:+ sin caché} → up" # 1. Resolver el JAR (ruta explícita o el más reciente del inbox) - [[ -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 "JAR no encontrado (${jar_path:-vacío}). Pasá la ruta o dejá un .jar en ${inbox}"; return 1; } + [[ -z "$jar_path" ]] && jar_path="$(_latest_jar_in_inbox)" + [[ -z "$jar_path" || ! -f "$jar_path" ]] && { + err "JAR no encontrado (${jar_path:-vacío}). Pasá la ruta o dejá un .jar en ${inbox}" + echo -e " ${GRAY}Ejemplo: scp bdtesb-0.0.1-SNAPSHOT.jar luis.perezsm@10.112.2.133:${inbox}/${NC}" + return 1 + } ok "JAR: ${jar_path} ($(du -h "$jar_path" | cut -f1))" # 2. Colocar en build/libs (uno solo — el Dockerfile copia *.jar) - 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 a build/libs"; return 1; } - ok "Colocado en ${dir}/build/libs/$(basename "$jar_path")" + _stage_jar_to_build_libs "$dir" "$jar_path" || return 1 # 3. Limpiar Docker previo (por defecto sí) if [[ -n "$clean" ]]; then @@ -643,8 +733,8 @@ cmd_deploy_jar() { # 4. Build + up _docker_build_local "$svc" "$nocache" || { err "Build de ${svc} falló"; return 1; } info "Recreando contenedor ${svc}..." - ( cd "$INFRA_DIR" && $COMPOSE_CMD --profile apps --profile tools up -d --force-recreate "$svc" 2>&1 \ - | while read -r l; do echo -e " ${GRAY}${l}${NC}"; done ) + _run_compose --profile apps --profile tools up -d --force-recreate "$svc" 2>&1 \ + | while read -r l; do echo -e " ${GRAY}${l}${NC}"; done # 5. Health local url; url="$(svc_health_url "$svc")" @@ -663,6 +753,145 @@ cmd_deploy_jar() { ok "${svc} recreado" } +# Menú interactivo: deploy-jar en el server (JAR ya subido a /tmp o JAR_INBOX) +cmd_deploy_jar_menu() { + banner + local inbox="$(_jar_inbox)" + step "DEPLOY JAR" "JAR en ${inbox} → imagen Docker → contenedor arriba" + + echo -e " ${GRAY}Subí el .jar antes (desde tu PC):${NC}" + echo -e " ${GRAY} scp build/libs/bdtesb-*.jar luis.perezsm@10.112.2.133:${inbox}/${NC}" + echo "" + + local jars=() + while IFS= read -r j; do jars+=("$j"); done < <(ls -t "${inbox}"/*.jar 2>/dev/null | grep -v -- '-plain.jar' || true) + if [[ ${#jars[@]} -gt 0 ]]; then + echo -e " ${GRAY}JARs en ${inbox}:${NC}" + local i=1 j + for j in "${jars[@]}"; do + echo -e " ${WHITE}${i}${NC}) $(basename "$j") ${GRAY}($(du -h "$j" | cut -f1))${NC}" + i=$((i + 1)) + done + echo "" + else + warn "No hay .jar en ${inbox}. Podés indicar una ruta manual abajo." + echo "" + fi + + echo -ne " Servicio Java (gateway/service-bus) [gateway]: " + read -r svc + svc="${svc:-gateway}" + + echo -ne " Ruta del JAR (Enter = más reciente en ${inbox}): " + read -r jar_path + + echo -ne " ¿Build sin caché? (S/n): " + read -r nc + if [[ "$nc" =~ ^[nN] ]]; then + cmd_deploy_jar "$svc" ${jar_path:+$jar_path} --cache + else + cmd_deploy_jar "$svc" ${jar_path:+$jar_path} + fi +} + +#=============================================================================== +# COMANDO: deploy-git - No interactivo: git pull (remote del banco) → build → up +# El "buen deploy" para correr EN el server (sudo ./bdt.sh deploy-git ): +# hace git pull del GitLab del banco + (compila si es Java) + docker build + up +# + health, sin interacción. Es el hermano scriptable de la Opción 1 de 'rebuild' +# (igual que deploy-jar es el de la Opción 2). Requiere que el host alcance el +# GitLab del banco y, para canales/frontend, el registry npm (build en Docker). +# Uso: bdt deploy-git [--no-cache] [--no-clean] +#=============================================================================== + +cmd_deploy_git() { + banner + local svc="" nocache="" do_clean="1" a + for a in "$@"; do + case "$a" in + --no-cache|nocache) nocache="--no-cache" ;; + --no-clean) do_clean="" ;; + --clean) do_clean="1" ;; + *) svc="$a" ;; + esac + done + + # Validar que sea un servicio de aplicación conocido + local valid="" s + for s in $APP_SERVICES; do [[ "$s" == "$svc" ]] && valid="1"; done + [[ -z "$valid" ]] && { + err "deploy-git requiere un servicio de aplicación: ${APP_SERVICES}" + echo -e " Uso: ${GRAY}bdt deploy-git [--no-cache] [--no-clean]${NC}" + return 1 + } + + local dir; dir="$(repo_dir "$svc")" + [[ -z "$dir" || ! -d "$dir" ]] && { err "Directorio del servicio no encontrado: ${dir:-vacío}"; return 1; } + + step "DEPLOY-GIT ${svc}" "$(svc_desc "$svc") — git pull (banco) → build${nocache:+ sin caché} → up" + + # 1. git pull desde el remote del banco (nombre varía por repo: origin/dcgeeks) + if [[ -d "${dir}/.git" ]]; then + local remote br + remote="$(_bank_remote "$dir")" + br="$(repo_branch "$svc")" + if [[ -n "$remote" ]]; then + info "git pull ${remote} ${br} en ${dir}..." + ( cd "$dir" && git pull --ff-only "$remote" "$br" 2>&1 | tail -4 | 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 "Sin remote del banco (${GITLAB_URL}) en ${dir} — uso 'git pull --ff-only' por defecto" + ( cd "$dir" && git pull --ff-only 2>&1 | tail -4 | while read -r l; do echo -e " ${GRAY}${l}${NC}"; done ) \ + || warn "git pull no fue limpio — continúo con el código presente" + fi + else + warn "${dir} no es repo git — uso el código presente" + fi + + # 2. Compilar (solo Java; canales/frontend compilan dentro del Docker build multi-stage) + case "$svc" in + gateway|service-bus) + info "Compilando ${svc} (gradle bootJar, sin tests)..." + ( cd "$dir" && ./gradlew clean bootJar -x test > "${LOG_DIR}/${svc}-deploygit-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}/${svc}-deploygit-gradle.log)"; return 1; } + ;; + *) info "${svc}: compila dentro del Docker build (multi-stage), nada que compilar acá" ;; + esac + + # 3. Limpiar Docker previo (contenedor + imagen) salvo --no-clean + if [[ -n "$do_clean" ]]; then + info "Limpiando Docker previo de ${svc} (contenedor + imagen)..." + docker rm -f "$(docker_name "$svc")" >/dev/null 2>&1 || true + docker rmi -f "bdt-${svc}:latest" >/dev/null 2>&1 || true + ok "Contenedor e imagen previos eliminados" + fi + + # 4. Docker build + _docker_build_local "$svc" "$nocache" || { err "Build de ${svc} falló"; return 1; } + + # 5. Up + info "Recreando contenedor ${svc}..." + _run_compose --profile apps --profile tools up -d --force-recreate "$svc" 2>&1 \ + | while read -r l; do echo -e " ${GRAY}${l}${NC}"; done + + # 6. Health + local url; url="$(svc_health_url "$svc")" + if [[ -n "$url" ]]; then + info "Esperando salud de ${svc} (hasta 120s)..." + local tries=0 code="000" + while (( tries < 24 )); do + code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 3 "$url" 2>/dev/null || echo "000") + [[ "$code" =~ ^(200|302|401)$ ]] && break + sleep 5; tries=$((tries+1)) + done + cd "$BDT_ROOT" 2>/dev/null || true + [[ "$code" =~ ^(200|302|401)$ ]] && { ok "${svc} saludable (HTTP ${code})"; return 0; } || { err "${svc}: sin health OK (HTTP ${code}) — revisá: bdt logs ${svc} 100"; return 1; } + fi + cd "$BDT_ROOT" 2>/dev/null || true + ok "${svc} recreado" +} + #=============================================================================== # COMANDO: up - Levantar servicios #=============================================================================== @@ -1258,23 +1487,22 @@ cmd_setup() { # Detectar shell del usuario local user_shell="$(basename "$SHELL" 2>/dev/null || echo "bash")" - # 1. Instalar comando global 'bdt' + # 1. Instalar comando global 'bdt' (desde repo bdt-cli si existe) echo -e " ${O3}${BOLD}[1/5] Instalando comando global 'bdt'...${NC}" echo "" + local bdt_script="$(_bdt_cli_script)" if [[ -w "$install_dir" ]]; then - # Sin sudo - ln -sf "${BDT_ROOT}/bdt.sh" "${install_dir}/bdt" 2>/dev/null - ok "Enlace creado: ${install_dir}/bdt -> bdt.sh" + ln -sf "$bdt_script" "${install_dir}/bdt" 2>/dev/null + ok "Enlace creado: ${install_dir}/bdt -> ${bdt_script}" else info "Se necesita sudo para instalar en ${install_dir}" - sudo ln -sf "${BDT_ROOT}/bdt.sh" "${install_dir}/bdt" 2>/dev/null && \ - ok "Enlace creado: ${install_dir}/bdt -> bdt.sh" || { - # Fallback: instalar en ~/bin + sudo ln -sf "$bdt_script" "${install_dir}/bdt" 2>/dev/null && \ + ok "Enlace creado: ${install_dir}/bdt -> ${bdt_script}" || { install_dir="${HOME}/bin" mkdir -p "$install_dir" - ln -sf "${BDT_ROOT}/bdt.sh" "${install_dir}/bdt" 2>/dev/null - ok "Enlace creado: ${install_dir}/bdt -> bdt.sh" + ln -sf "$bdt_script" "${install_dir}/bdt" 2>/dev/null + ok "Enlace creado: ${install_dir}/bdt -> ${bdt_script}" warn "Asegurate de que ${install_dir} este en tu PATH" } fi @@ -1300,17 +1528,25 @@ GITLAB_GROUP=dcgeeks # Ambiente por defecto (desarrollo|calidad|demo|produccion) DEFAULT_ENV=desarrollo -# Servidor de deploy remoto (comando server-deploy) -# DEPLOY_SERVER=10.0.0.1 -# DEPLOY_USER=usuario.ssh +# Repo git del shell (para bdt self-update) +BDT_CLI_DIR=/opt/bdt-platform/bdt-cli +BDT_CLI_GIT_URL=http://gitlab.bicentenariobu.com.ve/dcgeeks/bdt-cli.git -# Logs -LOG_RETENTION_DAYS=30 +# Carpeta donde el server espera JARs subidos (deploy-jar / menú u) +JAR_INBOX=/tmp CONF ok "Archivo de configuracion creado: ${config_dir}/config" else ok "Configuracion existente preservada: ${config_dir}/config" fi + + # Logs del proyecto escribibles por el usuario (evita Permission denied en build) + if [[ -d "${BDT_ROOT}/logs" ]]; then + sudo chown -R "$(id -un):$(id -gn)" "${BDT_ROOT}/logs" 2>/dev/null \ + || sudo chmod -R 775 "${BDT_ROOT}/logs" 2>/dev/null \ + || true + fi + mkdir -p "${BDT_ROOT}/logs" 2>/dev/null || true echo "" # 3. Autocompletado @@ -1323,7 +1559,7 @@ _bdt_completions() { local cur="${COMP_WORDS[COMP_CWORD]}" local prev="${COMP_WORDS[COMP_CWORD-1]}" - local commands="clone pull install build rebuild jar-deploy deploy-jar up down restart status logs health verify-db verify-api deploy construir publish env update creds clean setup menu help image-login image-build image-push image-pull image-deploy image-build-amd64 server-deploy" + local commands="clone pull install build rebuild jar-deploy deploy-jar deploy-git self-update up down restart status logs health verify-db verify-api deploy construir publish env update creds clean setup menu help image-login image-build image-push image-pull image-deploy image-build-amd64 server-deploy" local services="frontend gateway service-bus canales-admin-web canales-worker apibank infrastructure database" local up_targets="all infra apps tools frontend gateway canales-admin-web canales-worker service-bus postgres redis keycloak" local envs="desarrollo calidad demo produccion" @@ -1485,6 +1721,8 @@ _menu_dispatch() { if [[ "$jd_nc" =~ ^[sSyY] ]]; then cmd_jar_deploy "$jd_svc" --build --no-cache; else cmd_jar_deploy "$jd_svc" --build; fi fi ;; + u) cmd_deploy_jar_menu ;; + x) cmd_self_update ;; g) cmd_clone ;; h) cmd_pull ;; i) @@ -1532,7 +1770,9 @@ cmd_menu() { echo -e " ${WHITE}e${NC}) Compilar todo ${WHITE}h${NC}) Actualizar repos ${WHITE}j${NC}) Cambiar ambiente" echo -e " ${WHITE}f${NC}) Build Docker ${WHITE}i${NC}) Actualizar servicio ${WHITE}k${NC}) Limpiar Docker" echo -e " ${WHITE}r${NC}) Build amd64 + push registry ${WHITE}t${NC}) Deploy en server (SSH)" - echo -e " ${WHITE}p${NC}) Subir JAR al server (jar-deploy: scp jar → build/libs → build+up remoto)" + echo -e " ${WHITE}u${NC}) Deploy JAR en este server ${GRAY}— /tmp (JAR_INBOX) → docker build → up${NC}" + echo -e " ${WHITE}p${NC}) Subir JAR desde tu PC ${GRAY}— jar-deploy: scp → server remoto${NC}" + echo -e " ${WHITE}x${NC}) Actualizar shell bdt ${GRAY}— git pull bdt-cli → reinstalar enlace${NC}" echo "" echo -e " ${WHITE}?${NC}) Ayuda ${WHITE}q${NC}) Salir" echo "" @@ -1961,6 +2201,72 @@ cmd_construir() { ok "Asistente completado en ${elapsed}s — ${svc} @ ${branch}" } +#=============================================================================== +# COMANDO: self-update - git pull del repo bdt-cli e reinstalar enlace global +# Pensado para el server del banco: bdt self-update +#=============================================================================== + +cmd_self_update() { + banner + step "SELF-UPDATE" "Actualizar shell bdt desde git (repo bdt-cli)" + + local cli_dir="$(_resolve_bdt_cli_dir)" + local bank_url="${BDT_CLI_GIT_URL:-http://gitlab.bicentenariobu.com.ve/dcgeeks/bdt-cli.git}" + local gitea_url="${BDT_CLI_GIT_URL_GITEA:-https://git.dcgeeks.net/BDT/bdt-cli.git}" + local branch="${BDT_CLI_BRANCH:-main}" + + if [[ ! -d "${cli_dir}/.git" ]]; then + info "Clonando bdt-cli en ${cli_dir}..." + sudo mkdir -p "$(dirname "$cli_dir")" 2>/dev/null || mkdir -p "$(dirname "$cli_dir")" + if git clone --branch "$branch" "$bank_url" "$cli_dir" 2>/dev/null; then + ok "Clonado desde GitLab del banco" + elif git clone --branch "$branch" "$gitea_url" "$cli_dir" 2>/dev/null; then + ok "Clonado desde Gitea (fallback)" + else + err "No se pudo clonar bdt-cli" + echo -e " ${GRAY}git clone ${bank_url} ${cli_dir}${NC}" + return 1 + fi + else + info "git pull en ${cli_dir}..." + ( + cd "$cli_dir" || exit 1 + local remote="origin" + git fetch "$remote" "$branch" 2>/dev/null || true + git pull --ff-only "$remote" "$branch" 2>/dev/null || git pull --ff-only "$remote" main + ) || { err "git pull falló en ${cli_dir}"; return 1; } + ok "Repo actualizado" + fi + + chmod +x "${cli_dir}/bdt.sh" + + local ver + ver="$(grep '^SCRIPT_VERSION=' "${cli_dir}/bdt.sh" | head -1 | cut -d'"' -f2)" + ok "Versión instalada: v${ver:-?}" + + local install_dir="/usr/local/bin" bdt_script="${cli_dir}/bdt.sh" + if [[ -w "$install_dir" ]]; then + ln -sf "$bdt_script" "${install_dir}/bdt" + else + sudo ln -sf "$bdt_script" "${install_dir}/bdt" + fi + ok "Enlace: ${install_dir}/bdt → ${bdt_script}" + + mkdir -p "${HOME}/.bdt" + [[ -d /opt/bdt-platform ]] && echo /opt/bdt-platform > "${HOME}/.bdt/project-root" + grep -q '^BDT_CLI_DIR=' "${HOME}/.bdt/config" 2>/dev/null || \ + echo "BDT_CLI_DIR=${cli_dir}" >> "${HOME}/.bdt/config" + + if [[ -d "${BDT_ROOT}/logs" ]]; then + sudo chown -R "$(id -un):$(id -gn)" "${BDT_ROOT}/logs" 2>/dev/null \ + || sudo chmod -R 775 "${BDT_ROOT}/logs" 2>/dev/null || true + fi + _init_log_dir + + echo "" + info "Probar: ${GRAY}bdt help | head -5${NC}" +} + #=============================================================================== # COMANDO: publish - Sincronizar bdt.sh al repo público bdt-cli (Gitea) #=============================================================================== @@ -1996,13 +2302,22 @@ cmd_publish() { git commit -q -m "chore: sync bdt.sh v${SCRIPT_VERSION} (monorepo @ ${src_sha})" && \ ok "Commit creado: v${SCRIPT_VERSION} @ ${src_sha}" || { err "Commit falló"; cd "$BDT_ROOT"; return 1; } - info "Pusheando a Gitea..." + info "Pusheando a Gitea (origin)..." if git push origin main 2>&1 | tail -2 | while read -r l; do echo -e " ${GRAY}${l}${NC}"; done; then ok "Publicado: https://git.dcgeeks.net/BDT/bdt-cli" else - err "Push falló — corré 'git push origin main' en ${cli_dir}" + err "Push a origin falló — corré 'git push origin main' en ${cli_dir}" cd "$BDT_ROOT"; return 1 fi + + if git remote | grep -qx dcgeeks; then + info "Pusheando a GitLab del banco (dcgeeks)..." + if git push dcgeeks main 2>&1 | tail -2 | while read -r l; do echo -e " ${GRAY}${l}${NC}"; done; then + ok "Publicado: ${GITLAB_URL}/${GITLAB_GROUP}/bdt-cli" + else + warn "Push a dcgeeks falló — el server puede usar Gitea como fallback en self-update" + fi + fi cd "$BDT_ROOT" } @@ -2057,6 +2372,9 @@ cmd_help() { echo -e " ${WHITE}deploy-jar${NC} [ruta-jar] [--cache] [--no-clean]" echo -e " NO interactivo (CI/local en el server): mueve un jar externo → build/libs →" echo -e " limpia docker → build --no-cache → up. Sin ruta usa el más reciente de JAR_INBOX (/tmp)." + echo -e " ${WHITE}deploy-git${NC} [--no-cache] [--no-clean]" + echo -e " NO interactivo, para correr EN el server: git pull (remote del banco) →" + echo -e " (compila si es Java) → docker build → up + health. El 'buen deploy' desde el server." echo "" echo -e " ${O3}${BOLD}JAR pre-compilado (image-build / image-build-amd64):${NC}" echo -e " Gradle NO corre. Copiá el JAR compilado ANTES de buildear:" @@ -2067,7 +2385,8 @@ cmd_help() { echo "" echo -e " ${O2}${BOLD}UTILIDADES${NC}" echo -e " ${WHITE}git-auth${NC} [user] [pass] Configurar credenciales Git (no pide clave en cada pull)" - echo -e " ${WHITE}publish${NC} Sincronizar bdt.sh al repo público bdt-cli (Gitea)" + echo -e " ${WHITE}publish${NC} Sincronizar bdt.sh → repo bdt-cli (Gitea + GitLab banco)" + echo -e " ${WHITE}self-update${NC} En el server: git pull bdt-cli + reinstalar enlace global" echo -e " ${WHITE}setup${NC} Instalar 'bdt' como comando global + alias + autocompletado" echo -e " ${WHITE}menu${NC} Menu interactivo (panel de control)" echo -e " ${WHITE}creds${NC} Mostrar credenciales" @@ -2098,6 +2417,7 @@ case "$cmd" in rebuild|rebuild-nc) cmd_rebuild "$@" ;; jar-deploy|jardeploy) cmd_jar_deploy "$@" ;; deploy-jar|deployjar) cmd_deploy_jar "$@" ;; + deploy-git|deploygit) cmd_deploy_git "$@" ;; up|start) cmd_up "$@" ;; down|stop) cmd_down "$@" ;; restart) cmd_restart "$@" ;; @@ -2111,6 +2431,7 @@ case "$cmd" in deploy) cmd_deploy "$@" ;; construir|wizard|asistente) cmd_construir "$@" ;; publish) cmd_publish "$@" ;; + self-update|selfupdate|update-cli) cmd_self_update "$@" ;; creds) cmd_creds "$@" ;; clean) cmd_clean "$@" ;; git-auth) cmd_git_auth "$@" ;;