Deploy automático con GitHub Actions

Con GitHub Actions, un archivo YAML en .github/workflows se ejecuta en cada push y hace el deploy por ti. Guardas las credenciales en secrets y eliges qué ramas disparan el flujo.

Actualizado el 7 min de lectura

Objetivos de aprendizaje

Después de leer este artículo podrás:

  • Crear un workflow que haga deploy en cada push a la rama principal
  • Guardar tokens y claves de API en secrets sin exponerlos en el código
  • Ejecutar pruebas antes del deploy y comprobar que funcionó
En esta página

Hacer el deploy a mano funciona las primeras veces: comprimes la carpeta, la subes, reinicias. Con el tiempo, el paso manual se vuelve el punto donde alguien olvida ejecutar las pruebas, sube la carpeta equivocada o deja el servidor en una versión vieja.

GitHub Actions resuelve esto llevando el deploy al propio repositorio. Un archivo de texto describe qué pasa en cada push, y GitHub ejecuta los pasos en una máquina temporal. Si el concepto de deploy todavía es nuevo para ti, empieza por qué es un deploy.

DEPLOY_TOKENpushramamaintestjob depruebasdeployneeds: testServidornueva versiónen líneaLas pruebas fallanel job de deploy se omite
El push a main ejecuta las pruebas; solo si pasan, el job de deploy usa el secret y pone la nueva versión en línea.

¿Cómo funciona el deploy automático con GitHub Actions?#

Un workflow es un archivo YAML guardado en .github/workflows/ dentro del repositorio. Declara:

  • Disparadores (on): lo que inicia la ejecución, como un push, la publicación de una release o un clic manual.
  • Jobs: bloques de trabajo. Cada job se ejecuta en una máquina virtual propia, llamada runner.
  • Steps: los pasos de cada job. Un paso ejecuta un comando (run) o usa una acción lista (uses).

En el deploy automático, el disparador es el push a la rama principal y el último job envía el código al servidor. Todo lo que el job necesita (token, clave de API) viene de los secrets, nunca del código.

¿Qué necesitas antes de empezar?#

  • Un repositorio en GitHub con el proyecto.
  • Una aplicación ya creada en tu servidor o plataforma de hosting, para tener adónde enviar el código.
  • Una credencial que permita enviar código a ese destino (clave de API, token o clave SSH).
  • Un script o comando que haga el deploy desde la terminal. Si puedes hacer el deploy ejecutando un comando en tu máquina, puedes automatizarlo.

Prueba el comando de deploy en local antes de ponerlo en el workflow. Depurar el YAML y el deploy al mismo tiempo es mucho más lento.

¿Cómo crear el primer workflow, paso a paso?#

1. Crea el archivo. En el repositorio, crea .github/workflows/deploy.yml. El nombre del archivo es libre, pero la carpeta no.

2. Registra la credencial como secret. En GitHub, abre Settings > Secrets and variables > Actions, pestaña Secrets, y haz clic en New repository secret. Ponle un nombre, como DEPLOY_TOKEN, y pega el valor. Desde la línea de comandos, gh secret set DEPLOY_TOKEN pide el valor y lo guarda.

3. Escribe el workflow. Este ejemplo ejecuta las pruebas de un proyecto Node.js y solo después hace el deploy:

yaml
name: Deploy

on:
  push:
    branches: [main]
  workflow_dispatch:

concurrency:
  group: deploy-${{ github.ref }}
  cancel-in-progress: false

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-node@v7
        with:
          node-version: lts/*
      - run: npm ci
      - run: npm test

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - name: Enviar al servidor
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
        run: ./scripts/deploy.sh

4. Haz commit y push a main. El workflow aparece en la pestaña Actions del repositorio y empieza a ejecutarse.

El script scripts/deploy.sh es el comando que ya probaste en local. Cámbialo por lo que exija tu destino; cada plataforma tiene su camino: un rsync por SSH, una CLI propia o una acción oficial, como la de la sección final.

¿Cómo funciona cada parte del archivo?#

¿Qué rama dispara el deploy?#

branches: [main] limita el disparador de push a main. Un push a otra rama no dispara el deploy. Puedes listar más de una rama o usar patrones como release/**. No se pueden combinar branches y branches-ignore en el mismo evento.

¿Por qué usar workflow_dispatch?#

Agrega el botón Run workflow en la pestaña Actions. Sirve para repetir un deploy sin crear un commit nuevo, por ejemplo después de corregir una variable de entorno. El disparador solo funciona cuando el archivo existe en la rama por defecto del repositorio.

¿Para qué sirve concurrency?#

Sin él, dos push seguidos pueden iniciar dos deploys al mismo tiempo, y gana el que termine último, aunque sea el más antiguo. Con group, solo se ejecuta una corrida del grupo a la vez y, por defecto, si varias esperan, solo queda pendiente la más reciente. Mantén cancel-in-progress: false en los deploys: cancelar un envío a la mitad puede dejar la aplicación en un estado incompleto.

¿Qué hace needs?#

needs: test hace que el job de deploy espere al job de pruebas y solo se ejecute si pasa. Es la forma más simple de garantizar que el código roto no llegue a producción.

¿Qué versión de cada acción usar?#

Fija la versión principal, como actions/checkout@v7. Evita apuntar a @main: un cambio del autor de la acción puede alterar tu deploy sin aviso.

¿Cómo guardar tokens y claves con seguridad?#

Reglas que evitan la mayoría de los incidentes:

  • Nunca escribas la credencial en el YAML ni en el código. El archivo queda en el historial de Git. Si una clave llega ahí, considérala comprometida y mira qué hacer si se expone una clave de API en GitHub.
  • Usa ${{ secrets.NOMBRE }}. GitHub oculta el valor en los logs y lo reemplaza por asteriscos.
  • Los valores que no son secretos (como el ID de una aplicación) pueden ir en Variables, en la misma pantalla, y se usan como ${{ vars.NOMBRE }}.
  • Los secrets no llegan a los workflows disparados por forks. GitHub no los pasa al runner, lo que protege contra pull requests maliciosos.
  • Da el mínimo de permisos. Agrega permissions: contents: read al workflow cuando no necesite escribir en el repositorio.

Para la configuración de la aplicación en sí (base de datos, tokens del bot), sigue la misma lógica de las variables de entorno: el valor vive en el entorno, no en el repositorio.

¿Cómo saber si el deploy funcionó?#

  1. Abre la pestaña Actions y entra en la ejecución. Cada step tiene su log. Un check verde en todos los jobs significa que el comando terminó sin error.
  2. Confírmalo en el destino: ¿la aplicación se reinició? ¿Aparece el cambio? Un check verde solo dice que el comando salió con código 0, no que la aplicación arrancó.
  3. Lee los logs de la aplicación justo después del deploy (mira cómo leer los logs de una aplicación). Ahí aparecen los errores de variables que faltan o de dependencias no instaladas.

¿Cuáles son los errores más comunes?#

  • Secret vacío. Un nombre mal escrito en secrets.NOMBRE no genera error: la expresión devuelve una cadena vacía, y el comando falla después con un error de autenticación. Revisa el nombre donde registraste el secret.
  • Olvidar el checkout. El runner empieza vacío. Sin actions/checkout, no hay archivos que enviar.
  • Archivo en la carpeta equivocada. El workflow tiene que estar en .github/workflows/ en la raíz, con extensión .yml o .yaml.
  • Indentación del YAML. Dos espacios por nivel, sin tabulaciones. Un espacio de más cambia el significado o invalida el archivo.
  • El workflow no se dispara. Comprueba que el push fue a la rama listada en branches y que el archivo está en la rama que enviaste.
  • Un comando que pide confirmación. El runner no tiene una terminal interactiva. Los comandos que preguntan "¿estás seguro?" se quedan colgados o salen con error, así que usa la opción de confirmación automática del comando.
  • El deploy desde un fork no se ejecuta. Sin secrets, el job de deploy falla en los pull requests de forks. Haz el deploy solo en push, no en pull_request.

Cómo hacerlo en Square Cloud#

Si tu destino es Square Cloud, la GitHub Action oficial reemplaza a scripts/deploy.sh: ejecuta un comando de la CLI en cada push, release o ejecución manual. Mantén el job de pruebas y cambia solo el job de deploy:

yaml
  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: squarecloudofc/github-action@v2
        with:
          token: ${{ secrets.SQUARECLOUD_API_KEY }}
          command: commit ${{ vars.APP_ID }} --restart

La entrada token recibe la API key de tu cuenta, guardada en Secrets como describe esta guía, y el ID de la aplicación puede ir en Variables, porque no es un secreto. commit envía los archivos de la carpeta de trabajo (la entrada opcional workdir cambia cuál) y sobrescribe solo los que van en el envío; el resto del disco de la aplicación se queda como estaba. --restart reinicia la aplicación para que la nueva versión quede en línea. La plataforma no tiene paso de build: si tu proyecto compila, ejecuta el build en un step antes del commit.

Después del push, revisa los logs de la aplicación en el panel, como en la sección sobre verificar el deploy. El archivo squarecloud.app es opcional: el panel lo genera en el deploy, o lo escribes en la raíz del proyecto. Mira las entradas de la acción en GitHub Action y los comandos de la CLI.

Deploy

Sube desde GitHub, la CLI o un ZIP y publica en segundos

Más información

Preguntas frecuentes

¿GitHub Actions es gratis?

Depende del plan y del tipo de repositorio. GitHub incluye una cuota de minutos y cobra el excedente en algunos casos, así que revisa la página de facturación de GitHub Actions para tu caso.

¿Puedo usar secrets en pull requests de forks?

No. GitHub no pasa los secrets al runner cuando el workflow lo dispara un repositorio fork. Eso impide que un pull request de terceros lea tus credenciales.

¿Cómo disparo el deploy manualmente?

Agrega el disparador workflow_dispatch al bloque on. GitHub muestra entonces el botón Run workflow en la pestaña Actions, y el disparador solo funciona si el archivo está en la rama por defecto.

¿El deploy se ejecuta si fallan las pruebas?

No, si el job de deploy declara needs apuntando al job de pruebas. Cuando falla un job del que otro depende, el job dependiente se omite.

Siguiente artículo¿Cuánto cuesta hospedar una aplicación Node.js?Hospedar Node.js cuesta desde cero, con límites, hasta unos pocos dólares al mes. Mira qué define el precio, cuánta RAM usa tu app y cómo cobra cada opción.

Más en Deploy

Ver los 33 artículos