Guía para crear un pipeline GitLab CI/CD para aplicaciones Angular en un monorepo NX

Guía para crear un pipeline GitLab CI/CD para aplicaciones Angular en un monorepo NX
Photo by James Baltz / Unsplash

A continuación una guía paso a paso para crear un pipeline que permita desplegar aplicaciones Angular a diferentes directorios mediante SSH/FTP.

Paso 1: Crear la estructura base del pipeline

Primero, crea un archivo .gitlab-ci.yml en la raíz de tu proyecto NX:

# .gitlab-ci.yml
stages:
  - build
  - deploy

variables:
  NX_BRANCH: $CI_COMMIT_REF_NAME
  NX_RUN_GROUP: $CI_PIPELINE_ID

Paso 2: Crear scripts de despliegue

Crea una carpeta scripts en la raíz del proyecto y añade dos archivos:

  1. deploy-ssh.sh para despliegue por SSH
  2. deploy-ftp.sh para despliegue por FTP

Paso 3: Implementar el script SSH

En deploy-ssh.sh:

#!/bin/bash
set -e

# Parámetros requeridos
APP_NAME=$1
BUILD_DIR=$2
REMOTE_USER=$3
REMOTE_HOST=$4
REMOTE_DIR=$5
SSH_PRIVATE_KEY=$6

# Comprobación de parámetros
if [ -z "$APP_NAME" ] || [ -z "$BUILD_DIR" ] || [ -z "$REMOTE_USER" ] || [ -z "$REMOTE_HOST" ] || [ -z "$REMOTE_DIR" ]; then
  echo "Error: Faltan parámetros requeridos"
  echo "Uso: $0 app_name build_dir remote_user remote_host remote_dir [ssh_private_key]"
  exit 1
fi

# Configurar SSH si se proporciona una clave privada
if [ ! -z "$SSH_PRIVATE_KEY" ]; then
  mkdir -p ~/.ssh
  echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
  chmod 600 ~/.ssh/id_rsa
  ssh-keyscan -H "$REMOTE_HOST" >> ~/.ssh/known_hosts
fi

# Desplegar al servidor remoto
echo "Desplegando $APP_NAME a $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR..."
ssh $REMOTE_USER@$REMOTE_HOST "mkdir -p $REMOTE_DIR"
rsync -avz --delete $BUILD_DIR/ $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR

echo "Despliegue de $APP_NAME completado con éxito."

Paso 4: Implementar el script FTP

En scripts/deploy-ftp.sh:

#!/bin/bash
set -e

# Parámetros requeridos
APP_NAME=$1
BUILD_DIR=$2
FTP_USER=$3
FTP_PASSWORD=$4
FTP_HOST=$5
REMOTE_DIR=$6

# Comprobación de parámetros
if [ -z "$APP_NAME" ] || [ -z "$BUILD_DIR" ] || [ -z "$FTP_USER" ] || [ -z "$FTP_HOST" ] || [ -z "$REMOTE_DIR" ]; then
  echo "Error: Faltan parámetros requeridos"
  echo "Uso: $0 app_name build_dir ftp_user ftp_password ftp_host remote_dir"
  exit 1
fi

# Crear archivo de configuración temporal para lftp
LFTP_CONF=$(mktemp)
echo "set ssl:verify-certificate no" > $LFTP_CONF

# Desplegar al servidor FTP
echo "Desplegando $APP_NAME a $FTP_HOST:$REMOTE_DIR..."
lftp -c "
open ftp://$FTP_USER:$FTP_PASSWORD@$FTP_HOST
mirror -R $BUILD_DIR $REMOTE_DIR
bye
"

rm -f $LFTP_CONF
echo "Despliegue de $APP_NAME completado con éxito."

Paso 5: Crear plantillas para la compilación y despliegue

Crea una carpeta ci/templates y añade dos archivos:

  1. En ci/templates/build.gitlab-ci.yml:
.build:
  stage: build
  image: node:18
  script:
    - npm ci
    - npx nx build ${APP_NAME} --configuration=production
  artifacts:
    paths:
      - dist/apps/${APP_NAME}
    expire_in: 1 day
  1. En ci/templates/deploy.gitlab-ci.yml:
.deploy-ssh:
  stage: deploy
  image: node:18
  needs:
    - job: build-${APP_NAME}
      artifacts: true
  before_script:
    - apt-get update && apt-get install -y rsync openssh-client
    - chmod +x ./scripts/deploy-ssh.sh
  script:
    - ./scripts/deploy-ssh.sh ${APP_NAME} dist/apps/${APP_NAME}/browser ${DEPLOY_USER} ${DEPLOY_HOST} ${DEPLOY_PATH}/${APP_NAME} ${SSH_PRIVATE_KEY}
  environment:
    name: production/${APP_NAME}
    url: https://${DEPLOY_URL}/${APP_NAME}

.deploy-ftp:
  stage: deploy
  image: node:18
  needs:
    - job: build-${APP_NAME}
      artifacts: true
  before_script:
    - apt-get update && apt-get install -y lftp
    - chmod +x ./scripts/deploy-ftp.sh
  script:
    - ./scripts/deploy-ftp.sh ${APP_NAME} dist/apps/${APP_NAME}/browser ${FTP_USER} ${FTP_PASSWORD} ${FTP_HOST} ${FTP_PATH}/${APP_NAME}
  environment:
    name: production/${APP_NAME}
    url: https://${DEPLOY_URL}/${APP_NAME}

Paso 6: Configurar los trabajos específicos para cada aplicación

Crea una carpeta ci/apps y añade un archivo por cada aplicación. Por ejemplo, para app-uno:

En ci/apps/app-uno.gitlab-ci.yml:

build-brewermap:
  extends: .build
  variables:
    APP_NAME: app-uno

deploy-brewermap:
  extends: .deploy-ssh  # O .deploy-ftp según necesites
  variables:
    APP_NAME: app-uno
  # Las variables DEPLOY_* se definirán en GitLab CI/CD variables

Paso 7: Incluir todos los archivos en el archivo principal

Actualiza el archivo .gitlab-ci.yml para incluir todos los archivos:

stages:
  - build
  - deploy

variables:
  NX_BRANCH: $CI_COMMIT_REF_NAME
  NX_RUN_GROUP: $CI_PIPELINE_ID

include:
  - local: 'ci/templates/build.gitlab-ci.yml'
  - local: 'ci/templates/deploy.gitlab-ci.yml'
  - local: 'ci/apps/app-uno.gitlab-ci.yml'
  - local: 'ci/apps/map-app.gitlab-ci.yml'
  - local: 'ci/apps/other-app.gitlab-ci.yml'
  # Incluye el resto de tus aplicaciones

Paso 8: Configurar las variables en GitLab

En GitLab, ve a Settings > CI/CD > Variables y añade:

Para SSH:

  • DEPLOY_USER - Usuario SSH
  • DEPLOY_HOST - Host SSH
  • DEPLOY_PATH - Directorio base en el servidor
  • DEPLOY_URL - URL base para acceder a las aplicaciones
  • SSH_PRIVATE_KEY - Clave SSH privada (variable protegida y enmascarada)

Para FTP:

  • FTP_USER - Usuario FTP
  • FTP_PASSWORD - Contraseña FTP (variable protegida y enmascarada)
  • FTP_HOST - Host FTP
  • FTP_PATH - Directorio base en el servidor FTP
  • DEPLOY_URL - URL base para acceder a las aplicaciones

Paso 9: Personalizar la configuración para cada aplicación

Para personalizar la configuración de cada aplicación, puedes modificar sus respectivos archivos en ci/apps/. Por ejemplo, puedes cambiar la ruta de despliegue o usar diferentes métodos de despliegue.

Paso 10: Configurar el trigger del pipeline

Por defecto, el pipeline se ejecutará en cada push. Si quieres cambiarlo, puedes añadir reglas en tu .gitlab-ci.yml:

workflow:
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: always
    - if: $CI_COMMIT_BRANCH == "develop"
      when: always
    - when: manual

Subscribe to OssprO Blog

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe