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.