Integración Continua con Flutter y GitHub: Cómo publicar una aplicación en Firebase Hosting

0
4194
flutter github actions firebase

Anteriormente ya hablé sobre las acciones de GitHub, que nos permiten crear entornos de CI en los repositorios. Expliqué cómo crear una acción para poder reutilizarla en diferentes proyectos. Sin embargo, esta vez voy a crear un proyecto utilizando Flutter y, posteriormente, definiré un workflow de GitHub Actions para que se publique la versión web en Firebase Hosting.

  1. Introducción
  2. Entorno
  3. Crear una aplicación con Flutter
  4. Configurar el repositorio en GitHub
  5. Crear proyecto en Firebase
  6. Conectar el proyecto Flutter con Firebase
  7. Configurar la acción de GitHub
  8. Conclusiones

Introducción

Los flujos de trabajo de GitHub nos permiten configurar servicios de integración continua que podemos completar utilizando las acciones predefinidas. Con ellas podemos construir, testear y desplegar nuestras aplicaciones, entre otras muchas cosas.

En este caso, vamos a crear un proyecto utilizando Flutter. Después, utilizaremos una GitHub Action para instalar Flutter en nuestro entorno de integración continua para poder compilar nuestra aplicación a una versión web. Finalmente, desplegaremos el proyecto generado en Firebase Hosting.

Todo el código utilizado se puede consultar en el repositorio público utilizado en el tutorial.

Entorno

  • Hardware: Portátil MacBook Pro 15 (2,9 GHz Intel Core i7, 16GB 1600 MHz DDR3, 500GB Flash Storage)
  • GitHub y Github Actions
  • Flutter versión 2.0.4
  • Firebase y Firebase Hosting

Crear una aplicación con Flutter

El primer paso es crear una aplicación con Flutter. Si no tenemos Flutter instalado en nuestro ordenador, podemos seguir los pasos de su guía oficial. En este caso la vamos a crear utilizando Android Studio. Lo abrimos y pulsamos sobre «Create new Flutter project».

Android Studio create flutter project button

Elegimos «Flutter Application» entre las opciones y pulsamos a Next, rellenando los datos hasta que el proyecto se haya creado. Para este ejemplo se va a utilizar la versión de la aplicación que se genera automáticamente, es decir, no se va a cambiar nada del proyecto de Flutter.

Debemos ejecutar un comando para generar los ficheros de configuración de la versión web. Esto lo haremos ejecutando desde el terminal (el de Android Studio o desde un terminal normal) el siguiente comando:

flutter create .

Configurar el repositorio en GitHub

Abrimos GitHub y cremos un nuevo repositorio, con el nombre que queramos. Una vez lo hayamos creado, debemos subir la aplicación. Para eso, ejecutamos los siguientes comandos desde el terminal, en la ruta del proyecto, cambiando el enlace de nuestro respositorio:

git init
git add .
git commit -m "First commit"
git remote add origin <<REPOSITORY>>
git push -u origin master

Si ahora vamos a GitHub, veremos que el proyecto está subido.

Crear proyecto en Firebase

Para poder subir el proyecto a Firebase Hosting, debemos primero crear un proyecto en la consola de Firebase. Pulsamos sobre «Agregar proyecto» y le damos un nombre. El habilitar Google Analytics es opcional.

Crear un proyecto en Firebase

Conectar el proyecto Flutter con Firebase

Ahora que tenemos creados los dos proyectos y el repositorio en GitHub, es hora de conectar el proyecto que estamos haciendo con Flutter con Firebase. Para ello tenemos que utilizar Firebase CLI para ejecutar sus comandos desde un terminal. Por lo tanto, debemos instalar primero Firebase CLI. Si tenemos Node.js y npm en nuestro ordenador, podemos instalarlo fácilmente con el siguiente comando («-g» hará que se instale de manera global en nuestro ordenador):

npm install -g firebase-tools

Si no tenemos Node.js y queremos instalarlo de otra forma, podemos hacerlo siguiendo la guía oficial.

Una vez hayamos terminado la instalación, debemos iniciar sesión. Para ello abrimos un terminal (o continuamos con la que teníamos abierta) y navegamos hasta la ruta del proyecto de Flutter (este paso no es necesario en este punto pero lo va a ser más adelante). Escribimos el siguiente comando:

firebase login

Este comando nos abrirá una ventana en el navegador en la que tenemos que iniciar sesión con el mismo usuario que hemos utilizado para crear el proyecto en Firebase. Una vez hayamos iniciado sesión, nos saldrá un mensaje como el siguiente:

Mensaje de login con firebase cliAhora podemos volver al terminal y veremos que se ha iniciado sesión correctamente. Ahora debemos conectar la aplicación con el proyecto en Firebase. Para ello, escribimos en el terminal, estando en la ruta de la aplicación, el siguiente comando:

firebase init hosting

Este comando nos va a hacer algunas preguntas para configurar el proyecto. Lo primero que nos pide es elegir o crear un proyecto, en este caso, como hemos creado el proyecto antes en la consola de Firebase, seleccionamos «Use an existing project». Cuando nos salgan los proyectos que tenemos en nuestra cuenta, utilizamos las flechas del teclado para seleccionar el proyecto.

seleccionar opción de seleccionar proyecto ya creado seleccionar proyecto de firebase creado

El siguiente paso es escribir la ruta donde van a estar los ficheros que queremos que se suban y hagan públicos. Por defecto, el valor es «public» pero nosotros lo debemos cambiar a la ruta donde se encuentran los ficheros de la versión web de una aplicación de Flutter, «build/web».

escribir el directorio público

Ahora nos pregunta si queremos configurar el proyecto como un single-page app. Como Flutter trabaja, de momento, con este tipo de aplicaciones, debemos escribir que sí.

configurar como single page app

Finalmente, nos pregunta si queremos configurar la construcción y despliegue de nuestras aplicaciones con GitHub. Escribiremos que , para que nos configure una variable secreta en GitHub que nos sirve para hacer el despliegue. Si en este paso hemos escrito que no, podemos configurar la variable secreta después con el comando firebase init hosting:github.

Nos va a pedir que iniciemos sesión en GitHub para así poder configurar el repositorio remoto. Una vez hayamos iniciado sesión, nos pedirá el repositorio que queremos configurar. Por defecto viene escrito el repositorio al que se ha subido el proyecto, pero si no fuera correcto, podemos cambiarlo.

firebase cli github configuración

Después nos preguntará si queremos establecer un flujo de trabajo después de cada deploy y otro después de cada pull request. A las dos preguntas vamos a responder que no. Sin embargo, debido a un bug, es posible que nos cree uno de los dos flujos, así que lo eliminaremos de nuestro directorio de trabajo (tenemos que eliminar la carpeta .github, podemos hacerlo desde Android Studio).

Al terminar con esta configuración, se habrán creado algunos archivos, entre ellos firebase.json, en el que encontramos parte de la configuración como el directorio público, y también encontramos .firebaserc, donde se establece el proyecto por defecto. Además, si vamos a GitHub y entramos en el apartado de variables secretas, veremos que se nos ha creado una con la configuración de la cuenta de Firebase.

variable secreta dentro de github con la configuración de firebase

Finalmente, debemos subir los ficheros de configuración de Firebase al repositorio remoto. Volvemos al terminal, añadimos los archivos con git add ., creamos un commit con git commit -m "firebase configuration" y los subimos con git push

Configurar la acción de GitHub

El último paso a seguir va a ser configurar el flujo de trabajo que queremos con GitHub Actions para poder hacer build del proyecto, generando los archivos que componen la versión web y desplegarlos en Firebase Hosting.

Desde GitHub, abrimos la pestaña de «Code», pulsamos sobre «Add file» y después «Create new file».

crear nuevo fichero desde github

En el nombre del fichero vamos a escribir «.github/workflows/deploy_flutter_to_firebase.yml».

nombre que le vamos a dar al flujo de trabajo

En el fichero vamos a añadir lo siguiente, cambiando el valor de firebaseServiceAccount por la variable secreta de nuestro repositorio y projectId por el identificador del proyecto en Firebase (es muy importante que los cambiemos, si no no va a funcionar):

name: Deploy Flutter to Firebase Hosting

on:
  push:
    branches: [ master ]
    
    
jobs:
  build: 
    name: Build the web version of the Flutter app
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
      - name: Download flutter
        uses: subosito/flutter-action@v1
        with:
          flutter-version: '2.0.4'
      - name: Build web project
        run: flutter build web
      - name: Upload web artifact
        uses: actions/upload-artifact@master
        with:
          name: web artifacts
          path: build/web
          
  deploy:
    name: Deploy the built version to firebase hosting
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Checkout repo
        uses: actions/checkout@v2
      - name: Download web artifact
        uses: actions/download-artifact@master
        with:
          name: web artifacts
          path: build/web
      - name: Deploy to Firebase
        uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: '${{ secrets.GITHUB_TOKEN }}'
          firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_FLUTTER_FIREBASE_CI }}'
          channelId: live
          projectId: flutter-firebase-ci
        env:
          FIREBASE_CLI_PREVIEWS: hostingchannels

Como podemos ver en la configuración, este flujo se va a ejecutar cuando hagamos push sobre master. Cuando esto ocurra, los pasos que se siguen son los siguientes:

  1. Comienza el flujo de build.
  2. Se obtiene el código del repositorio con la acción «actions/checkout».
  3. Se descarga Flutter para poder utilizar los comandos, como el que construye la versión web, utilizando la acción «subosito/flutter-action» (esta acción es de un usuario y no es oficial de GitHub, pero se puede encontrar en el Marketplace de GitHub). A esta acción se le debe indicar cuál es la versión que queremos usar de Flutter, en este caso 2.0.4.
  4. Se construye la versión web de la aplicación con el comando flutter build web .
  5. Se suben los ficheros generados en la ruta build/web como artifacto, para poder descargarlos después, con el nombre «web artifacts».
  6. Comienza el flujo de deploy que depende de build, por lo que esperará a que termine.
  7. Se obtiene el código del repositorio con la acción «actions/checkout».
  8. Se descarga el artefacto con los ficheros de la versión web, que se ponen en la ruta build/web. Es muy importante que esta ruta coincida con la que pusimos como directorio público a la hora de configurar Firebase en el terminal (se puede consultar la ruta en el fichero firebase.json).
  9. Se despliega la aplicación con la acción «FirebaseExtended/action-hosting-deploy», una acción que no es oficial de Firebase, pero es la que recomiendan utilizar. Se debe indicar, obligatoriamente, el valor de firebaseServiceAccount, poniendo la variable secreta que hemos generado a iniciar Firebase. El resto de los valores son opcionales.

Una vez tengamos el fichero con las instrucciones y modificado con nuestros valores, podemos hacer commit del fichero. Podemos ir a la pestaña «Actions» y ver que se está ejecutando. Esta acción la podemos pulsar para ver cómo se ejecutan todos los pasos uno a uno. Si hemos seguido los pasos correctamente, deberíamos ver el siguiente resultado:

el resultado de la acción de github

Podemos ver la aplicación publicada visitando el enlace que aparecerá en la salida del segundo trabajo, que tendrá el formato https://<<firebase-project-id>>.web.app/. Además, como vemos al final de la acción, podemos descargar los artefactos creados, pudiendo así ver los archivos que han sido subidos a Firebase Hosting.

Conclusiones

Las acciones de GitHub nos ayudarán a automatizar las tareas de despliegue de nuestras aplicaciones, pudiendo configurar los recursos y los comandos que queremos que se ejecuten. Podríamos, por ejemplo, añadir un trabajo más que se encargara de testear la aplicación antes de desplegarla.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad