Configurando CI/CD con Github Actions
Durante varios proyectos, cada despliegue implicaba conectarme al servidor, ejecutar el build, copiar archivos y verificar que todo funcionara correctamente. Repetir estos pasos manualmente en cada actualización aumentaba las posibilidades de olvidar algún paso o introducir inconsistencias entre staging y producción. GitHub Actions apareció como una alternativa para centralizar este proceso en un único workflow automático.
Un workflow automatizado ejecuta siempre la misma secuencia: instala dependencias, construye el proyecto, copia archivos de configuración y despliega al servidor correspondiente. Esto permite que los cambios lleguen al entorno correcto con la misma configuración en cada despliegue.
Creando las llaves SSH para el despliegue
Una forma práctica de permitir que GitHub Actions acceda al servidor es mediante autenticación SSH con pares de llaves. La clave pública se coloca en el servidor, mientras que la privada se guarda como secreto en el repositorio.
Generé el par de llaves desde mi máquina local con el siguiente comando:
ssh-keygen -t rsa -b 4096 -C "breve descripción" -f "C:/Users/santiago/.ssh/id_rsa_github_actions" Esto generó dos archivos:
id_rsa_github_actions(clave privada)id_rsa_github_actions.pub(clave pública)
La clave pública se copia en el archivo authorized_keys del servidor. La clave privada se guarda como secreto en el repositorio de GitHub.
Configuración de secretos en GitHub
La clave privada se carga en el repositorio desde:
Settings → Secrets and variables → Actions → New repository secret
Definí secretos separados para cada entorno:
STAGING_HOST,STAGING_USER,STAGING_SSH_KEYPROD_HOST,PROD_USER,PROD_SSH_KEY
Esto permite que el workflow acceda a las credenciales correspondientes según el entorno, sin exponer información sensible en el código.
Workflow basado en tags
El workflow unifica staging y producción en un único archivo YAML. La diferencia está en el sufijo del tag que se pushea:
*-staging→ despliega a staging*-prod→ despliega a producción
Cada job evalúa el sufijo del tag con endsWith(github.ref, '-staging') o endsWith(github.ref, '-prod') para determinar qué pasos ejecutar.
El workflow completo:
name: Deploy
on:
push:
tags:
- "*-staging"
- "*-prod"
jobs:
deploy-staging:
if: endsWith(github.ref, '-staging')
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Instalar Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Instalando dependencias
run: npm ci
- name: Build SvelteKit
run: npm run build
env:
VITE_ENVIRONMENT: staging
- name: Copiar .htaccess al build
run: cp .htaccess.staging build/.htaccess
- name: Copiar robots.txt para staging (bloquear bots)
run: cp static/robots.staging.txt build/robots.txt
- name: Deploy via SCP to STAGING
uses: appleboy/scp-[email protected]
with:
host: ${{ secrets.STAGING_HOST }}
username: ${{ secrets.STAGING_USER }}
key: ${{ secrets.STAGING_SSH_KEY }}
source: "build/*,build/.htaccess"
target: "/home/santiag1/hola.santiagocarranza.net.ar"
strip_components: 1
debug: true
deploy-prod:
if: endsWith(github.ref, '-prod')
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Instalar Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Instalando dependencias
run: npm ci
- name: Build SvelteKit
run: npm run build
env:
VITE_ENVIRONMENT: production
- name: Copiar .htaccess al build
run: cp .htaccess build/.htaccess
- name: Copiar robots.txt para producción (permitir bots)
run: cp static/robots.production.txt build/robots.txt
- name: Deploy via SCP to PRODUCTION
uses: appleboy/scp-[email protected]
with:
host: ${{ secrets.PRODUCTION_HOST }}
username: ${{ secrets.PRODUCTION_USER }}
key: ${{ secrets.PRODUCTION_SSH_KEY }}
source: "build/*,build/.htaccess"
target: "/home/santiag1/public_html"
strip_components: 1
debug: true Este enfoque centraliza la configuración de ambos entornos en un único archivo, evitando duplicar lógica y facilitando el mantenimiento del workflow.
Resultado
Automatizar los despliegues eliminó varios pasos que antes hacía manualmente. Ahora subo cambios con git push normalmente, y solo cuando quiero publicar creo un tag. El workflow ejecuta automáticamente el build, copia la configuración correspondiente y despliega al servidor según el entorno.
Lo uso en proyectos donde hay múltiples entornos o donde las actualizaciones son frecuentes. No es necesario en todos los casos, pero cuando necesito probar cambios en staging antes de llevarlos a producción, reduce bastante el margen de error.