GatsbyJS en GitHub Pages con Azure DevOps
Siguiendo con el anterior post en el que construíamos un sitio estático con GatsbyJS, nos enfrentamos a desplegar el resultado de esta web en un nuevo sitio de GitHub Pages.
Para desplegar la aplicación, utilizaremos Azure DevOps, creando dos pipelines, uno para la integración continua (CI Continuous Integration) y otro para la entrega continua (CD Continuous Delivery).
Configurando el repositorio
El primer paso que debemos realizar es preparar el repositorio para activar y configurar GitHub Pages.
Creamos un nuevo branch llamado gh-pages
en el repositorio donde tenemos el sitio estático hecho con GatsbyJS.
Configuramos GitHub Pages en este repositorio desde la pestaña de settings.
Nota: Si tienes un Custom Domain ya agregado, GitHub Pages te sirve todos los sitios web desde el dominio que has configurado
Por último, necesitaremos configurar un PAT (Personal access token) con permisos sobre repo.
Almacenamos el token en un lugar seguro para utilizarlo más adelante.
Azure DevOps
En Azure DevOps debemos crear dos pipelines, el primero hará la build de la solución y generará un artefacto, el segundo utilizará este artefacto y lo publicará en la rama gh-pages
del repositorio en el que estamos trabajando.
Pipeline
Dentro del Team Project, en el menú seleccionamos el ítem Pipelines.
Creamos un nuevo pipeline y elegimos como origen GitHub.
Seleccionamos el repositorio que queremos publicar como sitio estático.
Al escoger el repositorio, deberemos configurar en GitHub el acceso que va a tener Azure Pipelines sobre nuestro repositorio. Tenemos dos opciones, dejar que tenga acceso a todos los repositorios, o dejar que sólo tenga acceso a los repositorios que seleccionemos.
Tras aprobar el acceso al repositorio, volvemos al pipeline, y lo configuramos para que utilice Node.js.
En el último paso nos encontramos con un fichero YAML, con el nombre preestablecido de azure-pipelines.yml y que se almacenará en el repositorio de GitHub.
Este fichero, viene por defecto con un trigger que se desencadenará cuando se consoliden cambios en master
, además realiza la instalación de Node.js, ejecuta la instalación de los paquetes npm y la compilación de la solución.
# Node.js
# Build a general Node.js project with npm.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '10.x'
displayName: 'Install Node.js'
- script: |
npm install
npm run build
displayName: 'npm install and build'
Actualizamos el código YAML que viene por defecto, modificando los pasos de la operativa para que instale el Gatsby-CLI
, y con yarn
instale las dependencias y haga la build de la solución.
# Build a GatsbyJS solution with npm and yarn.
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '10.x'
displayName: 'Install Node.js'
- script: |
npm install -g gatsby-cli
displayName: 'Install Gatsby-CLI'
- script: |
yarn install
displayName: 'Install dependencies'
- script: |
yarn build
displayName: 'Build'
En el lateral derecho, tenemos la posibilidad de utilizar el asistente, el cual nos permitirá cargar nuevos pasos dentro del YAML para completar el pipeline.
Agregamos dos pasos nuevos, el primero realizará la copia de los ficheros generados en la build. El segundo paso la publicación del resultado como artefacto.
Para la copia de los ficheros, agregamos la tarea de copia e indicamos que debe copiar los ficheros que se generan en la carpeta public al Build Artifact Staging Directory.
- task: CopyFiles@2
inputs:
sourceFolder: "public"
contents: "**"
targetFolder: "$(Build.ArtifactStagingDirectory)"
cleanTargetFolder: true
displayName: "Copy built site"
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
Tras la copia de ficheros, publicamos el resultado en el Staging Artifact Directory.
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: "$(Build.ArtifactStagingDirectory)"
ArtifactName: "drop"
publishLocation: "Container"
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
displayName: "Publish Build Artifacts"
Al finalizar las modificaciones, salvamos, establecemos el mensaje de commit
y automáticamente se lanzará un pipeline que generará los ficheros estáticos necesarios para un sitio web de GitHub Pages.
Una vez lanzado el pipeline, vemos el estado de la ejecución, y tenemos la posibilidad de ver los cambios o cancelar el propio pipeline.
Si pulsamos en el Job, podemos acceder al estado de la ejecución del pipeline y ver cómo va avanzando.
Tras ejecutarse el pipeline, si no ha habido ningún error tendremos un tick verde en el resultado del Job, e internamente, en los logs, todas las operaciones estarán Ok y habrá un artefacto generado.
Release
Accedemos al ítem Release, dentro del menú Pipelines.
Creamos una nueva Release Pipeline.
En pantalla se nos mostrará un workflow para configurar nuestro Release Pipeline
, por defecto Azure DevOps nos ofrece plantillas predefinidas con diversa funcionalidad para facilitar esta tarea. En nuestro caso, seleccionamos una plantilla vacía.
Establecemos un nombre al Stage, y vamos al bloque Artifacts
, dónde configuraremos el artefacto resultante de la pipeline que hemos creado en el punto anterior.
Después de agregarlo, configuramos el trigger que desencadenará la Release Pipeline
, pulsando en el símbolo del rayo del artefacto e indicamos la entrega continua con cada build que se produzca.
En el bloque de Stages
, accedemos al Stage que tenemos y pulsamos sobre el resumen de 1 job, 0 task.
En el job del agente agregamos una nueva tarea del tipo Publish to GitHub Pages y configuramos la tarea.
En primer lugar debemos establecer el origen de los documentos, en el apartado Documentation Source, examinamos y establecemos el resultado del artefacto
Una vez seleccionado el directorio, agregamos el wildcard /**
para que publique el contenido de la carpeta del artefacto y no la carpeta en sí, así evitaremos que la publicación agregue a nuestro sitio un subdirectorio con el nombre del drop.
A continuación completamos el resto de campos requeridos con las siguientes variables:
Name | Value |
---|---|
Documentation Source | $(System.DefaultWorkingDirectory)/DemoGatsbyJS/drop/** |
GitHub Username | $(UserName) |
GitHub Email Address | $(UserEmail) |
GitHub Personal Access Token | $(PAT) |
Repository Name | $(Repository) |
Branch Name | gh-pages |
Commit Message | Azure DevOps: Automated Release $(Release.ReleaseId) |
En la pestaña de Variables, agregamos las variables que estamos utilizando en la tarea, y el PAT lo marcamos como variable de tipo Secret.
Establecemos un nombre al Release Pipeline
, pinchando sobre el nombre actual, guardamos y pulsamos en Create release.
Accedemos a la Release creada, y una vez completado el proceso, si todo ha ido Ok, se mostrará un Succeeded en el Stage.
Si vamos al resultado del Stage, podemos ver que, como con las Pipeline, se puede visualizar los logs de lo que ha sucedido durante el proceso.
Finalmente en el navegador, si entramos al sitio estático de GitHub Pages, visualizaremos algo como esto.