chore: sync bdt.sh v2.7.0 (monorepo @ e06c6bb)

This commit is contained in:
2026-07-29 10:27:09 -04:00
parent c2392b31ee
commit 7b9baa3488

401
bdt.sh
View File

@@ -20,7 +20,7 @@ set -euo pipefail
# CONFIGURACION # CONFIGURACION
#=============================================================================== #===============================================================================
SCRIPT_VERSION="2.5.0" SCRIPT_VERSION="2.7.0"
SCRIPT_NAME="$(basename "$0")" SCRIPT_NAME="$(basename "$0")"
# Directorios - resolver symlinks para encontrar la ruta real # Directorios - resolver symlinks para encontrar la ruta real
@@ -37,6 +37,30 @@ _resolve_root() {
} }
BDT_ROOT="${BDT_ROOT:-$(_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 # Si existe ~/.bdt/project-root, usarlo como override
if [[ -f "${HOME}/.bdt/project-root" ]]; then if [[ -f "${HOME}/.bdt/project-root" ]]; then
_saved_root="$(cat "${HOME}/.bdt/project-root")" _saved_root="$(cat "${HOME}/.bdt/project-root")"
@@ -63,7 +87,30 @@ SERVICEBUS_DIR="${BDT_ROOT}/backend/service-bus"
APIBANK_DIR="${BDT_ROOT}/backend/apiBank" APIBANK_DIR="${BDT_ROOT}/backend/apiBank"
DATABASE_DIR="${BDT_ROOT}/database" DATABASE_DIR="${BDT_ROOT}/database"
LOG_DIR="${BDT_ROOT}/logs" 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
GITLAB_URL="${GITLAB_URL:-http://gitlab.bicentenariobu.com.ve}" GITLAB_URL="${GITLAB_URL:-http://gitlab.bicentenariobu.com.ve}"
@@ -134,8 +181,8 @@ svc_port() {
svc_health_url() { svc_health_url() {
case "$1" in case "$1" in
gateway) echo "http://localhost:58050/actuator/health" ;; gateway) echo "http://localhost:58050/api/actuator/health" ;;
service-bus) echo "http://localhost:58060/actuator/health" ;; service-bus) echo "http://localhost:58060/api/actuator/health" ;;
canales-admin-web) echo "http://localhost:58180/api/health" ;; canales-admin-web) echo "http://localhost:58180/api/health" ;;
canales-worker) echo "http://localhost:59091/health" ;; canales-worker) echo "http://localhost:59091/health" ;;
frontend) echo "http://localhost:59002" ;; frontend) echo "http://localhost:59002" ;;
@@ -176,6 +223,14 @@ else
COMPOSE_CMD="docker compose" COMPOSE_CMD="docker compose"
fi 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) # Servicios (lookup via funciones svc_port, svc_health_url, docker_name arriba)
#=============================================================================== #===============================================================================
@@ -351,11 +406,12 @@ _docker_build_local() {
fi fi
[[ -n "$dockerfile" ]] && args+=(-f "$dockerfile_path") [[ -n "$dockerfile" ]] && args+=(-f "$dockerfile_path")
args+=("$dir") 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" ok "bdt-${svc}: imagen construida"
else else
err "bdt-${svc}: build falló (ver ${LOG_DIR}/${svc}-docker-build.log)" err "bdt-${svc}: build falló (ver ${logfile})"
tail -15 "${LOG_DIR}/${svc}-docker-build.log" | while read -r l; do echo -e " ${GRAY}${l}${NC}"; done tail -15 "$logfile" | while read -r l; do echo -e " ${GRAY}${l}${NC}"; done
return 1 return 1
fi fi
} }
@@ -452,13 +508,10 @@ cmd_rebuild() {
esac esac
echo -ne " ${O3}Ruta del JAR para ${s} (Enter = más reciente en ${inbox}):${NC} " echo -ne " ${O3}Ruta del JAR para ${s} (Enter = más reciente en ${inbox}):${NC} "
read -r jar_path 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; } [[ -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/" info "Moviendo $(basename "$jar_path")${dir}/build/libs/"
mkdir -p "${dir}/build/libs" _stage_jar_to_build_libs "$dir" "$jar_path" || continue
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 else
# OPCIÓN 1 — git pull + compilar acá # OPCIÓN 1 — git pull + compilar acá
if [[ -d "${dir}/.git" ]]; then 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)." 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 # 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). # 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")" local dir; dir="$(repo_dir "$svc")"
[[ -z "$dir" ]] && { err "Servicio desconocido: ${svc}"; return 1; } [[ -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" 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) # 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" ]] && 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}"; return 1; } [[ -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))" ok "JAR: ${jar_path} ($(du -h "$jar_path" | cut -f1))"
# 2. Colocar en build/libs (uno solo — el Dockerfile copia *.jar) # 2. Colocar en build/libs (uno solo — el Dockerfile copia *.jar)
mkdir -p "${dir}/build/libs" _stage_jar_to_build_libs "$dir" "$jar_path" || return 1
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")"
# 3. Limpiar Docker previo (por defecto sí) # 3. Limpiar Docker previo (por defecto sí)
if [[ -n "$clean" ]]; then if [[ -n "$clean" ]]; then
@@ -643,8 +733,8 @@ cmd_deploy_jar() {
# 4. Build + up # 4. Build + up
_docker_build_local "$svc" "$nocache" || { err "Build de ${svc} falló"; return 1; } _docker_build_local "$svc" "$nocache" || { err "Build de ${svc} falló"; return 1; }
info "Recreando contenedor ${svc}..." info "Recreando contenedor ${svc}..."
( cd "$INFRA_DIR" && $COMPOSE_CMD --profile apps --profile tools up -d --force-recreate "$svc" 2>&1 \ _run_compose --profile apps --profile tools up -d --force-recreate "$svc" 2>&1 \
| while read -r l; do echo -e " ${GRAY}${l}${NC}"; done ) | while read -r l; do echo -e " ${GRAY}${l}${NC}"; done
# 5. Health # 5. Health
local url; url="$(svc_health_url "$svc")" local url; url="$(svc_health_url "$svc")"
@@ -663,6 +753,145 @@ cmd_deploy_jar() {
ok "${svc} recreado" 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 <svc>):
# 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 <svc> [--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 <svc> [--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 # COMANDO: up - Levantar servicios
#=============================================================================== #===============================================================================
@@ -1258,23 +1487,22 @@ cmd_setup() {
# Detectar shell del usuario # Detectar shell del usuario
local user_shell="$(basename "$SHELL" 2>/dev/null || echo "bash")" 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 -e " ${O3}${BOLD}[1/5] Instalando comando global 'bdt'...${NC}"
echo "" echo ""
local bdt_script="$(_bdt_cli_script)"
if [[ -w "$install_dir" ]]; then if [[ -w "$install_dir" ]]; then
# Sin sudo ln -sf "$bdt_script" "${install_dir}/bdt" 2>/dev/null
ln -sf "${BDT_ROOT}/bdt.sh" "${install_dir}/bdt" 2>/dev/null ok "Enlace creado: ${install_dir}/bdt -> ${bdt_script}"
ok "Enlace creado: ${install_dir}/bdt -> bdt.sh"
else else
info "Se necesita sudo para instalar en ${install_dir}" info "Se necesita sudo para instalar en ${install_dir}"
sudo ln -sf "${BDT_ROOT}/bdt.sh" "${install_dir}/bdt" 2>/dev/null && \ sudo ln -sf "$bdt_script" "${install_dir}/bdt" 2>/dev/null && \
ok "Enlace creado: ${install_dir}/bdt -> bdt.sh" || { ok "Enlace creado: ${install_dir}/bdt -> ${bdt_script}" || {
# Fallback: instalar en ~/bin
install_dir="${HOME}/bin" install_dir="${HOME}/bin"
mkdir -p "$install_dir" mkdir -p "$install_dir"
ln -sf "${BDT_ROOT}/bdt.sh" "${install_dir}/bdt" 2>/dev/null ln -sf "$bdt_script" "${install_dir}/bdt" 2>/dev/null
ok "Enlace creado: ${install_dir}/bdt -> bdt.sh" ok "Enlace creado: ${install_dir}/bdt -> ${bdt_script}"
warn "Asegurate de que ${install_dir} este en tu PATH" warn "Asegurate de que ${install_dir} este en tu PATH"
} }
fi fi
@@ -1300,17 +1528,25 @@ GITLAB_GROUP=dcgeeks
# Ambiente por defecto (desarrollo|calidad|demo|produccion) # Ambiente por defecto (desarrollo|calidad|demo|produccion)
DEFAULT_ENV=desarrollo DEFAULT_ENV=desarrollo
# Servidor de deploy remoto (comando server-deploy) # Repo git del shell (para bdt self-update)
# DEPLOY_SERVER=10.0.0.1 BDT_CLI_DIR=/opt/bdt-platform/bdt-cli
# DEPLOY_USER=usuario.ssh BDT_CLI_GIT_URL=http://gitlab.bicentenariobu.com.ve/dcgeeks/bdt-cli.git
# Logs # Carpeta donde el server espera JARs subidos (deploy-jar / menú u)
LOG_RETENTION_DAYS=30 JAR_INBOX=/tmp
CONF CONF
ok "Archivo de configuracion creado: ${config_dir}/config" ok "Archivo de configuracion creado: ${config_dir}/config"
else else
ok "Configuracion existente preservada: ${config_dir}/config" ok "Configuracion existente preservada: ${config_dir}/config"
fi 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 "" echo ""
# 3. Autocompletado # 3. Autocompletado
@@ -1323,7 +1559,7 @@ _bdt_completions() {
local cur="${COMP_WORDS[COMP_CWORD]}" local cur="${COMP_WORDS[COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD-1]}" 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 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 up_targets="all infra apps tools frontend gateway canales-admin-web canales-worker service-bus postgres redis keycloak"
local envs="desarrollo calidad demo produccion" 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 if [[ "$jd_nc" =~ ^[sSyY] ]]; then cmd_jar_deploy "$jd_svc" --build --no-cache; else cmd_jar_deploy "$jd_svc" --build; fi
fi fi
;; ;;
u) cmd_deploy_jar_menu ;;
x) cmd_self_update ;;
g) cmd_clone ;; g) cmd_clone ;;
h) cmd_pull ;; h) cmd_pull ;;
i) 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}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}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}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 ""
echo -e " ${WHITE}?${NC}) Ayuda ${WHITE}q${NC}) Salir" echo -e " ${WHITE}?${NC}) Ayuda ${WHITE}q${NC}) Salir"
echo "" echo ""
@@ -1961,6 +2201,72 @@ cmd_construir() {
ok "Asistente completado en ${elapsed}s — ${svc} @ ${branch}" 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) # 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})" && \ 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; } 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 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" ok "Publicado: https://git.dcgeeks.net/BDT/bdt-cli"
else 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 cd "$BDT_ROOT"; return 1
fi 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" cd "$BDT_ROOT"
} }
@@ -2057,6 +2372,9 @@ cmd_help() {
echo -e " ${WHITE}deploy-jar${NC} <gateway|service-bus> [ruta-jar] [--cache] [--no-clean]" echo -e " ${WHITE}deploy-jar${NC} <gateway|service-bus> [ruta-jar] [--cache] [--no-clean]"
echo -e " NO interactivo (CI/local en el server): mueve un jar externo → build/libs →" 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 " limpia docker → build --no-cache → up. Sin ruta usa el más reciente de JAR_INBOX (/tmp)."
echo -e " ${WHITE}deploy-git${NC} <svc> [--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 ""
echo -e " ${O3}${BOLD}JAR pre-compilado (image-build / image-build-amd64):${NC}" 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:" echo -e " Gradle NO corre. Copiá el JAR compilado ANTES de buildear:"
@@ -2067,7 +2385,8 @@ cmd_help() {
echo "" echo ""
echo -e " ${O2}${BOLD}UTILIDADES${NC}" 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}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}setup${NC} Instalar 'bdt' como comando global + alias + autocompletado"
echo -e " ${WHITE}menu${NC} Menu interactivo (panel de control)" echo -e " ${WHITE}menu${NC} Menu interactivo (panel de control)"
echo -e " ${WHITE}creds${NC} Mostrar credenciales" echo -e " ${WHITE}creds${NC} Mostrar credenciales"
@@ -2098,6 +2417,7 @@ case "$cmd" in
rebuild|rebuild-nc) cmd_rebuild "$@" ;; rebuild|rebuild-nc) cmd_rebuild "$@" ;;
jar-deploy|jardeploy) cmd_jar_deploy "$@" ;; jar-deploy|jardeploy) cmd_jar_deploy "$@" ;;
deploy-jar|deployjar) cmd_deploy_jar "$@" ;; deploy-jar|deployjar) cmd_deploy_jar "$@" ;;
deploy-git|deploygit) cmd_deploy_git "$@" ;;
up|start) cmd_up "$@" ;; up|start) cmd_up "$@" ;;
down|stop) cmd_down "$@" ;; down|stop) cmd_down "$@" ;;
restart) cmd_restart "$@" ;; restart) cmd_restart "$@" ;;
@@ -2111,6 +2431,7 @@ case "$cmd" in
deploy) cmd_deploy "$@" ;; deploy) cmd_deploy "$@" ;;
construir|wizard|asistente) cmd_construir "$@" ;; construir|wizard|asistente) cmd_construir "$@" ;;
publish) cmd_publish "$@" ;; publish) cmd_publish "$@" ;;
self-update|selfupdate|update-cli) cmd_self_update "$@" ;;
creds) cmd_creds "$@" ;; creds) cmd_creds "$@" ;;
clean) cmd_clean "$@" ;; clean) cmd_clean "$@" ;;
git-auth) cmd_git_auth "$@" ;; git-auth) cmd_git_auth "$@" ;;