Firebase deploy GitLab CI

Una parte importante de nuestros desarrollos es realizar el despliegue a producción o ambientes de pruebas. Para esto, contamos con la ayuda de CI (Continuous Integration), que nos permite integrar cambios de código y preparar el proyecto para el despliegue en producción. También contamos con CD (Continuous Delivery), que nos permite automatizar el despliegue a producción. Con la llegada de GitHub Actions, este trabajo es menos complejo, lo que hace que esta integración sea cada día más común. Sin embargo, también utilizamos GitLab para alojar nuestros repositorios y tener el control del despliegue.

Como ejercicio, me propuse hacer esta integración. Leyendo la documentación y buscando información al respecto, llegué al resultado esperado para mí en este ejercicio. Principalmente, me enfoqué en hacer el despliegue en Firebase del front-end de la aplicación, por lo que me centraré principalmente en Firebase.

Proyecto en firebase ci-ejemplo

Documentación oficial de GitLab CI/CD

Vamos a crear el archivo .gitlab-ci.yml tal como se debe llamar, y creamos las tareas que queremos ejecutar. Estas tareas se llaman stages. En primer lugar, necesitamos instalar las dependencias.

stages:
 - install

install-dependencies:
  stage: install
  script:
    - npm ci
    - echo "Install successfully!"
  only:
    - main
  cache:
    paths:
      - node_modules
    key: 
      files:
        - package-lock.json
      prefix: npm

Para que el stage: install se ejecute, debemos nombrarlo igual que en la definición stages: -install. A continuación, describiré brevemente los pasos que estamos realizando.

  • install-dependencies: Nombre del stage que aparece en el runner de GitLab.
  • stage: Nombre del paso que se va a ejecutar.
  • script: Los scripts que necesitamos ejecutar, en este caso npm ci
  • only: Aquí podemos definir cuándo se empezará a ejecutar el runner. En este caso, en la rama main pero hay muchas más opciones.
  • cache: Podemos guardar en caché para su uso posterior en otro stage. Aquí se está cacheando node_modules, que se necesita para otros stages como test, lint y deploy. También se está cacheando el archivo package-lock.json para que las versiones sean correctas.

Ahora agregaremos los stages de lint, test, build y deploy. Cada uno se ejecutará en su orden.

stages:
  - install
  - lint
  - test 
  - build
  - deploy-firebase

En el despliegue en Firebase, necesitamos hacer lo siguiente previamente:

  1. Instalar Firebase CLI: npm install -g firebase-tools
  2. Ejecutar firebase init hosting. Esto creará el archivo firebase.json necesario para el despliegue.
{
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}
  1. Ejecutar firebase login:ci para iniciar sesión en Firebase, seleccionar el proyecto donde se va a desplegar la aplicación (previamente creado en la consola de Firebase). Esto generará un token y una línea que debe agregarse al archivo .gitlab-ci.yml.
✔  Success! Use this token to login on a CI server:

1//01LQsa808iTKSNwF-L9IrQ1VXTX_XWHLrfjbk_zn3X8mtsX5SiNMcruJV_DKFXfhjshufsyzTnRISFkj9E3K7iRu7xo

Example: firebase deploy --token "$FIREBASE_TOKEN"
  1. Agregas esta línea y creas la variable $FIREBASE_TOKEN en GitLab > Configuración > CI/CD > Variables. Con esto, estamos listos para completar el stage que nos permitirá hacer el deploy desde CI.
deploy:
  stage: deploy-firebase
  only: 
    - main
  before_script:
    - npm install
    - npm install -g firebase-tools
  script:
    - firebase deploy --token "$FIREBASE_TOKEN"
variables:
  FIREBASE_TOKEN: $CI_JOB_TOKEN
  VITE_API_URL: $API_URL
  1. Si tienes variables de entorno, también debes agregarlas en GitLab y en el archivo de CI, al igual que la variable $FIREBASE_TOKEN. El archivo .gitlab-ci.yml listo para usar queda así:
default:
  image: node:16

stages:
  - install
  - lint
  - test 
  - build
  - docker-build
  - deploy-firebase

install-dependencies:
  stage: install
  script:
    - npm ci
    - echo "Install successfully!"
  only:
    - main
  cache:
    paths:
      - node_modules
    key: 
      files:
        - package-lock.json
      prefix: npm

run-lint:
  stage: lint
  needs: ["install-dependencies"]
  script:
    - npm install
    - npm run lint
  only:
    - main
  cache:
    paths:
      - node_modules
    policy: pull

run-test:
  stage: test
  needs: ["install-dependencies"]
  script:
    - npm install
    - echo "Test successfully!"
  only:
    - main
  cache:
    paths:
      - node_modules
    policy: pull

build-app: 
  stage: build
  needs: ["install-dependencies", "run-test"]
  script:
    - npm install
    - npm run build
    - cp -a dist/. public/
    - echo "Build successfully!"
  only:
   - main
  cache:
    paths:
      - node_modules
    policy: pull
  artifacts:
    paths:
      - public

deploy:
  stage: deploy-firebase
  only: 
    - main
  before_script:
    - npm install
    - npm install -g firebase-tools
  script:
    - firebase deploy --token "$FIREBASE_TOKEN"
variables:
  FIREBASE_TOKEN: $CI_JOB_TOKEN
  VITE_API_URL: $API_URL

En resumen, este proceso de despliegue en Firebase mediante GitLab CI nos proporciona una solución robusta y eficiente para llevar nuestros proyectos a producción y a entornos de pruebas de manera automatizada. A través de la integración continua y la entrega continua, podemos asegurarnos de que los cambios en nuestro código se integren de manera suave y se desplieguen correctamente, reduciendo los posibles errores y garantizando una experiencia de usuario fluida.

En futuros ejercicios inentare hacer el depliegue en aws, google cloud, azure, por nombrar algunos.

Saludos!!