From b2b35f41ebefdda3736fe3e21adad3f4d6c32c9d Mon Sep 17 00:00:00 2001 From: nbaglietto Date: Sun, 17 Aug 2025 00:31:28 -0300 Subject: [PATCH] Auto-commit --- README.md | 160 +++++++++++++++------------ instalar-subir.sh | 274 ++++++++++++++++++++++++---------------------- test-subir.sh | 42 +++++++ 3 files changed, 275 insertions(+), 201 deletions(-) create mode 100644 test-subir.sh diff --git a/README.md b/README.md index 4065fb8..c4c47ef 100644 --- a/README.md +++ b/README.md @@ -1,99 +1,123 @@ -# 🚀 git-subir +# 🧠 git-subir — Instalador autosuficiente para subir cambios vía Git con autenticación segura -Script CLI para automatizar el push de cambios a repositorios Gitea con autenticación segura, configuración automática de remotos, commits interactivos, recuperación ante errores y cifrado opcional de credenciales. +Este proyecto instala el comando `git subir`, que encapsula `git push` con autenticación segura, tolerancia a errores y configuración automática del entorno. Está diseñado para entornos reales, con portabilidad, robustez y experiencia de usuario optimizada. --- -## 📦 Archivos incluidos +## ✅ Funcionalidades incluidas -| Archivo | Descripción | -|------------------------|-----------------------------------------------------------------------------| -| `instalar-subir.sh` | Instalador interactivo que configura credenciales, instala el comando global `git-subir` y valida entorno. | -| `git-subir` | Script principal que automatiza el flujo de push, commits, configuración de remotos y recuperación ante errores. | -| `desinstalar-subir.sh` | Elimina el binario instalado y la configuración/credenciales guardadas. | +| Funcionalidad | Estado | +|---------------|--------| +| Solicitud y validación de credenciales | ✅ | +| Cifrado con OpenSSL (AES-256-CBC + PBKDF2) | ✅ | +| Cambio de contraseña de cifrado (`--cambiar-clave`) | ✅ | +| Reconfiguración completa (`--reconfigurar`) | ✅ | +| Generación automática del script `git-subir` | ✅ | +| Instalación en `~/.local/bin` | ✅ | +| Alias `git subir` vía `git config --global` | ✅ | +| Verificación y corrección de `$PATH` | ✅ | +| Inicialización de repositorio si no existe | ✅ | +| Configuración automática de upstream | ✅ | +| Mensajes claros y tolerancia a errores | ✅ | --- -## 🔧 Requisitos +## 📦 Requisitos -- Bash 4+ -- Git instalado y configurado -- `curl`, `jq`, `openssl` disponibles en el sistema -- Acceso a un servidor Gitea con token o usuario/contraseña válidos -- Carpeta `~/.local/bin` incluida en el `$PATH` +- Git instalado y accesible desde la terminal +- `curl` para validación de credenciales vía API +- `openssl` para cifrado seguro (AES-256-CBC + PBKDF2) +- Shell compatible (`bash` o `zsh`) +- Acceso a la API de Gitea (o compatible con GitHub/GitLab si se adapta el endpoint) --- -## 🧪 Instalación +## 🚀 Instalación -```bash -chmod +x instalar-subir.sh -./instalar-subir.sh +1. Cloná el repositorio o descargá el script `instalar-subir.sh` +2. Ejecutá el instalador: -Durante la instalación se te pedirá: + ```bash + chmod +x instalar-subir.sh + ./instalar-subir.sh -URL base del servidor Gitea (ej: https://gitea.midominio.com) -Usuario y contraseña o token +# 🧠 git-subir — Instalador autosuficiente para subir cambios vía Git con autenticación segura -Si querés cifrar las credenciales (usando AES-256-CBC con PBKDF2) +Este proyecto instala el comando `git subir`, que encapsula `git push` con autenticación segura, tolerancia a errores y configuración automática del entorno. Está diseñado para entornos reales, con portabilidad, robustez y experiencia de usuario optimizada. -Confirmación para instalar git-subir como comando global +--- -El script valida las credenciales contra la API de Gitea antes de continuar. +## ✅ Funcionalidades incluidas -🚀 Uso -Una vez instalado, podés usar git-subir desde cualquier repositorio git: +| Funcionalidad | Estado | +|---------------|--------| +| Solicitud y validación de credenciales | ✅ | +| Cifrado con OpenSSL (AES-256-CBC + PBKDF2) | ✅ | +| Cambio de contraseña de cifrado (`--cambiar-clave`) | ✅ | +| Reconfiguración completa (`--reconfigurar`) | ✅ | +| Generación automática del script `git-subir` | ✅ | +| Instalación en `~/.local/bin` | ✅ | +| Alias `git subir` vía `git config --global` | ✅ | +| Verificación y corrección de `$PATH` | ✅ | +| Inicialización de repositorio si no existe | ✅ | +| Configuración automática de upstream | ✅ | +| Mensajes claros y tolerancia a errores | ✅ | + +--- + +## 📦 Requisitos + +- Git instalado y accesible desde la terminal +- `curl` para validación de credenciales vía API +- `openssl` para cifrado seguro (AES-256-CBC + PBKDF2) +- Shell compatible (`bash` o `zsh`) +- Acceso a la API de Gitea (o compatible con GitHub/GitLab si se adapta el endpoint) + +--- + +## 🚀 Instalación + +1. Cloná el repositorio o descargá el script `instalar-subir.sh` +2. Ejecutá el instalador: + + ```bash + chmod +x instalar-subir.sh + ./instalar-subir.sh + +source ~/.bashrc # o ~/.zshrc según tu shell + +Uso +bash +git subir +Sube los cambios al remoto configurado, validando credenciales y configurando upstream si es necesario. + +Opciones avanzadas +bash +git subir --reconfigurar +🔄 Permite cambiar usuario, token, URL y contraseña de cifrado. bash -git-subir -El script realiza: - -Carga y descifrado de credenciales (si están cifradas) - -Verificación de cambios sin commitear - -Commit automático si lo autorizás - -Verificación de configuración del remote origin - -Push al repositorio remoto - -Si el push falla, intenta git pull --rebase y reintenta - -🔁 Reconfigurar credenciales -Podés ejecutar: - -bash -git-subir --reconfigurar -Esto permite: - -Cambiar usuario/contraseña o token - -Elegir si querés cifrar o guardar en texto plano - -Validar nuevamente contra la API - -Reescribir la configuración en ~/.config/git-subir/ +git subir --cambiar-clave +🔐 Cambia solo la contraseña de cifrado sin tocar usuario/token. 🔐 Seguridad -Cifrado con openssl usando AES-256-CBC y derivación PBKDF2 +Las credenciales se cifran con AES-256-CBC + PBKDF2 usando OpenSSL -La contraseña de cifrado nunca se guarda +El archivo de configuración se guarda en ~/.config/git-subir.conf -Los archivos se almacenan en ~/.config/git-subir/ para mantener orden +La contraseña de cifrado nunca se guarda, se solicita en cada ejecución -El binario se instala en ~/.local/bin/git-subir para uso global +El script tolera errores de autenticación, PATH, upstream y configuración + +📁 Desinstalación +Si querés eliminar todo: -🧹 Desinstalación bash -chmod +x desinstalar-subir.sh -./desinstalar-subir.sh -Esto elimina: +rm ~/.local/bin/git-subir +git config --global --unset alias.subir +rm ~/.config/git-subir.conf +🧪 Estado del proyecto +Listo para producción. Validado en entornos bash, zsh, root, y con múltiples configuraciones de Git. Diseñado para ser portable, seguro y fácil de mantener. -El binario git-subir de ~/.local/bin -Las credenciales y configuración de ~/.config/git-subir - -🧠 Autor -Nahuel Baglietto diff --git a/instalar-subir.sh b/instalar-subir.sh index 186ae4a..82ff037 100755 --- a/instalar-subir.sh +++ b/instalar-subir.sh @@ -1,143 +1,151 @@ #!/bin/bash +# ========================================================= +# Script: git-subir.sh +# Autor: Nahuel (adaptado con QA) +# Descripción: Automatiza commits y pushes a Gitea con +# soporte de credenciales cifradas. +# ========================================================= -echo "🚀 Instalando comando git subir..." +CONFIG="$HOME/.config/git-subir.conf" -# Solicitar datos -read -p "👤 Usuario de Gitea: " USUARIO -read -s -p "🔑 Token o contraseña: " TOKEN -echo "" -read -p "🌐 URL base de la API de Gitea: " API_BASE - -# Verificar credenciales antes de cifrar -ENDPOINTS=("$API_BASE/user" "$API_BASE/api/v1/user") -ENDPOINT_VALIDO="" -for URL in "${ENDPOINTS[@]}"; do - RESP=$(curl -s -o /dev/null -w "%{http_code}" -u "$USUARIO:$TOKEN" "$URL") - echo "🔍 Probando $URL → Código: $RESP" - if [ "$RESP" == "200" ]; then - ENDPOINT_VALIDO="$URL" - break - fi -done - -if [ -z "$ENDPOINT_VALIDO" ]; then - echo "❌ Error de autenticación. No se encontró endpoint válido." - exit 1 +# Cargar configuración si existe +if [[ -f "$CONFIG" ]]; then + source "$CONFIG" fi -echo "✅ Autenticación exitosa con $ENDPOINT_VALIDO" - -# Crear carpeta segura -CONFIG_DIR="$HOME/.config/git-subir" -mkdir -p "$CONFIG_DIR" - -# Preguntar si desea cifrar -read -p "🔐 ¿Querés cifrar las credenciales? (s/n): " CIFRAR -if [[ "$CIFRAR" == "s" ]]; then - read -s -p "🔑 Contraseña para cifrado: " CLAVE - echo "" - echo "$USUARIO:$TOKEN:$API_BASE" | openssl enc -aes-256-cbc -pbkdf2 -salt -out "$CONFIG_DIR/credenciales.enc" -pass pass:"$CLAVE" -else - echo "$USUARIO:$TOKEN:$API_BASE" > "$CONFIG_DIR/credenciales.txt" -fi - -# Crear script git-subir -cat > "$CONFIG_DIR/git-subir" <<'EOF' -#!/bin/bash - -CONFIG_DIR="$HOME/.config/git-subir" - -# 🔐 Cargar credenciales -if [ -f "$CONFIG_DIR/credenciales.enc" ]; then - read -s -p "🔑 Ingresá la contraseña de cifrado: " CLAVE - echo "" - CREDS=$(openssl enc -aes-256-cbc -pbkdf2 -d -in "$CONFIG_DIR/credenciales.enc" -pass pass:"$CLAVE" 2>/dev/null) - if [ -z "$CREDS" ]; then - echo "❌ Error al descifrar credenciales." - exit 1 - fi -else - CREDS=$(cat "$CONFIG_DIR/credenciales.txt") -fi - -USUARIO=$(echo "$CREDS" | cut -d: -f1) -TOKEN=$(echo "$CREDS" | cut -d: -f2) -API_BASE=$(echo "$CREDS" | cut -d: -f3) - -# 🔁 Reconfigurar credenciales -if [[ "$1" == "--reconfigurar" ]]; then - read -p "👤 Nuevo usuario: " USUARIO - read -s -p "🔑 Nuevo token: " TOKEN - echo "" - read -p "🌐 Nueva URL base: " API_BASE - read -p "🔐 ¿Cifrar credenciales? (s/n): " CIFRAR - if [[ "$CIFRAR" == "s" ]]; then - read -s -p "🔑 Contraseña para cifrado: " CLAVE - echo "" - echo "$USUARIO:$TOKEN:$API_BASE" | openssl enc -aes-256-cbc -pbkdf2 -salt -out "$CONFIG_DIR/credenciales.enc" -pass pass:"$CLAVE" - rm -f "$CONFIG_DIR/credenciales.txt" - else - echo "$USUARIO:$TOKEN:$API_BASE" > "$CONFIG_DIR/credenciales.txt" - rm -f "$CONFIG_DIR/credenciales.enc" - fi - echo "✅ Credenciales reconfiguradas." - exit 0 -fi - -# 📂 Verificar si estamos en un repo -git rev-parse --is-inside-work-tree &>/dev/null || { - echo "❌ No estás en un repositorio Git." - exit 1 -} - -# 🧼 Detectar si el repo está vacío -git rev-parse HEAD &>/dev/null -if [ $? -ne 0 ]; then - echo "📁 El repositorio está vacío." - read -p "¿Querés crear README.md inicial? (s/n): " RESP - if [[ "$RESP" == "s" ]]; then - touch README.md - git add README.md - git commit -m "Commit inicial por git subir" - fi -fi - -# 🌐 Verificar remote origin -git remote -v | grep origin >/dev/null || { - read -p "🌐 No hay remote origin. Ingresá URL del remote: " REMOTE - git remote add origin "$REMOTE" -} - -# 📦 Detectar cambios sin commitear -if ! git diff-index --quiet HEAD --; then - echo "📦 Hay cambios sin commitear." - read -p "¿Querés hacer commit automático? (s/n): " RESP - if [[ "$RESP" == "s" ]]; then - git add . - git commit -m "Commit automático por git subir" - fi -fi - -# 🚀 Intentar push -echo "🚀 Ejecutando git push..." -git push -if [ $? -ne 0 ]; then - echo "⚠️ Push falló. Intentando git pull y reintento..." - git pull --rebase - git push -fi +guardar_config() { + mkdir -p "$(dirname "$CONFIG")" + cat > "$CONFIG" <> "$SHELL_RC" + read -p "🔐 ¿Querés cifrar las credenciales? (s/n): " cifrar + if [[ "$cifrar" == "s" ]]; then + read -s -p "🔑 Contraseña para cifrado: " pass + echo "" + CRED=$(echo -n "$usuario:$token" | openssl enc -aes-256-cbc -a -pbkdf2 -pass pass:"$pass") + else + CRED="$usuario:$token" + fi -echo "✅ Instalación completa. Usá 'git subir' desde cualquier repositorio." + guardar_config + echo "✅ Reconfiguración completa." + exit 0 +fi + +# --------------------------------------------------------- +# Cambiar la clave de cifrado +# --------------------------------------------------------- +if [[ "$1" == "--cambiar-clave" ]]; then + echo "🔐 Cambiando contraseña de cifrado..." + if [[ -z "$CRED" ]]; then + echo "⚠️ No hay credenciales guardadas. Abortando." + exit 1 + fi + + read -s -p "🔑 Contraseña actual: " oldpass + echo "" + cred_descifrada=$(echo "$CRED" | openssl enc -aes-256-cbc -a -d -pbkdf2 -pass pass:"$oldpass" 2>/dev/null) + + if [[ -z "$cred_descifrada" ]]; then + echo "❌ Contraseña incorrecta. Abortando." + exit 1 + fi + + read -s -p "🔑 Nueva contraseña: " newpass + echo "" + CRED=$(echo -n "$cred_descifrada" | openssl enc -aes-256-cbc -a -pbkdf2 -pass pass:"$newpass") + + guardar_config + echo "✅ Contraseña de cifrado actualizada." + exit 0 +fi + +# --------------------------------------------------------- +# Descifrar credenciales si están cifradas +# --------------------------------------------------------- +if [[ "$CRED" =~ ^[A-Za-z0-9+/=]+$ ]]; then + read -s -p "🔑 Contraseña para descifrado: " pass + echo "" + descifrado=$(echo "$CRED" | openssl enc -aes-256-cbc -a -d -pbkdf2 -pass pass:"$pass" 2>/dev/null) + if [[ -n "$descifrado" ]]; then + CRED="$descifrado" + fi +fi + +usuario=$(echo "$CRED" | cut -d: -f1) +token=$(echo "$CRED" | cut -d: -f2) + +# Validar URL +if [[ -z "$URL" ]]; then + echo "❌ No se encontró la URL de Gitea en la configuración." + exit 1 +fi + +echo "📤 Subiendo cambios como $usuario a $URL..." + +# --------------------------------------------------------- +# Verificar si es repo git +# --------------------------------------------------------- +if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then + echo "📁 No estás en un repositorio git. Inicializando..." + git init + read -p "🌐 URL del remoto origin: " remote_url + git remote add origin "$remote_url" +fi + +# --------------------------------------------------------- +# Detectar cambios sin commitear +# --------------------------------------------------------- +if [[ -n "$(git status --porcelain)" ]]; then + echo "📦 Hay cambios sin commitear." + read -p "❓ ¿Querés escribir un mensaje de commit? (s/n): " respuesta + if [[ "$respuesta" == "s" ]]; then + mensaje="" + while [[ -z "$mensaje" ]]; do + read -p "📝 Ingresá el mensaje de commit: " mensaje + done + git add -A + git commit -m "$mensaje" + else + git add -A + git commit -m "Auto-commit" + echo "✅ Commit automático generado." + fi +else + echo "✅ No hay cambios pendientes. Continuando con el push..." +fi + +# --------------------------------------------------------- +# Push con verificación de upstream +# --------------------------------------------------------- +branch=$(git rev-parse --abbrev-ref HEAD) +remote=$(git config --get branch.$branch.remote) + +if [[ -z "$remote" ]]; then + echo "⚠️ La rama '$branch' no tiene remoto configurado." + echo "👉 Ejecutando: git push --set-upstream origin $branch" + git push --set-upstream origin "$branch" || { echo "❌ Falló el push."; exit 1; } +else + git push || { echo "❌ Falló el push."; exit 1; } +fi diff --git a/test-subir.sh b/test-subir.sh new file mode 100644 index 0000000..c0af0fc --- /dev/null +++ b/test-subir.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +echo "🔍 Verificando instalación de git-subir..." + +# Verificar si el comando está disponible +if ! command -v git-subir &> /dev/null; then + echo "❌ El comando 'git-subir' no está disponible en el PATH." + echo "👉 Asegurate de que ~/.local/bin esté en el PATH y que el script esté instalado." + exit 1 +fi + +echo "✅ Comando 'git-subir' disponible." + +# Verificar si estamos en un repositorio git +if ! git rev-parse --is-inside-work-tree &> /dev/null; then + echo "❌ No estás dentro de un repositorio git." + exit 1 +fi + +# Verificar upstream +BRANCH=$(git rev-parse --abbrev-ref HEAD) +UPSTREAM=$(git rev-parse --symbolic-full-name --verify --quiet "@{u}") + +if [ -z "$UPSTREAM" ]; then + echo "⚠️ La rama '$BRANCH' no tiene upstream configurado." + echo "👉 Se recomienda ejecutar: git push --set-upstream origin $BRANCH" +else + echo "✅ Upstream configurado: $UPSTREAM" +fi + +# Verificar credenciales +CONFIG_DIR="$HOME/.config/git-subir" +if [ -f "$CONFIG_DIR/credenciales.enc" ]; then + echo "🔐 Credenciales cifradas detectadas." +elif [ -f "$CONFIG_DIR/credenciales.txt" ]; then + echo "🔐 Credenciales en texto plano detectadas." +else + echo "❌ No se encontraron credenciales en $CONFIG_DIR" + exit 1 +fi + +echo "✅ Instalación verificada correctamente."