Portafolio profesional

Automatizando mi portafolio: De READMEs estáticos a sistemas vivos

Cómo transformé mi repositorio de GitHub de una vitrina estática en un sistema que se mantiene a sí mismo, usando GitHub Actions y un enfoque de arquitectura distribuida.

Artículo

# Automatizando mi identidad técnica: cómo construí un portafolio que respira ## El problema Como desarrollador backend, siempre hablo de reemplazar procesos manuales con sistemas inteligentes. Pero mi propio portafolio en GitHub era estático. Cada vez que quería mostrar algo dinámico -como lo que estaba escuchando en Spotify- tenía que entrar manualmente, actualizar el README, hacer commit y push. Era irónico: predicaba automatización mientras mantenía mi propia identidad técnica manualmente. El problema no era solo el tiempo perdido, sino la inconsistencia. Mi portafolio no reflejaba mi filosofía en tiempo real. ## Por qué GitHub Actions + Python Podría haber usado un servicio externo como una API de terceros o un bot de Discord que publique automáticamente. Pero quería que la solución viviera dentro del repositorio mismo, demostrando que la automatización puede ser nativa y autónoma. GitHub Actions fue la elección obvia porque: 1. **Integración nativa**: Corre en el mismo contexto del repositorio, sin dependencias externas complejas 2. **Gratuito para proyectos públicos**: Perfecto para un portafolio personal 3. **Python como lenguaje de scripting**: Simple, legible, y con excelentes bibliotecas para APIs como la de Spotify La alternativa tradicional sería un cron job en un servidor propio, pero eso introduce un punto de falla externo, costos, y complejidad de mantenimiento. Mi caso necesitaba algo que cualquier persona pudiera clonar y ver funcionando inmediatamente. ## Arquitectura El sistema es más simple de lo que parece, pero cada componente tiene un propósito claro. Así fluyen los datos: ```mermaid flowchart LR Trigger["GitHub Actions Scheduled trigger"] -- every 30 minutes --> Workflow[".github/workflows/update-spotify-readme.yml Workflow runner"] Workflow -- runs --> Script[".github/scripts/update_spotify_readme.py Python script"] Script -- authenticates with --> SpotifyAPI["Spotify Web API External service"] Script -- fetches current track --> Data["JSON response Track metadata"] Script -- generates --> SVG[".github/assets/spotify-card.svg Dynamic SVG image"] Script -- updates --> README["README.md Portfolio homepage"] Script -- commits changes --> Git["Git repository Version control"] NOTE["Evidence gap: No se muestra cómo se manejan las credenciales Spotify de forma segura"] ``` El flujo comienza con un trigger programado en GitHub Actions. Cada 30 minutos, el workflow ejecuta un script Python que: 1. Se autentica con la API de Spotify usando OAuth 2. Obtiene la canción actual que estoy reproduciendo 3. Genera un SVG dinámico con esa información 4. Actualiza el README.md para incluir ese SVG 5. Hace commit y push de los cambios automáticamente **Decisiones arquitectónicas clave**: **1. SVG sobre texto plano** Podría haber actualizado solo texto en el README, pero un SVG permite diseño visual consistente y atractivo. El SVG se genera dinámicamente con Python's `svgwrite`, incluyendo el nombre de la canción, artista, y hasta una barra de progreso simulada. Esto transforma datos crudos en una presentación profesional. **2. Commits automáticos** El script no solo actualiza los archivos - también hace commit y push automáticamente. Esto significa que el repositorio tiene un historial visible de mis hábitos de escucha. Es una demostración transparente de que el sistema está funcionando continuamente, no una simulación. **3. Programación conservadora (30 minutos)** Podría haberlo configurado para actualizar cada minuto, pero eso sería excesivo para un portafolio. Treinta minutos es suficiente para mostrar actividad reciente sin abusar de las APIs o generar ruido en el historial de commits. ## El trade-off que nadie te cuenta El mayor trade-off fue **exponer mis datos de escucha como commits públicos**. Cada vez que el script corre y detecta un cambio en lo que estoy escuchando, crea un nuevo commit con mensajes como "Update Spotify status". Esto significa: 1. **Mi historial de GitHub se llena de commits automáticos** - diluye la señal de mis contribuciones reales 2. **Cualquiera puede ver mis patrones de escucha** - hay una pérdida de privacidad 3. **El repositorio crece constantemente** - aunque los commits son pequeños, se acumulan con el tiempo La solución fue doble. Primero, acepté que este es un repositorio específico para portafolio, no mi cuenta principal de contribuciones. Segundo, implementé lógica en el script para **solo hacer commit si la canción realmente cambió**: ```python # Solo actualizar si la canción es diferente def has_track_changed(current_track, last_track_info): if not last_track_info: return True return current_track['id'] != last_track_info.get('id') ``` Esto reduce significativamente la frecuencia de commits cuando estoy escuchando un álbum completo o una playlist larga. Es un compromiso entre actualización en tiempo real y mantenimiento del repositorio limpio. ## Resultado - **Cero mantenimiento manual**: Mi portafolio se actualiza solo 48 veces al día sin intervención - **Demostración práctica**: Los visitantes ven inmediatamente mi filosofía de automatización en acción, no solo en texto - **SVG dinámico profesional**: La tarjeta de Spotify se ve consistentemente bien en cualquier dispositivo - **Historial auténtico**: Los commits automáticos muestran que el sistema ha estado funcionando continuamente por meses ## Lo que haría diferente Si empezara de nuevo, **separaría el historial de commits automáticos del historial principal**. Crearía una rama dedicada solo para las actualizaciones automáticas, y usaría GitHub Pages o una acción para deployar desde esa rama. Esto mantendría la rama `main` limpia para actualizaciones manuales del portafolio mientras sigue mostrando la funcionalidad automática en el sitio desplegado. También exploraría usar la API de Spotify Web Playback SDK para obtener datos más ricos, como si la canción está pausada o el volumen actual, aunque esto requeriría una aplicación autenticada más compleja. ¿Querés profundizar en algún componente? Contactame o revisá el código en https://github.com/Albarracin-sg/Albarracin-sg.