Como automatizar el deployment de Next.JS en Github Pages

User icon Crysfel VillaCalendar icon Apr 4, 2023Calendar icondevops,programming

Como automatizar el deployment de Next.JS en Github Pages

Hace un par de semanas actualicé el diseño de este sitio, decidí usar Next.JS para generar todos los archivos HTML y CSS de manera estática, para luego ponerlos en GitHub pages. Todo mi contenido ahora está en Notion y soy muy feliz escribiendo.

En este tutorial te voy a mostrar como automatizar el deployment, la idea es usar GH Actions para hacer el build y correr los scripts que sacan la información de Notion. Tuve algunos problemas que me gustaría documentar por si le sirven a alguien más.

Creación del workflow

Lo primero es crear un archivo para el nuevo workflow en tu repositorio, este archivo lo vas a crear dentro del directorio .github/workflows, si este directorio no existe lo puedes crear. Puedes nombrar el archivo como deploy.yml pero realmente no importa el nombre.

Dentro de este archivo vas a definir tres secciones, el nombre (name) del workflow, el evento que lo inicializa (on), por ejemplo push al main branch y los jobs que se van a ejecutar.

Aquí está la configuración que yo he usado para mi proyecto. Es importante mencionar que los pasos van a variar dependiendo de cada proyecto.

name: Deploy to GitHub Pages
on:
  push:
    branches:
      - main
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '14.x'
      - name: Install dependencies
        run: npm install

La configuración anterior define un job llamado build-and-deploy que se ejecuta en una máquina Ubuntu con la última versión disponible.

Los pasos definidos son secuenciales y lo primero que hace es descargar el código de GitHub haciendo un checkout con git. Luego instala Node.js con la versión indicada, en este caso la versión 14. Por último instala las dependencias del proyecto.

Ejecutando scripts

Como ya mencioné antes, toda mi información de este blog está en Notion, por lo tanto cree dos scripts que se conectan al API Rest de Notion y descargan todos los posts publicados, también van descargando las imágenes asociadas a cada post y generando thumbnails para los posts.

Antes de generar el sitio estático con Next.js, necesito descargar la información y guardarla en archivos JSON que voy a usar en el build, para eso simplemente agrego los dos scripts al job que se definió en el paso anterior.

name: Deploy to GitHub Pages
on:
  push:
    branches:
      - main
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '14.x'
      - name: Install dependencies
        run: npm install
      - name: Download posts
        run: npm run blog
      - name: Download projects
        run: npm run projects

He definido estos scripts dentro del archivo package.json en mi proyecto, por lo tanto puedo usar npm para ejecutarlos.

Generar el sitio estático

Una vez que ya tengo toda la información en archivos JSON y las imágenes descargadas a la máquina Ubuntu donde estoy haciendo el build, ya puedo pasar al siguiente paso que es generar todos los archivos HTML y CSS.

name: Deploy to GitHub Pages
on:
  push:
    branches:
      - main
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '14.x'
      - name: Install dependencies
        run: npm install
      - name: Download posts
        run: npm run blog
      - name: Download projects
        run: npm run projects
      - name: Build
        run: npm run build
      - name: Export
        run: npm run export

Next.JS provee dos comandos para generar sitios estáticos, build y export. Así que simplemente agrego estos dos pasos al job y listo.

Deployment

El último paso es deployar el build a GitHub pages, lo único que tenemos que hacer es agregar este paso a la lista de jobs.

name: Deploy to GitHub Pages
on:
  push:
    branches:
      - main
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '14.x'
      - name: Install dependencies
        run: npm install
      - name: Download posts
        run: npm run blog
      - name: Download projects
        run: npm run projects
      - name: Build
        run: npm run build
      - name: Export
        run: npm run export
      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./out

Usamos un paquete ya predefinido, peaceiris/actions-gh-pages nos permite acceder al build, generar un nuevo commit y hacer un push al gh-pages branch, esto hará que el sitio sea actualizado.

Para poder hacer push, es necesario que le demos el token de github, esta es la llave del repositorio y se puede acceder mediante la variable de entorno secrets.GITHUB_TOKEN.

Otra cosa a considerar en esta configuración es el publish_dir, aquí tenemos que indicarle el directorio dónde está el build, en este caso Next.js pone todos los archivos generados dentro del folder out.

Variables de entorno

Dentro del código fuente, accedo a algunas variables de entorno, ahí tengo el Secret Key para el API de Notion, el número de posts por página y otras cosas más.

Las llaves de Notion no las quiero agregar al repositorio, por lo tanto debo usar variables de ambiente. GitHub te provee una manera de definir environments, cada uno puede tener diferentes valores, por ejemplo, podrías tener uno para staging y otro para production. En mi caso no requiero tener varios ambientes, así que solo voy a definir uno que se llama gh-pages.

Dentro del tab Settings > Environments de tu repositorio, podrás manejar estos ambientes. Una vez que crees tu ambiente, asegúrate de darle acceso al branch main para que se puedan usar estos valores en el build.

Aquí puedes definir todos tus llaves secretas en la sección Environment Secrets, con esto estamos listos para usar estas llaves en nuestro workflow.

Una vez que has definido tus valores secretos, queda solamente agregarlos a la configuración, aquí vamos a usar la propiedad environment para indicarle el nombre del ambiente que acabamos de crear con nuestros valores secretos.

Con esto el script podrá acceder a estas variables de entorno, pero estas variables realmente las necesitamos en el código fuente, por lo tanto debemos agregarlas al ambiente del build. Para esto usamos la propiedad env, aquí podemos acceder a los valores secretos y también definir valores de configuración para nuestros proyecto, por ejemplo aquí puse el número de posts por página, información que no es secreta.

El script final quedaría de la siguiente manera.

name: Deploy to GitHub Pages
on:
  push:
    branches:
      - main
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    environment: github-pages
    env:
      NOTION_PK: ${{ secrets.NOTION_PK }}
      NOTION_DB_ID: ${{ secrets.NOTION_DB_ID }}
      NEXT_PUBLIC_GA_MEASUREMENT_ID: "UA-12345-1"
      POST_PER_PAGE: "6"
    steps:
      - name: Checkout code
        uses: actions/checkout@v2
      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '16.x'
      - name: Install dependencies
        run: npm install
      - name: Blog Data
        run: npm run blog
      - name: Projects Data
        run: npm run projects
      - name: Build
        run: npm run build
      - name: Export
        run: npm run export
      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./out

¡Eso es todo! Cada vez que hagas un push al repositorio o merge a un PR al branch main, la acción se ejecutará de manera automática, haciendo que tu flujo de trabajo sea mucho más efectivo y automatizado.

Si quieres aprender más sobre Next.JS, te recomiendo el curso de mi amigo Armando, es un curso bastante completo donde vas a aprender cosas como integrar Stripe para recibir pagos, autenticación y manejo de sesiones, acceso a base de datos y muchas cosas más, en verdad que te lo recomiendo mucho.

Puedes usar mi cupón para tener un 20% de descuento en la compra del curso: CRYS20, también puedes dar click en el siguiente link: https://sendero.dev?promotion=CRYS20

Happy Coding!

Te ayudo a mejorar al entrevistar, únete a mi lista de correo.

Unirse

Te mando historias y consejos para mejorar tu carrera como Ingeniero de Software, también hablo sobre finanzas personales e inversiones.

Crysfel's Twitter accountCrysfel's Linkedin accountCrysfel's Youtube channel

También estoy en Youtube

Publico videos en Youtube de vez en cuando, suscríbete a mi canal.

©2023 ALL RIGHTS RESERVED CRYSFEL'S BLOG