logo

midudev


Transcribed podcasts: 161
Time transcribed: 5d 11h 43m 38s

This graph shows how many times the word ______ has been mentioned throughout the history of the program.

Vamos a aprender Github Actions.
¿Y Github Actions por qué lo vamos a aprender?
Bueno, porque es un sistema de Continuous Integration.
¿Qué es lo que nos va a permitir el Continuous Integration?
Bueno, pues integrar nuestra aplicación siempre, constantemente.
¿Pero qué es esto de integrar? ¿Qué quiere decir?
Bueno, básicamente, la integración continua lo que quiere decir
es un sistema de automatización para verificar la integridad,
hablando de integridad, como la calidad o que esté bien formado nuestro código.
Y que además se pueda añadir en producción.
O sea, que la integración digamos que es un poquito todo.
Esta despedida del BotCamp duele más que las despedidas de Messi. Sad.
Una lágrima, una lágrima, Luigi. Gracias por el comentario, hombre.
Entonces, ¿qué es lo que buscamos?
Pues automatizar la verificación e integración de los cambios de código
de varios contribuidores, no solo de uno, de todos los que trabajan en ese repositorio
en un único proyecto de software. ¿Por qué?
Porque tenemos un montón de desarrolladores y desarrolladoras
que trabajan sobre un código y al final lo que queremos es integrarlo todo.
Pues esa integración continua, ¿qué quiere decir?
Pues cada vez que se haga un cambio en cada una de las copias que tienen estos desarrolladores,
lo que vamos a querer es integrarlo en la pieza de software que queda
y verificar que todo ha ido correctamente o evitar que no se integre, ¿no?
Porque si tiene algún error no vamos a querer que se integre.
Pues esto es lo que se hace.
Ahora, ¿por qué se llama continua?
Porque es un proceso que no deja de pasar.
Cada vez que se sube un cambio, vuelve a ejecutarse este proceso.
Este proceso en el que va del desarrollador al source control, al repositorio,
que puede ser Gija, puede ser Gitla, puede ser cualquiera.
A partir de ahí se hace la build para construir nuestra aplicación,
se hacen los tests para asegurarnos que está correctamente,
se pueden reportar, enviar notificaciones y lo que sea,
y luego hacer la release, que es un despliegue que puede ser a producción,
que hoy lo vamos a hacer.
Hoy vamos a hacer toda la continuous integration.
Vamos a hacerlo con GitHub Actions y vamos a hacer todos y cada uno de estos pasos
que he comentado.
Incluso el despliegue lo vamos a hacer en Heroku,
porque es que en Vercell es tan sencillo que no tiene sentido explicarlo.
Pero bueno, vamos a explicar Heroku para que podáis hacerlo con cualquier otro hosting,
el que prefiráis y que sepáis que se puede hacer.
Así que esto es lo que vamos a hacer.
Ahora, ¿qué pasos son los que hacen el continuous integration?
Pues lo vamos a ver, ¿vale?
Pasar el link, revisar que los commits funcionen correctamente,
que tengan una normativa de nombres, construir o empaquetar la aplicación,
bueno, un montón de cosas.
¿Y cómo lo vamos a hacer?
Bueno, pues yo tengo este proyecto de aquí,
que se llama Midudev Pokedex for Continuous Integration, ¿vale?
Está pensado justamente para hacer continuous integration.
Os lo dejo por el chat, por si lo queréis, ¿vale?
Esto acabo de empezar, así que nada, que una cosa que podéis hacer si queréis
es hacer todo lo que voy a hacer yo a la vez.
O sea, que podéis hacer un fork y todo lo que voy a hacer lo vais a poder hacer vosotros mismos,
de la misma forma que lo estoy haciendo yo.
Así que si queréis, ya sabéis, os vais a este repositorio, le dais a fork
y a partir de ahí podéis hacer todo lo que voy a hacer yo.
Todo, todo, todo, sin ningún tipo de nada, nada.
O sea, igualito, igualito.
Obviamente necesitaréis cuentas de rock y tal, pero eso lo iréis viendo.
Así que vamos a empezar con el Continuous Integration, con las GitHub Actions.
¿Por qué las GitHub Actions?
A ver, hay un montón de sistemas de Continuous Integration.
Tenemos Jenkins, ¿vale?
Jenkins es uno de los más famosos.
Seguramente es uno de los que más se utilizan.
También tenemos, por supuesto, Travis.
A ver si no me equivoco, porque Travis, Continuous Integration,
Travis C, voy a poner.
Travis también, que está bastante bien integrado con GitHub.
Y el otro son las GitHub Actions.
¿Por qué vamos a utilizar GitHub Actions?
Bueno, aparte de porque es totalmente gratuito y es muy fácil de utilizar,
pues está muy bien integrado con GitHub, como lo vamos a ver.
Pero lo que vamos a aprender hoy, aunque no es exactamente igual para Jenkins o para Travis,
es muy similar.
Lo que está detrás al final se escribe de otra forma,
pero lo que vamos a hacer es muy similar en todos estos sistemas de integración continua, ¿vale?
Al final los sistemas de integración continua tenéis que pensar que son máquinas virtuales, ¿ok?
Lo que son, son servidores que tienen máquinas con su memoria RAM, con su procesador,
porque básicamente lo que hacemos es que en lugar de hacerlo de forma local,
todos estos procesos lo hacemos en una máquina que está en la nube,
y así nos aseguramos que siempre sea la misma máquina con la misma configuración
y que tenga siempre una instalación limpia y todo esto, ¿vale?
Pero bueno, que sepáis que tenéis Jenkins, tenéis Travis CI y tenemos GitHub Actions.
GitHub Actions, como he dicho, es totalmente gratis.
Entonces, es verdad que tiene un límite y el límite es el número de minutos.
De la forma de gratuita, si tenéis la cuenta gratuita, tenéis 2.000 minutos al mes.
A partir de ahí tendríais que pagar.
2.000 minutos al mes está bastante bien.
Ya veréis cuánto tarda nuestro, el que vamos a crear hoy, vais a ver cuánto tarda
y veréis que a lo mejor dos o tres minutos.
Lo que haría que podríamos pasar casi, pues, mil veces.
Al mes podríamos pasar nuestro Continuous Integration.
El Pro tiene 1.000 minutos más y si no, a partir de ahí, pues, ya habría que empezar a pagar.
Luego, si necesitas otro tipo de configuración, por ejemplo, que tenga más potencia,
que sea un Mac OS en lugar de un Linux, por defecto es un Linux.
Ya veréis que nosotros utilizamos Ubuntu porque es el que se suele utilizar para este tipo de herramientas.
Pero podéis contratar un Mac OS y entonces tenéis que pagar aparte, ¿vale?
Que lo tengáis en cuenta.
Y también incluso lo podéis hospedar si tenéis un hosting vuestro, lo podéis hospedar.
Pero bueno, eso se sale un poquito de lo que queremos hacer.
Lo importante, vamos a empezar con nuestro proyecto, con el Pokédex for Continuous Integration.
Y lo primero que voy a hacer es clonarlo.
Y vamos a ver cómo podemos hacer justamente esto, ¿vale?
Nos vamos a la terminal, voy a hacer un git clone de este proyecto, el de Pokédex for Continuous Integration.
Me voy al proyecto, Pokédex for Continuous Integration.
Y ahora que tenemos esto, pues como siempre, cuando se empieza un proyecto, pues nada, un MPM install para instalar las dependencias.
No debería tener muchas, así que vamos a esperar que no tenga muchas.
Y ahora le echaremos un vistazo al proyecto para explicar qué es, qué hace.
Le haremos una build, le pasaremos los tests y veremos unas cuantas cosas y te explico lo que tiene, ¿vale?
En principio, con el MPM install, se me ha estado toda la dependencia que necesitamos.
Ya veremos si luego necesitamos alguna más.
Tampoco le he hecho un vistazo muy en detalle.
Pero bueno, vamos a ver.
MPM run, para ver qué scripts tenemos.
Tenemos un start, tenemos el test, tenemos un start prot, es linked y un build.
Vale.
Vamos a hacer un MPM start.
No, vamos a empezar con la build.
Vamos a hacer un MPM run build, porque seguramente el start...
Bueno, el start, sí, vamos a hacer el start.
El start es el del modo desarrollo y esto va a hacer la compilación por defecto.
Y ya está.
Aquí se debería...
Vale, este es nuestro proyecto.
Podemos ver que hay un montón de pokémones aquí.
Le podemos dar, yo que sé, al Widdle y aquí nos sale la información.
Podemos ir al siguiente, podemos ir al anterior, ¿vale?
Bueno, pues esto sería nuestro proyecto.
Vamos a ver qué más scripts tenemos.
Tendríamos también el test.
Vamos a ejecutar el test, a ver qué pasa.
Vale, MPM run test.
Vale, falla un test.
No te preocupes, lo arreglaremos después.
Esto es normal, por ahora vamos a dejar así.
Lo importante es que los tests se ejecutan.
Falla uno, pero bueno, ya veremos cómo lo arreglamos.
MPM run slint, para ver el linter.
También tiene errores, no pasa nada.
También lo arreglaremos después.
¿Qué más?
Vamos a hacer un MPM run build, para hacer la build de la aplicación.
A ver si falla o no.
No falla.
Perfecto, ya nos habrá hecho la build.
Y bueno, vamos a abrir el proyecto, para echarle un vistazo a este...
A esta aplicación.
Ya vemos que tenemos Babel RC.
Es un proyecto que tiene una configuración de Webpack.
No está hecha de abrir acá.
O sea, tiene su propia configuración desde cero.
Babel loader, HTML loader.
Esto no hemos visto en FullStat Bootcamp.
Pero bueno, no es importante.
Si no lo has visto, no pasa nada.
Lo único que tienes que saber es que utiliza Webpack.
Aquí tenemos todas las dependencias con todos los scripts.
Vale, todas las dependencias que necesitamos.
Tenemos dependencia de desarrollo y de producción.
Y mirando un poquito el código, pues podemos ver que son componentes de React.
Es un proyecto de React.
El que vamos a desplegar, con el que vamos a hacer Continuous Integration, es un proyecto de React.
Perfecto.
Tenemos aquí en el source todo lo que es el código, que seguramente tenemos que tocar alguna pequeña cosa.
Hoy no vamos a codificar mucho, sino que vamos a probar el Continuous Integration.
Pero ya hemos visto que tanto los test como el linter falla.
Así que vamos a tener que revisarlo.
Tenemos que hacer algo para arreglarlo.
¿Cómo podemos crear un workflow para GitHub Actions?
¿Y cómo funciona GitHub Actions?
Las GitHub Actions, si volvemos a nuestro repositorio, ya las tenéis aquí disponibles.
¿Veis que pone Actions?
Pues si tú le das aquí a Actions, ahora no aparece nada.
Y te dice, bueno, para empezar con GitHub Actions.
Y la verdad es que aquí ya te da algunas sugerencias que están bastante bien.
Una que te dice, mira, para proyectos con Webpack, pues ha detectado qué es lo que tiene tu repositorio y dice,
utiliza Webpack.
Node.js, Gulp.
No, pues Gulp no tengo.
Pero bueno, no es perfecto esto.
Son sugerencias.
Entonces, la de Webpack o Node.js no tendría mala cuenta.
Le podríamos dar a Setup this workflow.
Y esto te crea aquí un editor que está bastante bien.
Lo que pasa es que, claro, ya te viene con un montón de cosas aquí configuradas.
Y a lo mejor no es exactamente lo que queremos.
Pero ya vemos un poco que me está creando dentro de la carpeta .github barra workflows barra y el nombre de este fichero es webpack.yaml.
Así que va a utilizar un formato YAML, que para el que no conozca el formato YAML es similar a JSON, pero no utiliza llaves.
En lugar de utilizar llaves, utiliza espacios.
Luego lo verás claramente.
Y te daré un consejo, una recomendación súper importante que tienes que hacer sí o sí para no volverte tarumba.
Así que, bueno, no lo vamos a hacer así con el editor.
Lo vamos a hacer nosotros desde cero en Visual Studio Code.
Así que esto es solo para que sepas, si tienes otro proyecto, que sepas que puedes hacer esto y esto te puede dar alguna idea.
Nosotros lo vamos a hacer desde cero.
Vamos a crear el primer workflow.
Porque GitHub Actions, lo que tienes que crear son workflows.
Y puedes tener más de uno.
Así que vamos a hacer un new file.
Vamos a hacer punto github barra workflows.
Barra.
Vamos a poner por ahora hello.yaml.
¿Vale?
Hemos dicho que es un formato YAML.
Primera cosa súper importante del workflow.
Bueno, los workflows tienen que tener un nombre.
Así que vamos a ponerle un nombre y le vamos a llamar sayhello.
¿Vale?
Hasta para empezar.
Ahora, segunda cosa que tienen que tener los workflows de GitHub Actions.
Lo que tienen que tener es un evento.
¿Cuándo se tiene que activar un workflow?
Un workflow al final es una serie de procesos.
Pues ¿cuándo se tiene que activar este archivo?
Pues este archivo le tengo que decir.
Vale, este archivo va a escuchar el evento de push en las ramas.
Y le puedes decir las ramas.
En este caso vamos a decir que sea master.
Vamos a ver, vamos a asegurarnos cuál es la rama que tenemos aquí.
¿Ves?
Esta es main.
¿Vale?
Pues entonces en lugar de master vamos a poner main.
Cada vez que hagamos un push en la rama main lo que vamos a hacer es que se va a ejecutar todo este workflow.
¿Y qué es lo que va a hacer un workflow?
Vale, pues un workflow para trabajar lo que necesita.
Mira, de hecho fíjate que pone missing property jobs.
O sea, es una maravilla esta extensión.
Y ahora te diré cuál es, no te preocupes.
Lo que tiene que hacer es tener trabajo.
Porque la gente que no trabaja pues no hace nada.
No hace nada.
Bueno, puede estar estudiando.
Pero en este caso la GitHub Actions necesita trabajo.
Así que le decimos jobs.
Y le vamos a indicar cuáles son los trabajos que tiene que hacer este workflow.
Vamos a ponerle un nombre.
Vamos a poner hello world, por ejemplo.
Y le tenemos que decir primero en qué sistema operativo va a funcionar este trabajo.
Así que le decimos este trabajo funciona en Ubuntu Latest.
Ubuntu Latest sería la última versión de Ubuntu.
Pero puedes utilizar, si lo prefieres, y de hecho puede ser una buena idea,
que utilices una versión en concreto.
De hecho está muy bien que tiene hasta autocompletado.
¿Ves?
Aquí te pone 16.04, 18.04, 20.04.
Bueno, pues le podemos poner la versión específica.
Si le pones Latest, el problema que puede haber es que cuando salga la 22,
automáticamente utilizará esa y se puede romper todo y no queremos que se rompan las cosas.
Ahora que tenemos un trabajo con el nombre hello world,
que decimos que tiene que funcionar en Ubuntu,
le tenemos que decir todos los pasos que tiene que dar.
Así que le vamos a indicar los pasos.
A los pasos tú le puedes dar un nombre.
Por ejemplo, le podemos decir, vamos a hacer un eco del mensaje.
Le podemos poner un nombre o lo que tú quieras.
Si quieres no le pones un nombre.
Y aquí le vamos a poner run y le decimos lo que tiene que ejecutar.
Lo podemos hacer así, en la misma línea.
Vamos a poner hola midu.
Lo puedes hacer en la misma línea.
Otra cosa que puedes hacer es poner esta barra así y luego ya escribir todo lo que quieras.
Ahora, antes de continuar y de probar nuestro primer workflow,
una cosa súper, súper importante, porque si no, YAML es una locura.
Fíjate con una cosa, ¿no?
Yo, YAML funciona a través de las tabulaciones.
Todo lo que son tabulaciones entiende que es información que está contenida.
No es como JSON, que el JSON funciona con las llaves.
Lo que significa que las llaves pueden estar mal tabuladas y funcionar igualmente.
Pero YAML no.
YAML es muy, muy, muy, muy jodido.
Necesita que funcione con las tabulaciones correctamente.
Si yo hago mal esta tabulación, ¿vale?
Pues ya la estoy liando.
Ya no funcionaría exactamente igual.
Fíjate que a veces, si aquí hago mal una tabulación, ¿ves?
Me dice, bad indentation of a mapping entry.
O sea, ya me empieza a decir, oye, esto está mal.
¿Cómo puedes hacer?
¿Ves?
Aquí, bueno, aquí veo que no.
Depende un poco de dónde lo pongas.
Que algunas veces sí que te lo chiva y otras no.
Pero, bueno, está bastante interesante que por poco que te lo diga,
yo creo que si pones un espacio y cosas así, depende de dónde lo pongas y que te lo dicen.
Es súper importante, ¿vale?
Tienes que tener la extensión de YAML instalada.
Hay una extensión que es bastante oficial porque es de Red Hat.
Tiene 6 millones de descargas.
Esta extensión para trabajar con archivos YAML es súper, súper, súper necesaria.
Por dos motivos.
Uno, porque te va a indicar los errores.
Y si no te das cuenta de estos errores y los subimos aquí, Cap Actions,
vamos a volver locos perdidos, ¿vale?
Porque te va a decir, el YAML está mal formateado, no vas a encontrar el error, un rollo.
Así que instálate esta extensión cada vez que trabajes con un YAML.
Y luego, porque a lo mejor no hace lo que tú esperas, ¿vale?
Porque si, fíjate, que si el Steps lo pones aquí, a lo mejor, aquí sí que se ha dado cuenta que está mal intentado,
pero a lo mejor lo que simplemente hace es ignorarlo y nunca lo ejecuta.
A lo mejor funciona, pero no hace lo que tú esperas.
Así que, bueno, es buena idea tenerlo instalado.
Además, también tienes el autocompletado.
Fíjate que aquí me está haciendo el autocompletado de todos los eventos que puedo escuchar.
Y esto es una cosa que te lo está haciendo también la extensión.
Así que lo tengas en cuenta, que lo utilices, que es muy buena idea.
Ya tenemos nuestro primer workflow.
Vamos a verlo en funcionamiento, si os parece.
Vamos a add our first workflow of GitHub Actions.
Venga.
No hay, vale.
Lo comitamos todo y lo subimos.
Voy a poner aquí la terminal.
Pusheamos.
¿Vale?
Y voy a volver a mi repositorio y voy a refrescar.
A ver, capachao.
Mira, fíjate aquí que hay ya un circulito amarillo.
Esto lo que quiere decir es que se está procesando el workflow de GitHub Actions.
De hecho, si le das un clic, ya te dice, hay algunos checks que todavía no se han completado.
Y ves que pone aquí, say hello barra hello world.
Esto es el nombre que le hemos puesto al workflow.
Y el hello world es el nombre del trabajo que le hemos puesto.
Le podemos dar a detalles y esto nos lleva directamente a la ejecución de nuestro workflow.
Nos va diciendo todos los pasos.
En este caso, solo ha tardado 19 segundos.
Y hace un segundo que se ha ejecutado.
Todo ha ido bien porque aquí vemos que tiene un check.
¿Ves?
Check.
Perfecto.
Si hubiera fallado, nos hubiera puesto un fail.
Entonces, aquí nos pone los diferentes pasos.
Setup job.
Nos dice toda la información del sistema operativo.
El entorno.
Los tokens de los permisos que tenemos.
Esto lo veremos un poquito más adelante.
Hacemos el eco del mensaje.
Y ya ha terminado el trabajo.
Bueno, este es el job.
Seguramente uno de los más piratas, más aburridos del mundo.
Ahora lo complicamos un poco.
Si no, también le podéis dar a Actions.
Aquí, si le dais a Actions, ya podéis ver todos los workflows que hemos ido ejecutando.
Hace un minuto, ha tardado 11 segundos.
Y este es el primero.
A través del commit add or first workflow GitHub Actions, ha empezado este en la rama main.
Y aquí podemos ver, además, los diferentes workflows.
Porque, como he dicho, podemos tener más de uno.
De hecho, luego tendremos más de uno.
Así que veremos cómo funciona.
Vamos a hacer más cositas.
Ahora ya tenemos aquí Steps.
Tengo el eco del message.
Vamos a poner más Steps.
Para que veas las posibilidades que tienes aquí.
Importante de los Steps que estén alineados.
Cuando ponemos aquí en YAML, ponemos este guión, lo que quiere decir es que Steps es como un array.
Y cada guión lo que está haciendo es ser un elemento del array de Steps.
En este caso, solo había puesto uno.
Había puesto el name.
Había puesto este.
Pero si yo quito este name y lo ponemos aquí en el run, aquí es exactamente lo mismo.
El nombre es totalmente opcional.
Lo importante es que vayamos separando con el guión cada uno de los pasos que queremos que tenga.
Así que lo tengas en cuenta.
Así que tiene que estar también alineado.
Tiene que estar al mismo nivel.
¿Qué más podemos hacer?
Al final, como esto es una máquina, podemos ponerle dime la fecha.
Y le ponemos aquí en run.
Vamos a poner date.
Este lo vamos a poner aquí, en la misma línea, para que lo veas.
Y aquí vamos a poner directamente un run del LSL.
Vamos a hacer esto para que veas un poco como es una máquina realmente y que podemos enviarle cualquier comando que nos interese.
Add new commands for workflow.
Vale.
Puseamos.
Y vámonos otra vez aquí.
Normalmente hay que refrescar manualmente.
Hay veces que, mira, eso te iba a decir, hay veces que hace esto, que automáticamente lo detecta y te aparece.
Pero hay veces que a lo mejor si ves que no te lo detecta, pues lo refrescas manualmente y ya está.
Vale.
Está muy bien porque ya hemos visto cómo estaba en amarillo, se ha puesto en verde.
Volvemos a entrar.
Aquí nos pone todos los pasos, todos los trabajos.
Ahora solo tenemos uno, pero más adelante verás cómo van apareciendo todos los que vayamos haciendo en el siguiente workflow.
Y aquí tendríamos el echo de message.
Dime la fecha.
Ahora ves, aquí tienes el nombre porque le he puesto un nombre a este paso.
Pero el siguiente ves que pone ejecutar es lsl porque no le he puesto ningún nombre.
Aquí he ejecutado el comando date, me ha dicho la fecha, lsl y bueno, no tiene ningún archivo.
Y aquí es uno de los primeros, no problemas, pero uno de los primeros retos que vamos a tener.
Y es el hecho de que nuestra máquina de GitHub Actions está vacía.
O sea, no tiene ficheros.
He hecho un lsl y fíjate, no tiene nada.
Total, cero.
O sea, estoy ejecutando esto ahora mismo en una máquina vacía.
No me está aportando absolutamente nada.
Vamos a arreglar esto porque, claro, no tiene sentido que intente hacer comandos en algo que no tiene nada.
Está vacío.
¿Cómo vamos a hacer esto?
Bueno, vámonos a crear otro workflow.
Nos vamos aquí, en workflows, vamos a crear ahora el pipeline.
Le voy a llamar pipeline, que básicamente un pipeline, digamos que es una tubería en la que pasan todos los procesos por los que fluye nuestra aplicación.
Le podéis llamar como quieras.
Pero yo le voy a llamar deployment pipeline.
¿Por qué?
Porque al final lo que vamos a hacer es el despliegue de nuestra aplicación a producción.
Vamos a decir que trabaja cuando se hace un push en la rama de master.
Aquí esto hay otra forma de escribirlo, luego lo veremos.
Pero por ahora quédate con esta.
He puesto master, pero debería ser main.
Importante que sea tu rama master, de verdad.
Aquí al final lo puedes hacer con cualquier tipo de rama.
En este caso, nuestra es la main.
Vamos a decir los trabajos que tenemos.
Por ahora voy a hacerlo todo en uno.
Entonces le voy a llamar deploy, pero luego lo separaremos en diferentes jobs.
Y ahora en el deploy le vamos a decir que se va a ejecutar el sistema operativo 1804 de Ubuntu.
Y vamos con los pasos que tenemos que dar para conseguir esto.
¿Qué pasa con esto de los pasos?
Como hemos dicho, yo lo que quiero es conseguir el código, ¿no?
Porque es que ahora mismo aquí lo tengo vacío.
Lo que quiero conseguir seguro es tener el código de mi propia aplicación.
Así que ahora lo que vamos a ver es el concepto del marketplace de la GitHub Actions.
Porque si hay una cosa que es brutal de GitHub Actions es el hecho de que las acciones se pueden componer de otras acciones a su vez.
Una locura.
¿Qué quiere decir esto?
Lo que quiere decir es que yo lo que necesito sería hacer un checkout de mi proyecto, ¿verdad?
Pues voy a buscar checkout en el marketplace de GitHub.
Si yo busco checkout, podremos ver aquí que hay aplicaciones y aquí tenemos acciones.
Y hay un montón de acciones.
Hay una acción que justamente hace lo que necesito.
Checkout a Git Repositorio at a Particular Version.
Esto es lo que quiero yo.
Quiero hacer un checkout.
O sea, quiero traerme el repositorio a mi máquina.
Pero ves que hay un montón.
Hay un montón.
Submodule Checkout, Spark Checkout.
Aquí te puedes volver tarumba.
Hay aquí para enviar notificaciones, hacer testing de mobile, para hacer localización.
Hay de todo.
Hay de todo.
Esto no te lo terminas.
En este caso el que nos interesa es este que además, fíjate, los que están verificados suelen ser bastante chulos.
Así que vamos a utilizar este que es oficial además de GitKab.
En este lo único que tenemos que hacer es decirle quiero utilizar esta acción
y con With tú puedes pasarle la configuración de esta acción en concreto.
Y de hecho, en este caso no vamos a necesitar ninguna configuración, pero es bastante interesante porque le puedes decir el repositorio,
que por defecto es tu propio repositorio, pero podría ser otro.
Podrías hacer un checkout de otro repositorio que fuese tuyo o incluso que estuviese abierto.
Luego, el token que vas a utilizar, que todo esto te lo resuelve de forma totalmente automática.
Piensa que tú aquí realmente podrías hacer, igual que hemos hecho aquí, que hemos hecho el run y hemos hecho esto,
aquí podríamos empezar a hacer git, clone, no sé qué.
Pero claro, tendrías que configurarlo, tendrías que pasarle el token, tendrías que hacer un montón de cosas.
Pues con esta acción, esto lo está haciendo totalmente gratis para ti, sin que tú te tengas que preocupar de absolutamente nada.
De hecho, aquí podemos ver algunos de los ejemplos.
Dice, usando esta acción con un fetch depth cero.
Esto lo que hace es que solo se trae el último commit para hacer el git checkout mucho más rápido.
Bueno, pues podríamos hacer esto.
Este users lo tenemos que poner en los steps, ¿vale?
En los steps le vamos a decir que tenemos una step que es utilizar el actions checkout y le decimos con la opción del fetch depth que sea cero,
para que eso solo se traiga el último commit, así lo hará lo más rápido posible.
Ahora bien, ¿qué es lo que me gustaría hacer aquí?
Bueno, lo que quiero hacer en la Github Action, en este workflow, es instalar las dependencias y lintar el código.
Así que, ¿cómo puedo conseguir eso?
Bueno, lo que necesito es Node.
Así que podría, de la misma forma que hemos visto antes, podría hacer un run, instalar MVM y con MVM instalar Node y todo esto.
Pero, obviamente, hay muchos proyectos que necesitan Node, no es el único.
Así que buscando en nuestro Marketplace, vámonos a nuestro Marketplace.
Entonces, si yo aquí busco Node, pues vamos a ver que tenemos un action que es Setup Node.js Environment, que es justamente lo que necesitamos.
Así empezamos a componer con acciones que no tenemos que nosotros escribirlo todo.
Esta también es oficial de GitHub.
Y con esto, mira, es que además aquí, esto es lo más típico en cualquier proyecto de Frontend, que, o, sí, de Frontend o de Backend que esté hecho con Node.js.
Entonces, lo que vas a ver muchas veces repetido son estos steps.
Uno, hacer el checkout.
Dos, hacer el setup de Node con la versión que quieres.
Luego, hacer la instalación y tal.
Bueno, pues vamos a copiarnos esto para decirle que queremos utilizar esta versión.
Y lo intentamos correctamente.
Importantísimo.
Importantísimo.
Luego, fíjate, esto es una recomendación, aunque si tienes la extensión no te va a pasar nada.
Pero, ¿ves que yo tengo los simbolitos, estos puntos?
Estos puntos son espacios.
Y yo tengo que estos símbolos que normalmente son transparentes, ¿no?
Que no los ves, son invisibles.
Yo lo que tengo es que cuando selecciono los veo.
¿Por qué?
Porque hay veces que se te puede colar una tabulación con espacios y entonces el YAML no te funciona correctamente.
Y yo estas cosas, para no volverme loco, ya lo tengo bastante controlado.
Vale, pues ya utilizamos estas dos acciones.
Ya tenemos el checkout, tenemos el setup Node.
Ahora le vamos a decir, pues vamos a crear aquí otra.
Y vamos a tener, instalar las dependencias, ¿no?
Queremos instalar las dependencias.
¿Cómo lo hacemos?
Pues ejecutamos en PMInstall.
Ahora también vamos a tener otra.
Y aquí, ¿qué le vamos a hacer?
Vamos a empezar con el linter.
El linter es súper típico que se ejecute en Continuous Integration.
Ya sea Travis, GitHub Actions, CircleCI, GitLabCI, lo que sea.
¿Por qué?
Porque, hombre, el linter es lo que te asegura que el código que estás integrando en la rama master o en la rama que sea es correcto.
Así que vas a querer evitar que se integre si no está bien.
O que al menos te notifique que estás intentando integrar algo que no está bien.
Así que vamos a hacer un run de npm run slint.
Creo que era, si miro, voy a mirar por aquí.
Vale, esto no lo cerramos.
Pero creo que en el package.json habíamos puesto el script era slint.
¿Vale?
Muy bien, pues por ahora vamos a dejarlo así.
Vamos a probar que esto funciona, que todo ha ido correctamente.
Vamos a añadir Add New Pipeline Workflow.
¿Vale?
Y lo hacemos un push para nuestro proyecto.
Volvemos por aquí.
Aquí deberíamos ver la bolita.
Súper interesante.
Esta bolita está muy bien porque cuando está amarillo es que se está pasando y visualmente lo ves.
Pero también luego se pone en verde o se pone en rojo.
Y al darle, pues directamente puedes ver.
Aquí podemos ver que se están ejecutando los dos workflows.
Por un lado el de decir hola, que habíamos puesto, lo he dejado ya porque total no pasa nada.
Y por otro lado tenemos el deployment pipeline que acabo de crear.
Yo podría ir a Actions y verlo de otra forma.
Aquí podemos ver que tenemos los dos workflows.
Deployment pipeline y say hello.
Te puedes enfocar en uno u otro.
Podrías ir al say hello o el deployment pipeline.
Este es el más interesante.
Así que vamos a ver este.
Además este todavía se está ejecutando porque tiene que hacer bastantes más cosas.
Vámonos por aquí.
Vámonos al deploy.
Y fíjate que está instalando las dependencias y ha tardado 33 segundos.
Lo interesante, que ya ha pasado el linter y aquí hay mucho rojo.
Pero ha pasado el linter, me está diciendo todos los errores.
Lo cual está muy bien.
Y además lo que ha detectado es que el proceso que estaba haciendo ha salido con un código que no es cero.
Los comandos, los procesos pueden salir con un montón de códigos.
Pero básicamente si es cero es que ha ido bien.
Si no es cero es que ha ido mal.
Normalmente se sale con el código 1 para decir que no ha salido correctamente.
De hecho ves, exit status 1.
De esta forma es como el continuous integration detecta que el comando que estabas utilizando ha apretado.
Lo hace con esto, con el exit status 1.
Y una vez que sale, ya podemos ver aquí que nos sale bien grande.
Como te he dicho, si volvemos al repositorio, ves, aquí tienes ahora esto.
Esto es muy genial porque lo ves.
Pero también podrías incluso, si vamos aquí a las actions, veremos que en un sitio aquí,
Deployment Pipeline, aquí, en estos tres puntitos, ves que pone aquí create status batch.
Este lo puedes dar y lo que te hace es poder crearte este batch que tú puedes añadir en el README.
De esta forma, pues nada, te lo copias, te puedes ir al README, te lo, vamos a poner aquí, lo pegas ahí.
Y luego cuando haga un commit, pues vamos a tener, al menos en el README, ver cómo ha quedado la última vez,
que es todavía más grande y mucho más potente.
Bueno, ya sabíamos que iba a fallar el linter, pero era una forma de ver justamente, ¿no?
También otra cosa que te quiero enseñar es que si vas aquí a las actions y le das al workflow que ha fallado,
vas a ver que sin necesidad de entrar al detalle, como lo hemos hecho, aquí ya te indica las anotaciones.
Y en las anotaciones te está diciendo todos los errores que ha detectado.
Y fíjate que los errores que ha detectado son los errores que te da el linter.
Los strings tienen que ser así, aquí hay un semicolon de más, o sea, aquí tienes ya anotaciones.
No hace falta siempre que entres al detalle del log, sino que desde fuera ya lo puedes ver.
Obviamente el detalle del log es mucho más interesante porque tiene mucha información,
pero desde fuera ya podrías incluso ver cada uno de estos errores.
Aquí, pues además te dice la línea, el archivo y tal.
Bueno, vamos a echar un vistazo y nos pone que este error ha pasado en app.js.
Vámonos a nuestro proyecto.
Vamos a app.js.
Aquí puedo ver que también el editor me está diciendo que tengo todos estos errores.
Voy a formatear directamente el archivo y me los va a solucionar porque me va a hacer un fix del sling directamente.
Me ha solucionado los que ha podido, los que no ha podido me los ha dejado, me ha dicho, estos te encargas tú.
Este process is not defined.
Bien, vale, esto es porque seguramente el linter, si vamos a la configuración del linter,
en environment no tiene el environment de node a true.
Y por lo tanto, la variable global de process no la encontraba.
Ahora sí, ¿ves?
Y la detecta como que es un proceso de node.js.
Perfecto.
Y luego tenemos este unexpected console statement.
Podríamos hacer dos cosas.
Uno, hacer un sling disable line del no console.
Y esto, pues ya lo tendríamos.
O, bueno, para currarnos en salud, podríamos venir aquí al no console y decir que nos diga que es un warning.
Porque no es raro que tengamos console logs en la parte del servidor.
Y que ahí pongamos este tipo de información.
Puede no ser un error.
¿Vale?
Así que vamos a dejarlo así.
Y por si acaso, aquí en la terminal, voy a ejecutar aquí en la terminal, npm run sling, a ver si todo está bien.
¿Vale?
Ahora me dice los warnings del console.
¿Vale?
Perfecto.
Pues vamos a fix lint.
Vamos a hacerlo bien.
Fix lint errors.
¿Vale?
Y aquí vamos a hacer add t-cap action batch status.
¿Vale?
Hacemos un push de todo esto y vamos a ver cómo queda.
Vámonos por aquí a ver cómo queda el batch.
¿Vale?
¿Ves?
Este batch lo que te enseña es el estado de la última vez, de la última ejecución.
Así que hasta que no dé verde, esto no va a volver a pasar a ser verde.
¿Ves?
Todavía está failing porque no sabes si va a ser verde o failing el siguiente.
Vamos a darle aquí.
Vamos al deployment pipeline.
Vamos a ver si ahora sí que se está ejecutando correctamente el linter.
Voy a mirar una cosa con la instalación para hacerla más rápido.
¿Ves que tengo aquí un package lock?
Pues vamos a poder hacer las instalaciones un poco más rápido y ahora te explicaré un poco cómo y te revisamos esto.
Vale, ahora ha funcionado todo correctamente.
El linter me muestra los warnings.
Ha instalado las dependencias.
Son 18 segundos.
Tampoco mucho.
Mira, aquí se podrían hacer dos cosas.
Y esto es muy típico de hacerlo en continuous integration.
Uno.
Como puedes ver aquí el npm install, cuando los instala, tenemos aquí que además está haciendo lo del funding y además está haciendo lo de la audición.
O sea, audición de la seguridad de los paquetes.
Y te dice, oye, he encontrado 5.277 vulnerabilidades.
Aparte de que esto añade bastante ruido, además de eso, no se lo ve nadie y tiene un impacto en el tiempo que tarda.
A lo mejor es una cuestión de segundos.
Pero bueno, cuando estamos hablando de 18 segundos, pero que los ejecuta mil veces, todo suma.
Así que, una cosa que puedes hacer sería, aquí en la instalación que estábamos haciendo anteriormente, en el pipeline, podríamos hacer esto.
No audit y no fund.
Incluso podríamos decirle no optional, ¿vale?
Para que no instale las dependencias opcionales.
Por ahora voy a hacer esto, pero seguramente después lo voy a cambiar por otra cosa que es todavía más rápida.
Pero bueno, solo para ver cómo va evolucionando el tema de la rapidez.
Porque el optimizar la integración continua para que tarde lo menor posible, lo menor tiempo posible, vas a ver que también es una cosa súper importante.
Bueno, ya tenemos esto, ¿no?
El linter.
Perfecto.
¿Qué queremos hacer ahora?
Pues aparte del linter, vamos a querer hacer la build de nuestro proyecto.
Así que le voy a poner build.
Vamos a decir run, npm run build.
Vamos a hacer la build, ahora que lo tenemos bien.
Y, por supuesto, después vamos a ejecutar los tests.
Así que hacemos un npm test y con esto ya tendríamos la build y los tests.
Vamos a comprobar.
A ver, ya hemos visto antes en local si yo hacía un npm test que fallaba, ¿eh?
Pero bueno, veremos el fallo en Condition Integration y lo arreglaremos y tal.
Y luego veremos dónde sale este error.
Vamos por ahora a añadir la build y el test con estas nuevas opciones, parámetros del npm install.
Yo, si me preguntas, ¿eh?
Si me preguntas, estas opciones del no audit y el no fund, yo los tengo también en local.
Porque para mí también suelen ser bastante molestos.
GitHub, ya por sí, te suele avisar cuando tiene vulnerabilidades en las dependencias de tu aplicación.
Por lo tanto, que cada vez que haces un npm install te avise y además te llene el log.
Yo es que los ignoro.
Entonces, lo que te recomiendo es que hagas un npm config get audit y aquí verás, ¿ves?
Yo tengo un false.
Igual a ti te será la true.
Pues puedes hacer un npm config set audit y le pones el valor que quieras, pues false.
Y lo mismo lo puedes hacer para el fund, ¿vale?
Yo con el fund, que es para saber qué proyectos son los que aceptan funding, yo también los tengo a false.
De esta forma, cuando yo hago localmente un npm install, no me hace esas comprobaciones y araño unos segundos.
Pero yo todo lo que sea ganar segundos, a tope con eso.
Así que, bueno, vamos a build and test app in deployment pipeline, ¿vale?
Vamos a pushear los cambios.
Estos son aliases que tengo yo, ¿eh?
El gcmsg, ggpush, estos son aliases que tengo.
Nos vamos a actions y, bueno, aquí tenemos otra vez el say hello, que si queréis lo puedo quitar, porque si no va a estar ahí todo el rato.
Y el deployment pipeline, que es el que nos interesa.
Pues nada, entramos aquí.
Luego esto lo vais a ver tan bonito cuando...
Vamos a ir poco a poco, pero el final es muy bonito.
Vamos a ver si mejora un poco la instalación.
Igual no se nota.
Igual hay veces que la instalación fluctúa y además, como tarda relativamente poco, igual no vemos una mejora realmente.
Creo que sí que veremos más mejora que lo que haremos después en la instalación.
Vamos a ver.
De hecho, mira, ahora está tardando 18 y aquí ha tardado 22.
Ha tardado un poco más incluso, poniéndole los...
No es que tarde más, ¿sabes?
Porque alguien ahora puede decir, hostia, has hecho que tarde 4 segundos más.
No, lo que pasa es que hay veces que puede tardar 18, como puede tardar 30 y el hecho de que añada estos parámetros, lo que puedes hacer es que normalmente tarde menos.
Pero no se fija, siempre tarde menos.
No tiene un impacto tan grande y tarda muy poquito como para que tenga un impacto real.
Pero al menos el lock, que también es importante en Continuous Integration, tener el lock, lo que te muestra, limpio, pues ves, ahora no aparece nada aquí.
En cambio aquí, cuando había hecho la instalación, no sé, nos aparecía esto.
¿Vale?
Bueno, lo importante.
¿Qué nos ha fallado?
Aquí tenemos el jest, nos sale un montón de fail.
Bueno, esto es console.log, console.logs y nos ha fallado aquí y por lo tanto no ha continuado ejecutando, nos ha salido la x y tal.
Bueno, vamos a arreglarlo en un momento.
Ahora que hemos visto más o menos dónde está el error, tenía algo del next y el previous, ¿no?
Que el previous, ese enlace sí que va bien, pero el next no tiene la información correcta.
Vamos a buscar en el source, me imagino, Pokémon Page.
Vamos a ver aquí el next.
Next.
Next.
Next.
Vale.
Vale, ya veo el error.
Pokémon PreviousName.
Claro, este funciona correctamente, pero aquí en lugar de utilizar el next, está utilizando el previous otra vez.
Así que le ponemos aquí el next y ahora si ejecutamos los tests, pues ahora deberían funcionar correctamente.
Vale, vamos a verlo.
Vale, ahora sí que pasan los tests.
No sé si se ha visto porque eso está muy abajo, pero que ahora funciona correctamente.
Vale.
Por ahora voy a hacer esto.
Vamos a hacer el fix next link with correct info.
Vale.
Pusheamos y bueno, vamos a dejar que eso se vaya haciendo por ahí.
Mientras, luego lo veremos que está en verde.
¿Qué vamos a hacer ahora?
Bueno, los tests que tenemos están muy bien, pero unos tests que son muy típicos, que se suelen utilizar en este tipo de aplicaciones, son los de end to end.
Y lo vamos a ver.
Vamos a ver cómo los podemos hacer.
Y además te voy a decir una buena práctica que puedes hacer para evitar que tarde de más el Continuous Integration.
Ya te digo que es súper importante optimizar el tiempo del Continuous Integration.
Entonces, lo vamos a hacer con Cypress.
Lo vamos a hacer bastante rápido.
Si no sabes de Cypress, pues te recomiendo un montón que vayas a mi web.
A mi web, no, a mi canal de YouTube.
Y te busques el...
Hay un vídeo este.
Aprende testing con Cypress como lo hace un senior o algo así, me parece que es.
Mira, un chico feliz con unos rulos fantásticos.
Dos chicos o dos personas que no les gusta hacer testing.
Pero en esta clase te explico cómo hacer Cypress, por qué es importante, tal, tal, tal.
Si no sabes qué es Cypress, ahí lo tienes.
Pero es para hacer testing en tu end.
Entonces, lo más típico, lo que haríamos normalmente, ¿no?
Sería hacer, bueno, pues tienes que instalar Cypress, ¿no?
Y te diría, haz un npm install de Cypress y save dev.
¿Cuál es el problema de hacer esto?
Bueno, no es un problema.
Pero lo que estaríamos haciendo con esto, Cypress es una dependencia muy grande.
Muy, muy, muy grande.
Piensa que se instala un navegador.
Entonces, ya no solo la dependencia al paquete de notes es grande, sino que tener que instalar el navegador es bastante importante.
Entonces, vamos a evitar este paso.
Y vamos a hacer que se instale, o sea, que se ejecute y se descargue solo cuando sea necesario.
Lo que vamos a hacer para ello, nos vamos a ir aquí al Package.json.
Y lo primero que vamos a hacer aquí en scripts, además esto es una cosa que podéis utilizar para un montón de cosas, así que es muy interesante.
Igual que tenemos aquí un start prod, voy a añadir un start test, que va a ser lo mismo, pero lo vamos a poner en modo test.
Con la variable del node environment lo vamos a poner en test.
Y ahora que tenemos esto, pues voy a crear mis test end to end.
Vamos a poner un script que sea test end to end.
Y para esto, lo que vamos a hacer es ejecutar npx cypress run.
npx lo que va a hacer es ejecutar al vuelo el paquete de cypress, de forma que hasta que no lo necesite, no lo va a instalar.
Tú podrás tener tu aplicación y cuando ejecutes este script, entonces será que instalará en la carpeta temporal la dependencia de cypress y lo ejecutará de forma global.
Así que de esta forma nos evitamos el npm install y hasta que no lo necesites, no se instalará.
Para que lo veas, yo ahora mismo podría hacer un npm install, no instalaría cypress, pero en cuanto haga un npm run test end to end, ahora sí, voy a hacer esto un poquito más grande, ahora dirá, me va a preguntar y todo.
Oye, ¿quieres que instale realmente cypress? Porque claro, tengo que instalarlo si quieres que ejecute este comando.
Vamos a ver si funciona.
Vale.
Ah, bueno, será que ya lo ha detectado por algo, no sé por qué, pero ya lo tenía instalado.
Claro, puede ser que haya hecho un npx antes de cypress y ya esté la dependencia en el directorio temporal.
Si no lo tienes, aquí te preguntará y te dirá, oye, ¿quieres que instale cypress? Le dices que sí y ya está.
Aquí ahora me está fallando porque me dice que no encuentra la configuración de cypress y todo esto.
Vale, no pasa nada, pues la configuración de cypress, se le pueden pasar opciones para que no te pida la configuración.
Pero bueno, le vamos a dar la configuración que sea vacía para que se deje quejar y lo que vamos a hacer es crear aquí nuestros test de integración.
Va a ser un test de integración bastante sencillo.
En cypress barra integration barra app.js, aquí, ¿ves? En este directorio vamos a crear nuestros test de integración.
Aquí hay un tema importante. No pongas .spec ni .test porque como está utilizando jest el proyecto, se liaría y entonces podría intentar ejecutar los test de cypress.
Este es el directorio por defecto que utiliza cypress, pero si no te gusta puedes configurar justamente aquí en cypress, le puedes poner la configuración que quieras.
No me acuerdo ahora cuál era la configuración, pero creo que eran integration folder o algo así.
Bueno, como no te he dado autocomplete, pero bueno, que lo puedes configurar si no te gusta justo esta carpeta.
Vamos a poner un test que sea bastante fácil. Voy a ejecutar otra vez npm start.
Vamos a ver un poco lo que podríamos testear.
A ver qué tenemos por aquí.
Vale. Mira, aquí al fondo no se ve, pero vamos a hacer dos cosas.
Uno, ¿ves que aquí hay este string? Pues este string lo vamos a... vamos a ver si contiene este string y vamos a buscar un Pokémon aquí random, ¿vale?
Eso es lo que vamos a hacer para asegurarnos que funciona correctamente nuestra aplicación.
Así que hacemos un describe, le llamamos Pokédex y aquí pues tenemos una función y en la función vamos a hacer que la página de frontal pues can be open, ¿vale?
Al menos vamos a asegurarnos que se pueda abrir.
Vale, esto lo hacemos por aquí y aquí pues vamos a hacer que... ¿Cuál es la página que tiene que visitar?
La página que tiene que visitar sería http localhost 5000.
Lo que tengo que hacer es ver si hay alguno que contiene al Pikachu, por ejemplo.
Bueno, espérate, espero que esté Pikachu.
Pikachu, vale. Pikachu.
Y luego el ccontains que tenga la frase esta que he dicho que salía al fondo.
Vale, esto por un lado. Bueno, ahora se me queja por el tema del linter. Fíjate que me dice CI is not defined.
Aquí tienes diferentes opciones. Una, instalarte el plugin de Cypress, que sería lo correcto seguramente,
o hacer lo que voy a hacer yo para ir por faena, que es poner aquí una global de CI.
O sea, esto lo que hace es indicarle al linter que hay una variable global que es esta de aquí que la vas a utilizar en tu fichero.
Bueno, de esta forma deja de preguntarte. Pero lo mejor sería utilizar el plugin porque de esta forma tendrías autocompletado de esta variable global y todo esto.
Pero bueno, como esto va a ser todo lo que vamos a hacer de Cypress, ya está bien.
Muy bien. Vamos a quitar esto. Entonces, hacemos la build para que nos pille todos los últimos cambios que hemos hecho arreglando los tests.
Hacemos el npm run start test.
¿Vale? Ahora lo tenemos en el puerto 5000. Vamos al puerto 5000.
Parece que funciona. Por lo tanto, voy a abrir otra pestaña y vamos a ejecutar los tests en tuen para ver si pasan.
A ver si todo funciona correctamente.
Y esto es lo mismo que haremos en Continuous Integration.
Pero bueno, está bien que justamente te asegures primero si en local todo funciona bien, porque si no es un poco rollo.
¿Vale?
¿Ves? Esto es lo que comentaba antes. Antes alguien me preguntaba, ¿cuál es la diferencia si con Cypress puedes hacer todos los cambios?
Porque no nos haces todos los cambios en Cypress, o sea, todos los tests en Cypress, en lugar de hacer los unitarios.
Y este es el tema, ¿no? Es que los tests, los end to end, son más lentos que los unitarios o incluso los de integración.
Aquí podemos ver cómo ha tardado 8 segundos, o sea, hacer un test que es bastante sencillo.
No escala muy bien. Tienes que hacer test de end to end para funnels que sean muy importantes y críticos para tu aplicación.
Porque el problema es que le lleva demasiado tiempo.
Si tú te pones a hacer todos los tests aquí, pues no va a tardar demasiado tiempo.
No va a tardar muy poco tiempo, sino que se va a tomar su tiempo.
Lo bueno, pues que puedes hacer que guarde vídeos. Por ejemplo, mira, aquí me ha guardado un vídeo.
Vamos a ver si me lo pone. ¿Ves? Me guarda un vídeo y aquí te debería enseñar un poco la aplicación.
¿Qué es lo que ha hecho, no? Bueno, no sé, a ver si ve.
¿Vale? Visitar la página. Ahora deberían ser aquí los pokémons.
Entonces ahora mirar cada paso es súper potente, la verdad.
Pero el problema, ¿ves? Ahora ha encontrado el Pikachu y ha encontrado el Pokémon a un Pokémon carácter.
Pero el problema es que es bastante lento. Pero bueno, si hay un error, pues tienes el vídeo y es bastante genial.
Ahora que ya tenemos esto en local, ya tenemos el test end to end, perfecto.
Pero justamente fíjate cómo se llaman los tests de Cypress.
Integration. Esto no es casualidad. Esto no es casualidad.
Y es que los tests end to end, claro, tenemos tests de integración.
Pero cuando hablamos de Cypress, de integration y tal, es porque justamente la gracia que tienen estos tests end to end
es que acaben en continuous integration.
Porque son los que se van a asegurar que gran parte del funnel, de la experiencia del usuario, funciona correctamente.
Así que vamos a añadirlos a nuestro pipeline. No iban a ser menos.
Para añadirlos, pues nada, lo mismo. Vamos a crear aquí un name.
Luego esto lo vamos a refactorizar y vas a ver lo bonito que queda.
Vamos a poner los tests.
Y aquí vamos a utilizar otra GitHub Action.
Así que vámonos a nuestro marketplace.
Que por cierto, las actions antes le hemos dejado...
Vale, estaba en verde cuando he hecho el fix.
Digo, a ver si lo hemos dejado en rojo y yo me he puesto aquí a ver a hacer otras cosillas.
Vale, vámonos al GitHub Marketplace.
Este de aquí.
Y vamos a volver a buscar aquí a ver si tienen algo con Cypress.
Y obviamente debería...
Pensaba que iba a salir mucho más fácil.
Porque Cypress tiene su propia...
Cypress.io.
A ver.
By Cypress.io.
Creo que es este.
Este sí.
Este es de los propios creadores de Cypress que tienen una GitHub Action.
Pues aquí lo tenemos.
Vale.
Pues tiene su propia acción.
Y como podemos ver, es súper sencillo de utilizarlo.
Y es el que vamos a utilizar para no tener que nosotros configurar Cypress.
Cypress normalmente en Continuous Integration, tanto Travis, GitHub Actions, Jenkins y tal, suele ser un rollazo.
Suele ser bastante complejo.
¿Por qué suele ser bastante complejo?
Porque necesita instalar Chrome o Firefox o lo que sea.
Y para compilar Chrome y este tipo de navegadores en Ubuntu, pues necesitas librerías, dependencias...
Es un rollo.
Así que mi recomendación es que utilices esta acción y te vas a olvidar totalmente de configuraciones.
Y suele funcionar bastante bien.
Así que vamos a usarla.
Vamos a poner aquí en el Uses.
Vamos a utilizar esta acción, GitHub Action, la versión 2.
Hay una cosa que no he comentado antes y es bastante importante con el tema de las acciones.
Que como puedes ver, las acciones están versionadas.
Y la versión es bastante importante, más de lo que parece.
Porque claro, piensa que hay una versión 1, una versión 2 y cada versión puede tener sus opciones y configuraciones distintas.
Y puede tener breaking changes.
O sea, lo que antes funcionaba, mejor no funciona en la nueva versión.
De hecho, igual que esto, evitad siempre utilizar las acciones así.
Se puede utilizar, pero el problema es que esto lo que va a hacer es utilizar siempre la latest.
Si esto pasa, cuando salga la versión 3, pues la puede liar parda y dejar de funcionar el Continuous Integration.
Y no hay nada peor que el Continuous Integration deje de funcionarte de golpe.
Eso lo que va a hacer es bloquear al equipo de trabajo.
Así que asegúrate de al menos, al menos como mínimo, porque también puedes llegar a utilizar el hash del commit,
pero al menos de indicar la versión major.
Por si cambian la versión major, pues que no se rompa.
Así que aquí, igual, ves que pongo arroba versión 2.
Y así nos aseguramos que está utilizando justamente la versión que queremos de Cypress.
Esta GitHub Action, de la misma forma que hemos hecho esta acción aquí con este width y este width,
esta action también se puede configurar.
Así que le podemos poner aquí un width y le vamos a indicar diferenciación de configuración.
Primero, le podemos decir cuál es el comando que tiene que ejecutar para inicializar los tests end-to-end.
Pues le decimos comando. ¿Cuál es el comando que quiero que ejecutes?
npm run test end-to-end.
Porque si vamos a nuestro package.json, este es el comando justamente que ejecuta los tests end-to-end.
¿Qué más le podemos decir?
Vale, los tests end-to-end, como has podido ver, que he tenido que hacer yo aquí,
he tenido en la terminal esta, he tenido que levantar la aplicación para pasar los tests end-to-end.
Por lo tanto, antes de pasar los tests end-to-end, tenemos que levantar la aplicación.
¿Cómo hacemos esto? npm run start test.
Este run start test es justamente el que he añadido aquí y también creo que es el que he utilizado antes aquí,
si no me equivoco.
No sé si he utilizado... sí, aquí.
npm run start test, he levantado la aplicación y luego he ejecutado los tests end-to-end.
¿Qué más le podemos decir?
Vale, le podemos decir que es...
¿Es wait-on?
Sí, wait-on, así.
Vale.
Lo que le podemos decir también es dónde está el servidor y que tiene que esperar que se levante
antes de ejecutar los tests end-to-end.
En nuestro caso, http localhost 5000.
¿Por qué localhost 5000?
Bueno, esto no es una cosa que venga de la nada, sino que si vamos a nuestro app.js,
aquí tenemos el puerto, si no le indicamos ninguno, utiliza el 5000.
Y como este es el puerto por defecto...
Por cierto, que esto está mal.
Esto debería ser así.
Porque el puerto puede cambiar.
Pero bueno, era una tontería.
Entonces, si no se le pone ninguno, será el puerto 5000.
Pues así que, si no le pongo ninguno con el start test, será el puerto 5000.
Y con esto ya tendríamos todo el tema de los tests end-to-end.
Así que vamos a ver si funciona correctamente.
Voy a cerrar esto, voy a cerrar esto también.
Vamos a mirar todos los cambios que tengo.
Keyhub, vale.
Hay una cosa aquí que es importante para...
Claro, porque ya la iba a liar.
Cuando tú ejecutas Cypress en local, fíjate la de archivos que te ha creado.
¿Ves?
Me ha creado aquí un montón de archivos.
Este sí que es normal, este es el nuestro.
Vale.
El app.js he hecho este pequeño fix.
La configuración de Cypress vale.
En el package.json hemos añadido los scripts que necesitamos.
Perfecto.
En el pipeline hemos añadido los tests end-to-end.
Vale.
Pero estos archivos de aquí, estos archivos son...
Que los ha creado Cypress al vuelo.
Estos archivos no los necesitamos.
Para evitar que los subamos sin ninguna necesidad, especialmente el vídeo.
Que haría que todo fuese bastante más lento.
Lo que vamos a hacer aquí es poner Cypress y lo que vamos a decirle es que Cypress plugins fuera.
Cypress barra support fuera.
Cypress barra videos.
Y estos vamos a hacer que no los suba, que los ignore.
Y con esto, bueno, el support luego podría...
Y plugins puede ser que luego tenga sentido, pero en nuestro caso no tiene ningún sentido.
Así que vamos a evitarlo para que no los suba sin ninguna necesidad.
Porque son generados y no nos añade nada.
Vamos a añadir el gitignore también.
Bueno, lo vamos a añadir después.
Add end-to-end test to deployment pipeline.
¿Vale?
Y aquí en el gitignore, pues ignore Cypress folders.
Ahora puxamos los cambios.
Y volvemos a nuestro repositorio, a actions.
Vamos a...
Bueno, aquí saldrá en amarillo.
Vámonos al deployment pipeline.
Y esto tardaría un ratito.
Así que mientras se ejecuta, os voy a leer.
A ver qué me contáis mientras bebo también.
Empieza a tardar más, ¿vale?
Ya vamos viendo que nuestro continuous integration le empieza a costar un poquito más.
Entonces, podemos ver un poquito las instalaciones 21 segundos, el linter 2 segundos, la build 5 segundos, el test unitario 3 segundos y los end-to-end ya es 1 minuto 21.
Lo vamos a ver y podemos ver que ha funcionado correctamente.
Como os decía, la instalación...
Aquí también está haciendo la instalación de Cypress.
Fíjate aquí, ¿vale?
La instalación, pues 8 segundos.
8 segundos que nos hemos quitado del otro lado, pero bueno.
Y luego además, pues va a estar dando otras cosas.
Luego levanta.
Ejecuta el test 12 segundos.
Cosas así, ¿no?
También es verdad que está haciendo el vídeo y el vídeo no es necesario.
Igual esto lo podríamos...
Voy a hacer...
Ahora lo voy a quitar.
De hecho, en Cypress.config podríamos ver y quitar el vídeo es bastante útil porque es muy difícil que tengamos acceso al vídeo.
Así que, ¿ves?
Vídeo por defecto es true.
Pues puedes hacer dos cosas.
Una, desactivar el vídeo completamente o que el vídeo solo sea para los errores.
Eso también puede ser interesante.
A ver, vídeos folder...
Había uno que era vídeo...
¿Ves?
Vídeo upload on passes.
Claro, para los que van bien no tiene mucho sentido el vídeo.
Pero bueno, nosotros lo vamos a desactivar porque no tiene mucho sentido que nos guarde un vídeo ahí para nada.
Vamos a ponerlo aquí en la opción.
Vídeo.
False.
Antes os he dicho que íbamos a probar otra cosa para mejorar el npm install.
Pues lo vamos a hacer.
El tema es que cuando tú tienes un package lock, lo que puedes hacer en lugar de hacer un npm install,
el package lock lo que es es como un package JSON pero hipervitaminado
que lo que hace es indicar exactamente qué versiones ha instalado,
en qué orden lo ha hecho, justamente el hash que tiene de integridad.
O sea, es mucho más avanzado.
Y lo que permite es evitar mucho trabajo.
Así que el npm install lo que hace es ir más rápido.
Pero en continuous integration justamente npm tiene un comando que se llama npmci,
de continuous integration.
O sea, ya lo dice el nombre exactamente.
¿Y qué es lo que hace npmci?
Pues lo que hace es ejecutar npm install de una forma mucho más optimizada
basándose en las dependencias que tienes en el package lock.
Entonces la resuelve mucho más rápido, hace muchas menos comprobaciones
porque no tiene que calcular cómo queda el árbol de dependencias.
Y esto lo que debería hacer es hacer que nuestra continuous integration vaya un pelín más rápido.
Vamos a hacerlo, vamos a poner optimice ci with npmci and video cypress to false.
Vamos a enviar esto y vamos a ver si ahora funciona un pelín más rápido de cómo lo ha hecho antes.
Aquí ha tardado dos minutos, pues ahora veremos si el siguiente tarda un poquito menos.
Entonces, mientras va pasando y antes de ver todo esto, de cuánto ha tardado,
que bueno, el npm install sí que lo podemos ver porque debería ser más rápido,
tampoco tarda mucho.
Ya os digo que proyectos realmente grandes puede tardar segundos y segundos.
En este caso, ¿ves? No hay mucha diferencia.
De hecho, parece que va a tardar exactamente lo mismo que antes.
O incluso parece que más.
O sea, está tardando más.
Más o menos lo mismo.
No me parece que...
Ah, pero es que no he guardado los cambios.
No he guardado los cambios.
Ay, npm install with ci.
Vale.
Es que no he guardado los cambios.
Pero bueno, con esto voy a enseñar otro tema que es bastante interesante
que también vamos a arreglar ahora un momentito.
Fíjate que yo he hecho otra vez un push de mis cambios.
Por lo tanto, he emergeado en main cambios.
Y aquí se me están acumulando los workflows.
Bueno, justo está cambiado.
Pero este y este se están ejecutando a la vez.
¿Qué pasaría si yo tengo dos acciones, dos workflows que se están ejecutando y los dos se despliegan?
Y resulta que el último que se despliega es el más viejo, o sea, este.
Imagínate que este termina antes y de repente este sigue ejecutándose y se despliega.
Pues tendríamos un error.
Porque tendríamos en producción una versión de nuestra aplicación anterior y no la última.
Esto que veis aquí, esto que está pasando aquí es súper peligroso.
En continuous integration hay que evitar que un mismo workflow tenga más de una versión ejecutándose a la vez en paralelo.
Y para eso veremos después cómo podemos utilizar una acción súper fácil para evitarlo.
Pero antes de hacer esto, lo que vamos a mirar, voy a mirar si el en pie visto la pesa ha mejorado un pelín.
16 segundos.
Antes estaba sobre los 20 segundos.
Bueno, unos segundos que hemos arrastrado.
Y ahora veremos el end to end.
Antes de intentar evitar que haya builds redundantes, lo que vamos a hacer es hacer el deploy con Heroku.
Así que vamos a ello.
Voy a cerrar también otra vez todo esto.
Y nos vamos a ir a la terminal primero.
Si no tienes una cuenta de Heroku, te la puedes crear.
Es totalmente gratis.
No deberías tener ningún problema.
Para hacer esto, vamos a tener que empezar a conocer qué son los secrets.
¿Cómo podemos guardar variables de entorno para GitHub Actions?
Es súper fácil, pero te voy a explicar además por qué podemos tener entornos diferentes.
Primero vamos a conseguir el token de Heroku.
Así que le damos a Heroku, create.
Vamos a crear una aplicación en la región de Europa y le ponemos el nombre de nuestra aplicación.
Vamos a poner Midu.
Mira qué grande que tiene aquí mis aplicaciones.
El autocomplete de FIC es brutal.
Vamos a poner Midu CIGH.
¿Vale?
Contiguous integration.
GitHub.
Oh, ja.
De GitHub Actions.
Midu CIGH.
Vale.
Vamos a crear esta aplicación.
Vamos a ver.
Vale.
Perfecto.
Podríamos entrar, y esto no hay ninguna aplicación ahora mismo.
Veremos si conseguimos desplegarla ahí.
Y ahora lo que podemos hacer es recuperar un token.
Así que hacemos Heroku, authorizations, dos puntos, create.
Esto lo que va a hacer es crearnos un token que nos permitirá justamente hacer el despliegue.
Este token debería ser totalmente privado.
Yo luego lo eliminaré.
Pero bueno, es este de aquí.
Lo vamos a copiar.
Y vamos a ir otra vez a nuestro repositorio.
A ver cuánto ha tardado.
Mira, ahora el end to enter se ha tardado 49 segundos.
Ha tardado 40 segundos menos que antes.
Estamos ahí poco a poco optimizando, optimizando.
Vale.
Vámonos a Settings.
Y aquí vamos a ver que tenemos Secrets y tenemos Environments.
En Secrets ya no dice Action Secrets.
O sea, son tokens secretos que podemos tener para nuestro GitHub Actions.
Podemos tenerlas a nivel de repositorio para tener como unos secretos que sean en general.
O lo podemos tener por Environment.
El Environment es súper útil para este caso.
¿Por qué?
Porque puedes tener variables de entorno para producción y para preproducción, por ejemplo.
Vamos a poner un ejemplo.
Voy a crear para el repositorio.
Vamos a poner aquí Heroku API Key.
Y aquí pongo el token que tengo.
Ahora, imagínate que por lo que fuese, este es el que tengo por defecto,
pero podría tener uno que fuese para el entorno de producción.
Este sería el general que podría utilizar.
Pues en Environments podría crear aquí un New Environment, poner Production,
configurar Environment.
Aquí podrías configurarlo justamente para evitar que cualquier persona pueda hacer un push al workflow
y que se ejecute en ese entorno.
Y aquí podríamos añadir un secret.
Pues le das aquí.
Y aquí podríamos sobreescribir justamente el que hemos añadido.
Y aquí le podríamos poner otro diferente.
Para que producción se despliegue en otro sitio diferente al que tiene en general.
En nuestro caso, como solo vamos a tener el de general, pues lo vamos a dejar así.
Pero bueno, es interesante que lo conozcas.
Vamos a añadir más.
Vamos a poner Heroku API Email, que es mi cuenta.
Vamos a poner otro más, que es Heroku App.
Que si no me equivoco, a ver qué he creado por aquí.
Midu CIGA.
Vale.
Estos son los tres secretos que vamos a necesitar.
¿Por qué la app la pongo aquí?
Lo mismo, ¿no?
Porque podríamos tener la app para preproducción, que fuese diferente a la que es de producción.
En este caso lo vamos a poner en general, pero es bastante útil que lo tenga diferenciado.
Ahora, vamos a irnos a nuestro pipeline, porque era de despliegue.
Pues vamos a conseguir que se despliegue, ¿no?
Venga, lo mismo.
Name.
Aquí vamos a poner deploy to Heroku.
Y vamos a poner que esto usa...
Uy, digo, a ver si me lo encuentra.
Me lo llega a encontrar Gijacopilot automáticamente.
A ver.
No.
Pensaba que a lo mejor si le daba una pista lo conseguía.
Pero no.
No lo he conseguido.
Bueno, vamos al marketplace y ahora encontramos uno.
Heroku.
Heroku deploy.
Heroku deploy.
A ver si encontramos el que conozco.
Vale.
Mira, aquí tenemos.
Deploy to Heroku.
Por desgracia, Heroku no tiene, o que yo sepa, no tiene una action que sea oficial.
Entonces, la que yo he visto que mejor funciona, y de hecho ya se ve por las estrellitas que tiene, es esta de aquí.
No sé si Heroku en algún momento sacará suya propia, ya me extraña que no tenga.
Pero bueno, esta es la que a mí personalmente me ha funcionado y la que os recomiendo que utilicéis.
Así que vamos a copiarnos esto para utilizar esta Heroku deploy de Akhilensen.
Y aquí justamente tenemos las tres que necesitamos.
Las tres secrets y tal.
Y ahora te explicaré cómo funciona el tema de los secrets.
Vamos a poner esto por aquí.
El uses este no necesitamos.
El comentario lo quitamos.
Los secretos que he creado en GitHub, para acceder a ellos, lo único que tienes que hacer es secrets.
Y poner el secreto al que quieres acceder.
O sea, que yo aquí cuando he creado mis secretos, tenemos Heroku API Key, pues este lo haríamos secrets.
Bueno, este encaja.
Ahora, el app name.
Bueno, pues esto lo mismo.
Teníamos que poner el dólar, llaves, llaves, lo cerramos.
Y aquí secrets punto y utilizamos justamente el que sea nuestro.
Aquí Heroku app.
Y aquí en el email, pues sería lo mismo.
¿Vale?
Esto lo bueno que tienes es que una vez que lo configures por entornos y tal, esto te lo detecta automáticamente.
Y el environment lo puedes configurar aquí.
Y lo puedes hacer a través de objetos del contexto y tal, que luego veremos un poquito cómo se saca esa información del objeto del contexto.
¿Vale?
Y en el email, pues el API email.
No sé por qué le he puesto API email, pero bueno, con esto no debería funcionar.
Con esto ya tenemos nuestro deploy a Heroku.
Vamos a añadir aquí add Heroku deploy.
Vamos a pushear los cambios.
Vamos a nuestro repositorio.
Vamos a quitar todas estas cosas.
Esto fuera.
Esto fuera.
Esto fuera.
Fuera.
Vamos a nuestro repositorio.
A ver si lo encuentro.
Ah, mira.
Menos mal que hay gente que le ha dado aquí y así lo tengo por aquí.
Vale.
Vale.
Pues ya está aquí pensando.
Esto me debería fallar.
Y ahora veremos cómo lo podemos solucionar.
Y cómo hacemos algo más para que no nos vuelva a ocurrir el error que va a cometer ahora.
¿Vale?
Así que os leo un momentito.
¿Alguna action?
Vale.
Eso ya lo he leído.
¿Quién es este último Pokémon?
Yo, como no me los conozco ya, los he perdido un poco de vista a los pobres Pokémon.
Si es que en Sensitive te va a fallar Pikachu.
No, canallazo.
Porque es una buena observación la que ha hecho canallazo.
El caso es que en el test, este, integration, yo he puesto aquí Iptazo.
Venga.
Se está ejecutando.
¿Ves?
Tarda un montón.
Tarda un montón el deploy de Heroku.
La verdad es que Heroku no está muy bien resuelto para el tema de los deploys continuous integration.
Se está quedando bastante atrás.
A mí personalmente no es el hosting que más me guste.
Pero bueno, este proyecto es un proyecto de Node.
Y tal y como está pensado, el mejor sitio para desplegarlo justamente es Heroku.
Entonces, podemos ver que se ha ejecutado correctamente.
Ha hecho la build.
Aquí un montón de cosas.
Ha instalado las dependencias.
Pero, fíjate, ¿vale?
Se ha desplegado correctamente.
Esto debería funcionar.
Pero, si yo me voy a ver cómo era el app name.
¿Cómo era mi proyecto?
A ver, aquí.
Este proyecto.
Si entro, fíjate que tengo un application error.
O sea, acabamos de desplegar algo que no funciona.
Bueno, vamos a ver aquí en Heroku Logs.
Por suerte tenemos este comando.
Pero vamos a evitar que esto no vuelva a ocurrir, ¿vale?
Vamos a Heroku Logs.
Tail.
No, Tail no, porque nos dice lo...
Bueno, sí, nos dice lo último.
Fíjate, aquí me dice el error.
Mira, me dice que ha intentado hacer un npm start y me dice que webpack devserver not found.
Vale.
¿Qué es lo que ha pasado?
¿Cómo podemos solucionarlo?
¿Cómo lo vamos a solucionar?
¿Y qué es lo que ha pasado?
Lo que ha pasado es que por defecto Heroku lo que hace es ejecutar este comando aquí, npm start.
Pero Heroku solo instala las dependencias de producción, no las de desarrollo, porque se supone que no las necesita.
Entonces, este start, como está utilizando esta dependencia de desarrollo, no la encuentra.
Aquí lo que deberíamos hacer más bien es que esto, en lugar de ser start, sea dev.
Y este start prot lo vamos a cambiar a start.
Pero esta es la solución, ¿no?
Con esto lo solucionaríamos.
Vamos a ir un poquito más allá.
Aparte de hacer esto, de arreglar cómo va a encontrar bien correctamente Heroku la aplicación para iniciarla,
lo que vamos a hacer es añadir a nuestra aplicación un health check.
Esto es súper importante y súper básico, por tonto que parezca.
Hay mucha gente que no lo hace y debería eso.
Vamos a crear dos.
Vamos a crear el health y vamos a crear el de la versión también, ¿vale?
Mira, un health check básicamente es una ruta, vamos a ponerle health,
que lo que hace es responder diciendo que funciona correctamente.
¿Por qué?
Porque con este health check nosotros hubiéramos evitado un montón de problemas.
Ya hubiéramos evitado el problema de intentar deployar algo que no funciona.
Incluso cuando no funcione vamos a poder hacer un rollback,
que eso es bastante fácil hacerlo con esta acción de Heroku y nos puede evitar problemas en producción.
Así que tenemos este health.
Lo único que hacemos cuando entramos en este health es decir, ok, además de este,
también puedes tener uno que sea versión.
Y aquí hay un trucazo que está muy chulo, que tú puedes recuperar la versión del Package.json.
Package.json.
Que lo teníamos aquí, Package.json.
En el Package.json esta versión de aquí la puedes recuperar de forma que cada vez que cambie la versión
tú podrías indicarle a partir de este endpoint qué versión es la que está desplegada en producción.
Así que puedes hacer esto y ya lo tendríamos.
He puesto un más ahí, ¿vale?
Y ya tendríamos nuestros dos endpoints.
Uno el del health check y otro el de la versión.
A ver, no creo que haga...
Bueno, vamos a hacerlo.
Bueno, no lo iba a levantar, pero he pensado, venga, va, qué más da.
Puerto 5000, health.
¿Vale?
Aquí tenemos un OK.
Y luego si hago versión, esto debería aparecer 1.0.0.0.
¿Vale?
De esta forma, pues podremos saber la versión que se ha desplegado.
Hay un montón de formas de la versión de hacerlo, pero bueno, esta sería una de las formas más sencillas.
Tener un endpoint que te diga la versión que hay en producción y ya está.
Puede ser un endpoint que no digas cuál es y en lugar de llamarle versión que sea un endpoint mucho más largo.
Ahora que tenemos el health check y el tema de la versión, vamos a volver a nuestro pipeline.
Y aquí en las configuraciones de Heroku, además de esto, vamos a poder decirle, mira, pues vamos a tener un health check y te voy a decir dónde está la ruta.
Esto va a estar en https, barra, barra, Heroku App.
¿Vale?
Luego ponemos barra, health.
¿Qué es lo que va a hacer con esto?
Pues va a mirar si realmente la aplicación, una vez que la despliega, el health check responde.
Y si no responde, lo que podemos decirle es un rollback on health check fail.
Y esto lo voy a buscar porque no estoy seguro si esto es así.
Heroku Github Actions.
¿Vale?
Mira, sí.
Rollback health check fail.
¿Vale?
Cuando es true, lo que va a hacer es un rollback.
¿Qué es un rollback?
Un rollback es que automáticamente Heroku va a decir, vale, el health check no funciona, voy a hacer un rollback.
O sea, voy a tirar para atrás los cambios y voy a poner en producción una versión anterior que debería estar funcionando.
Esto es un rollback, además, totalmente automático.
Así que le vamos a decir true y ya tendríamos esto.
Ahora que tenemos esto, bueno, para que veas el rollback, lo mejor es que pongas Heroku releases.
Y aquí deberíamos ver todas las releases que se han hecho.
En este caso son releases que no han funcionado por el problema que teníamos antes.
Pero ves, initial release, deploy, no sé qué.
Y estas son todas las releases.
Cada vez que vayamos haciendo despliegues y despliegues y despliegues, pues iremos viendo que cada vez hay más.
Vamos a pushar estos cambios con el health check, add health check, undo rollback if not working.
Y con esto debería, además del cambio del npm start y esto, todo debería funcionar bien.
Mientras se va haciendo, vamos a seguir trabajando nosotros en otra cosa.
Vamos a dejar ahí la action que vaya haciendo su magia.
Ahora, aquí lo tenemos, que está haciendo su magia, como tarda un ratito, mientras vamos a hacer nosotros otra cosa.
Porque, ¿qué pasa? Esto está muy bien.
Todo lo que hemos hecho está fantástico.
Pero claro, alguien me diría, oye, ¿qué pasa si resulta que tú haces aquí?
Vamos a crear una nueva... voy a hacerlo aquí.
Vamos a crear una nueva rama que sea, no sé, add new feature.
¿Vale? Abro una nueva rama, y en esta nueva rama voy a añadir un cambio cualquiera, que es este de aquí.
Bump version.
Voy a pushar estos cambios en una rama y voy a crear una pull request.
Add new feature.
Creo la pull request.
¿Y cuál es el problema?
Pues que nuestra acción no está funcionando aquí.
No funcionan las pull requests.
¿Por qué no funcionan las pull requests?
Pues, porque justamente en el pipeline, si le echamos un vistazo, hemos dicho que esto debe funcionar cuando se haga push a la rama main.
Pero es que una pull request, esto, está pidiendo hacer el push, pero todavía no lo ha hecho.
Así que tenemos que indicarle un nuevo evento.
No solo podemos admirarlo en el push, sino que tenemos que añadir un nuevo evento que sea pull request.
Como puedes ver, tienes pull request cuando se hace una review, cuando se abre una pull request.
En este caso, pull request.
Cuando se hace una pull request de la rama, en este caso main, esta sería la otra forma de hacerlo.
Mira, se puede hacer así, que es como lo habíamos hecho antes, o lo puedes indicar aquí como un array.
Así que ponemos main, y aquí también vamos a ponerlo main, porque creo que se le...
A mí me gusta más esta forma de hacerlo, con un array directamente.
Así lo tenemos así.
Y aquí en types, además quedará mucho mejor.
Podemos decir cuando se ha abierto y cuando...
Mira, puedes decir cuando se ha abierto, cuando se ha asignado, cuando se ha cerrado, cuando...
Puedes decir cuando se ha sincronizado.
¿Vale?
Cuando se han vuelto a sincronizar los cambios.
Solo cuando se abre y cuando se le envía un nuevo cómic, cuando se sincroniza, con lo que sea.
Con esto, ahora sí, si voy a subir estos cambios, vamos a la terminal.
Vamos a decir add o listen pull request event for pipeline.
¿Vale?
Puseamos este cambio.
Y ahora, si vamos a la pull request, fíjate que ahora pone this branch has no conflict with base branch.
Parece que no ha pasado nada.
Voy a refrescar, voy a refrescar la pull request.
Y fíjate que ahora dice que hay unos checks que no se han completado.
Y es que está pasando aquí justamente el pipeline que hemos configurado antes.
Y está instalando las dependencias, está haciendo el linter, va a hacer la build, el test, hará el end-to-end y hará el deploy.
¿Y queremos que haga el deploy?
¿Queremos que haga el deploy y la pull request?
No, pues cancelamos el workflow que si no la liamos parda.
No queremos que haga el deploy, ¿vale?
Cáncélate, cáncélate, hazme caso, cáncélate.
Vale, ahora sí, se ha cancelado.
No queremos que haga el deploy.
Así que antes, lo he cancelado, el de la pull request, antes de que la lia parda y me haga un deploy donde no debe.
¿Cómo podemos evitar que me haga un deploy en la pull request?
Que no es lo correcto, ¿vale?
Ahora le hemos dicho que sí, que tiene que escuchar las pull requests.
Pero los jobs se están ejecutando todos.
Pues existe una forma de indicarle estos pasos que tiene el job, cuál es el que se tiene que ejecutar, dónde.
Vale, para eso puedes utilizar un campo que se llama if.
Y tú aquí puedes hacer mil millones de cosas.
Una de esas cosas es utilizar justamente otra vez lo de la evaluación con las llaves, el dólar y las llaves.
Existe un objeto en la GitHub Actions que tiene toda la información, o sea, digamos que tiene todo el contexto de donde estás trabajando.
Tiene un montón...
Uy, este se ha puesto en rojo.
Espérate.
Espérate, que es que no sé si es el...
A hatchet undo rollback.
Vale, vamos a ver qué ha pasado.
¿Qué ha pasado aquí?
Hatchet...
Has been rollback.
Please check your logs.
No sé qué es o cuánto.
Vale, vamos a ver qué ha pasado aquí.
Que parece ser que no le ha gustado lo que...
Heroku logs.
Vamos a ver qué ha pasado.
¿Qué es lo que ha pasado?
Ah, y ha vuelto a hacer esto.
¿Será que no he guardado los cambios antes?
En el package.json.
El start.
No, esto sí que lo he hecho bien aquí.
A ver, espera.
Parece que no ha hecho el deploy este.
Health check.
Vamos a ver los commits.
A ver si...
Add health check.
No sé qué, no sé cuánto.
Pero aún así, fíjate que me ha recuperado lo anterior, ¿eh?
Aquí en el Heroku logs este, ¿eh?
Know the app.
Rollback to versión 3.
Release 5.
Creative user restarting.
¡Ostras!
Fíjate que no me la ha hecho, ¿eh?
Este build started...
Mira, aquí sí que parece que dice server started on port 74.15.
Claro.
Bueno, esto es normal.
De que haga el 74.15.
Vamos a ir a Heroku.
Un momento.
A ver qué le ha pasado.
¿Qué le ha pachado esto?
Heroku testing...
Uy, no me sale...
Ni siquiera me sale el mío.
No me sale mi app.
Vamos a ver cómo lo había llamado.
Testing, testing...
Vamos a ver las releases.
Sí, podemos ver.
MiduCIGA.
Heroku app.com
Sí, no.
A ver.
Eno end.
A ver, esto es porque ha hecho después el rollback.
Pero al principio sí que parece que había hecho el no de app,
que había funcionado bien.
Lo único que...
Bueno, vamos a...
Para eso no funciona.
Para eso es el continuous integration.
Así que vamos a ver en la action
cuándo ha fallado.
Si había hecho la build y todo esto.
Vamos a ver.
Build.
La build.
Mientras os voy a leer también.
A ver si notáis dónde estaba el error.
Te hizo el rollback.
Sí, no.
Me hizo el rollback, pero porque falló el otro.
Falló el otro.
O sea, falló.
Cuando hice la release del 4, hizo el deploy to Heroku.
Eso debería haber hecho el deploy correctamente.
Coat and...
Trolling back to versión 3.
Es súper raro porque parece que todo ha funcionado bien.
O sea, espérate.
A ver si el...
Espérate.
HTTPS barra health.
A ver si el health check lo he puesto mal.
¿Sabes?
Dos puntos barra Heroku app.
Que igual el health check este que he puesto aquí está mal.
Lo que me extraña es que...
Ah, está aquí.
Vale, vale.
Ahora he visto.
Vale.
Vamos a ver en activity.
Rollback to versión 3.
Voy a hacer un rollback a la versión que yo quiero.
A ver si...
Build, build lock.
Bueno, esto es justamente lo mismo.
Lo que quiero ver es justamente si el midu este...
A ver si puedo ver...
Open up.
Es que sí que funciona bien.
Es como si el health...
El health está bien.
No sé, no sé.
Es como si esta app no hubiera detectado...
No es exactamente esta que está aquí.
O sea, que a lo mejor está mal el tema este de la opción.
Vamos por aquí.
En settings.
A ver si he puesto mal el secret o yo qué sé.
Vámonos a secrets.
El Heroku app no tiene toda la URL.
Ahí está.
Ahí está.
Ese es el problema.
Muy bien.
Bien visto.
Claro, el problema es que este Heroku app no tiene toda la URL.
Cuando ha intentado ir aquí...
Claro, yo he hecho esto.
Y esto...
Yo he sido super happy.
Lo que tiene que hacer es esto.
Esta parte solo tiene el nombre del subdominio.
¿Vale?
Entonces, donde tiene que mirar el health es en esta parte.
La verdad es que no sé si aquí podríamos incluso poner esto.
Pero bueno, vamos a ponerlo así.
Aquí ahora sí.
Esta es la parte del app name.
Que es el midu cgi a este.
Luego tenemos aquí esto.
Y luego barra health.
Pero mira, así hemos solucionado un error aquí en vivo en directo.
Creo que esto es lo mejor.
El que venga con un problema y ver cómo se soluciona de forma real.
Vale.
Lo arreglaremos en la PR.
¿Vale?
Y la PR luego lo mergearemos y tal.
Pero bueno, lo importante...
Bueno, claro, si lo dejamos en la PR...
Bueno, sí.
Lo arreglamos en la PR.
Bueno, ya lo tenemos arreglado, pues.
Muy bien.
Vamos a quitar esto por aquí.
¿Cómo podemos evitar?
Ahora que hemos arreglado el deploy...
Ahora el deploy va a funcionar correctamente.
Pero tenemos que evitar que ocurra el deploy en la pull request.
Aunque no vendría bien que se hiciese, pero lo vamos a evitar.
¿Vale?
Ya tenemos la aplicación funcionando.
Queremos evitar que la pull request no machaque el deploy.
¿Cómo lo podemos hacer?
Lo que quería enseñar justamente antes era el hecho que está GitHub Actions Context Object.
Que tiene un montón de información.
A ver si esto...
Github...
Vale.
Tenemos Github, que es un objeto que tiene un montón de información.
Tienes el environment.
Tienes todo el tema del nombre del commit.
O sea, quién ha hecho el commit.
El nombre de la rama.
Tienes un montón de información.
El evento que lo ha hecho.
El workflow.
El job que se está ejecutando.
El actor.
El repositorio.
Un montón de información.
La información que en este caso nos interesa sería el tema del evento.
De hecho, debería haber uno que sea event name.
¿Vale?
Que nos dice justamente el nombre del evento.
Con el nombre del evento podríamos decir.
Vale.
Si el deploy to Heroku este lo vamos a hacer solo si este evento, el nombre del evento, es el del push.
Porque el nombre del evento del push que estamos escuchando.
Que es este.
El nombre del evento es este.
Solo lo estamos escuchando en la rama main.
Por lo tanto, cuando sea el nombre del evento push, significa que lo que estamos haciendo es pusheando.
Estamos mergeando a master.
De esta forma, vamos a hacer que esto solo funcione en master.
Ya tenemos esto.
Perfecto.
Ya tenemos el tema del head check arreglado.
Vamos a ejecutar esto.
Para que ahora sí.
Make pipeline deploy to work only on master.
Y de esta forma, evitamos que funcione en la pull request.
Porque menuda liada que funcione en la pull request.
Imagínate que cada vez que se abre una pull request, te machaque lo que has desplegado.
Pues sería una locura.
A ver, podría ser divertido.
Podría estar divertido.
Pero también la gente se podría tirar mucho de los pelos.
Mientras esto se va desplegando.
Veremos que el deploy este se lo salta.
O sea, aquí veremos un ignore.
No veremos ni un error, ni caído bien.
Sino que veremos que se lo ha saltado.
Como un skip.
Mientras esto ocurre, te voy a explicar una cosita.
Que es bastante interesante.
Que es el tema de proteger master.
Ahora que estamos teniendo el tema este de las pull request.
Y todo esto, lo que podemos hacer justamente aquí sería en branches, proteger las ramas.
¿Veis que tenemos aquí branch protection rules?
Vamos a crear una nueva regla.
Y en esta regla aquí le vamos a decir que para branch name, para main,
vamos a requerir que el status check haya pasado antes de hacer un merge.
Esto es súper importante.
Porque si aquí añades las pull requests, añades que vas a pasar esto.
Pero fíjate, tú puedes mergear aquí sin ningún tipo de problema.
Esto no tiene ningún sentido.
¿Qué es lo que estás evitando?
No estás evitando nada.
Solo es un tema informativo.
Así que un check que tienes que poner es este.
Y luego además, fíjate que te dice requerir además que la rama esté actualizada antes de mergear.
Esto también es súper útil.
Porque si no, tú aquí lo que puedes hacer es que vale, te voy a obligar.
Pero a lo mejor lo que estás intentando mergear es una versión antigua que no está sincronizada con lo que hay en master o en main.
Así que también esto está bastante bien.
Además aquí le puedes poner los checks.
En los checks, a ver si creo que deploy.
Sí, puedes decir el de Hello World, que no es muy útil, o el de deploy, que es el que nos interesa.
Tienes un montón más y ya verás que en mi caso, como soy administrador, si yo voy aquí, bueno, ahora porque ha pasado.
Pero si ahora cuando volvamos, mira, ha ido bien, ha hecho verde nuestra PR y fíjate que el deploy se lo ha saltado.
Ha dicho, vale, me has dicho que me salte el deploy, pues me lo salto y ya está.
Como he dicho que os iba a explicar el tema de eliminar builds redundantes, vais a ver que esto es súper fácil.
Lo primero, donde se tiene que hacer esto de evitar builds redundantes, en el caso de que tengas más de una build a la vez,
que siempre lo vas a querer evitar porque si no puedes desplegar cosas que no es lo último, pues utilizando una acción, como siempre.
Aquí vamos a añadir antes de todo, antes del checkout, antes de todo, vamos a añadir una acción.
Le vamos a poner cancel, previous, redundant, builds.
Y lo que vamos a hacer aquí es que va a usar una acción que vamos a buscar en el Marketplace.
Es que en el Marketplace tiene de todo.
Cancel workflow.
Y creo que este no es.
Es este.
Yo me suelo fijar en el tema de las estrellas.
Si tiene 16 estrellas o tiene 487.
Y ya te digo, esta es la que yo he utilizado un montón de veces y a mí me ha funcionado correctamente.
Así que vamos a utilizar esta.
Vamos a ponerla por aquí.
Y aquí le puedes decir, le tienes que decir el access token que quieres utilizar.
El access token es el token de acceso de GitHub para que pueda justamente utilizar la API de GitHub y cancelar el workflow.
Entonces, claro, no hay que preocuparse.
Esto que te pone aquí, esto está prohibidísimo.
No puedes tener un GitHub token que sea un secreto porque ya lo tienes disponible.
En GitHub.token, ¿te acuerdas del objeto contexto que te he dicho que no sé qué?
Pues justamente en este objeto contexto, GitHub context token, este objeto este, tienes el token.
Cuando utilizas todo el contexto de GitHub, cuida que incluya información sensible.
Claro, lo que no puedes hacer es un log de esto porque si no la puedes liar.
Pero mira, GitHub.token.
Esto es súper útil porque de esta forma no tienes que preocuparte nunca de crear tú un token, sino que siempre lo tienes disponible.
Y aquí lo tenemos, ¿vale?
Access token, GitHub.token.
Access lo he escrito bien, ¿no?
Con dos Cs y dos Ss.
Sí.
Vale.
Pues con esto vamos a evitar.
Avoid redundant build.
Builds y de esta forma ya no podremos hacer dos builds en paralelo, sino que cuando detecte que hacemos dos en paralelo, la que no sea la última se cancelará.
¿Vale?
Con esto ya tendríamos nuestra PR ya más que hecha.
Vamos a pull request.
Vamos aquí, van version.
Y vamos a ver.
Fíjate que ahora me dice, como administrador, puedes mergear esta PR, pero me sale todo en rojo.
¿Por qué?
Porque me dice que es requerido que tiene que pasar antes de mergear el status de este check.
Esto es súper útil, ¿vale?
Esto es súper necesario.
Cuando quieras hacer continuous integration, parte de la gracia está aquí.
Que no tienes que desplegar.
Primero, no deberías mergear código si no pasa el continuous integration y no deberías desplegar a producción si no pasan los tests, si no linta bien el código y todo esto.
¿Vale?
Vale.
Pues vamos a ver cómo hace esto, que al final lo único que hemos hecho es lo del redundant.
Como no tenía redundance, ¿ves?
Pues esto no ha salido, no ha hecho nada.
Voy a forzar que haga unas cuantas builds redundantes.
Para ello lo que voy a hacer es cambiar justamente la versión del package.json.
Y así vas a ver cómo los cancela.
Vamos a publish new version.
Vamos a pushar esto.
Voy a ver que realmente inicie esa acción.
¿Vale?
Con el bump version.
¿Vale?
Ahora, justo este acaba de empezar.
Está en la cola.
Vamos a hacer otro.
Para encolar uno más.
Para ver si hace bump new version.
Otra vez.
A ver si se van cancelando.
Vamos a refrescar aquí.
Vale.
Fíjate que este ya ha hecho este...
Que este workflow ha sido cancelado.
¿Vale?
Y este, dentro de poco, este también debería cancelarse.
¿Por qué?
Porque tiene este arriba y están siendo redundantes.
Y entonces para no competir deberíamos ver que este también se cancela.
Vamos a ver.
¿Vale?
¿Ves?
Se ha cancelado.
Si entro, vamos a ver que justamente el deploy ha sido cancelado, cancelado, cancelado.
Y todo esto que ha sido cancelado, esta cancelación ha venido porque este, cuando ha ejecutado el paso este del cancel a previous tal, ¿ves?
Aquí lo ha encontrado.
He encontrado el token, he encontrado un workflow, tengo que cancelar uno y lo ha cancelado.
Así que, bueno, tenlo en cuenta que con esto funciona correctamente.
Una cosa que está bastante bien es el hecho de que si encuentra aquí un workflow y lo cancela, si estás en mitad de un deploy, no te preocupes que no cancela el deploy.
Sino que es justo cuando va a empezar el deploy.
Justo cuando va a empezar cada step.
Solo ahí es cuando lo cancela.
Porque si lo cancelase justo en medio mientras se está ejecutando el step, la podría liar muy parda.
¿Vale?
Vale.
Con esto ya tendríamos el tema este del deploy.
Ahora te voy a enseñar una cosa que es lo que yo creo que es lo más poderoso, lo más potente de la GitHub Actions.
¿Vale?
Creo que esto es lo que realmente marca la diferencia respecto no solo a otras soluciones, sino que creo que es lo que habilita hacer pipeline.
Pipelines muy potentes.
Y esto es lo que, por ejemplo, estamos utilizando en mi empresa.
De hecho, para que lo veas, te lo voy a enseñar.
Y para ver que es totalmente cierto.
Es totalmente de código abierto.
Le puedes echar un vistazo.
Eso es el catálogo de componentes de Suite.
Vamos a Actions.
Y aquí, si yo entro a esta misma, ¿vale?
Puedes ver que el pipeline lo tengo como separado.
Y fíjate que tiene como unas flechas.
Es como unas cosas un poco raras, ¿no?
Te dice el testing.
Vale.
Cuando termino el testing voy a release y a deploy.
Pero el deploy depende también de build.
Por lo tanto, espera la build.
Esto es justamente lo más poderoso que tiene la GitHub Actions.
Y lo que, en el ejemplo que vamos a ver hoy, o sea, en lo que tenemos hoy, es una aplicación muy pequeña.
Pero en este caso, cuando la aplicación es más real y más grande, es súper útil.
Porque lo que estás haciendo es esperar.
Justamente estamos esperando pasos anteriores antes de hacer el nuevo.
Y, además, paralelizamos pasos.
En este caso, ves que estamos haciendo el testing, el build y el check de hacer el skip del redunda.
Lo estamos haciendo a la vez.
Y luego, es que hacemos la release solo cuando termine el testing.
Pero el deploy lo hacemos cuando termina también la build, ¿vale?
O sea, bueno, lo vamos a ver para que veas cómo se hace.
No es súper...
A ver, es sencillo, pero puede ser un poco lío.
Pero, bueno, no te preocupes que lo vamos a hacer paso a paso.
Y a ver si sale bien.
Lo que hay que hacer...
Primero, vamos a ver la diferencia con este, con el nuestro, ¿no?
El nuestro ahora es un paso que es deploy.
Ya te digo que, a lo mejor, el tiempo que conseguimos es peor incluso.
Porque esto no es un caso real.
Pero, bueno, te quiero acercar un caso real que te pueda ayudar a hacer un Continuous Integration mucho más maduro y bien trabajado.
Y muy poca gente lo hace y lo sabe hacer.
Así que creo que es bastante interesante el contenido.
Ahora solo tenemos un trabajo que es deploy.
Y entonces tenemos deploy y lo hacemos todo.
Uno detrás de otro y tal.
Puede tener sentido, pero normalmente en la vida real no es así.
No funciona así.
Vamos a empezar a dividir en diferentes trabajos.
Por un lado, podemos tener el de evitar la redundancia.
¿Vale?
Vamos a decir que esto va en 18.04.
Y cada trabajo vas a ver que además tiene que tener su runs on.
Le tienes que decir en qué sistema operativo tiene que trabajar.
Porque es que son máquinas separadas.
Y es parte de la magia decir...
Bueno, es que lo vas a ver y es que vas a flipar.
¿Cuáles son los pasos que tiene que hacer este de la redundancia?
¿Vale?
Los pasos los tenemos ya aquí, justamente.
Este steps.
Este de aquí.
¿Vale?
Vamos a formatear esto bien.
Y lo tenemos aquí.
Así que en el deploy, esto ya lo podemos quitar.
Esto por un lado.
¿Vale?
¿Esto qué le ha pasado?
Que ahora dice...
Ah, que es que he quitado los steps.
¿Vale?
El de redundancy, este ya lo hemos quitado.
¿Cuál necesitamos ahora?
Ahora tenemos que tener el del linter.
El del linter.
Que este va a trabajar también 18.04.
¿Cuáles son los pasos que tiene el linter?
¿Vale?
Vamos a buscar por aquí.
Esto es un problema porque veremos que repetimos código.
Pero claro, es que es necesario ahora mismo.
¿Vale?
Luego os explicaré cómo se puede componer todo este tipo de cosas.
Que ya te puedes imaginar que se puede.
Porque fíjate que este uses.
Tienes aquí un actions.
O sea que se pueden componer.
Vamos con el linter.
El linter necesita esta parte de aquí.
En este caso, nos lo vamos a copiar y pegar.
Y lo dejamos así.
¿Qué es lo que necesita el paso del linter?
Tenemos que hacer un checkout porque necesitamos el código.
Tenemos que hacer un setup node porque tenemos que hacer luego un install.
Instalamos las dependencias con npmci.
Y hacemos el linter.
Ya está.
¿Qué más tenemos que hacer?
Aparte del linter, tenemos que hacer una build.
¿Vale?
Pues vamos a hacer la build.
¿Cómo os hacemos la build?
Vamos a quitar este que era el del linter que ya hemos copiado.
Y necesitamos este de build.
Y aquí en la build es una de las cosas más interesantes de los pasos que vamos a hacer.
¿Por qué?
Porque la build, cuando hacemos la build, ¿qué es lo que hace la build?
Pues empaqueta nuestra aplicación.
Pero ¿cuál es el problema?
Por ahora lo voy a dejar.
¿Cuál es el problema de los tests?
Pues que los tests necesitan nuestra aplicación empaquetada para poder ejecutarse.
Entonces, ¿cómo podemos compartir información entre este job?
Bueno, este job, el de build, y el de los tests.
Pues ahora lo veremos.
¿Vale?
Por ahora vamos a hacer el de test.
Me voy a eliminar este de build por aquí.
Y voy a añadir esto de test.
Lo vamos a añadir por aquí con el runson y todo esto.
¿Vale?
Como digo, el de los tests depende justamente de la build.
Pero debería hacer aquí otra vez la build.
No tiene sentido.
¿Por qué?
Porque ya la hemos hecho aquí.
¿Qué es lo que podemos hacer para esto?
Pues lo que podemos hacer es guardar un artefacto.
Que básicamente guardar un artefacto lo que quiere decir es que le decimos,
oye, esta carpeta de aquí me la guardas en un zip que luego igual lo utilizo en otro sitio.
¿Vale?
Entonces, lo que hacemos en esta build, una vez que tenemos aquí,
el MPN run build y ya ha empaquetado nuestra aplicación correctamente,
lo que vamos a hacer aquí es tener un paso más,
que es utilizar una de actions, que es upload artifact, la versión 2.
Y le decimos, esta acción la quiero utilizar con la opción,
con un nombre que es dist y el path donde está el dist es dist.
¿Cómo sé que es dist?
Bueno, porque cuando yo hago, fíjate, voy a eliminar el dist aquí.
Cuando yo hago un MPN run build, esto lo que hace es generarme una carpeta que se llama dist.
Y aquí es donde está empaquetada mi aplicación.
Entonces, lo que le estoy diciendo en esta acción es,
cuando hago el MPN run build con esta acción,
o sea, una vez, en esta acción voy a utilizar el upload artifact,
¿artifact?
Sí, o upload artifact.
Con la opción name, el nombre puede ser el que tú quieras,
lo que pasa es que luego lo vamos a necesitar para indicarle de dónde lo queremos descargar,
y el path es la carpeta donde está la información que queremos empaquetar.
En este caso, dist.
Con esto ya estaríamos subiendo a la nube lo que hemos construido,
la aplicación que hemos empaquetado.
Ahora que tenemos la aplicación empaquetada en algún sitio,
¿qué es lo que tenemos que hacer?
Pues lo que deberíamos hacer es, en el test,
antes de ejecutar los test,
es posible que los test necesiten la aplicación empaquetada ya.
Por lo tanto, lo que podemos hacer es descargarla.
¿Pero qué pasa con esto?
Que para descargarla tenemos que utilizar exactamente lo mismo que aquí,
pero en lugar de decir upload, lo que vamos a decir es download.
Antes de ejecutar los test, vamos a ponerlo aquí,
vamos a hacer un download con el nombre dist
y lo vamos a guardar en la carpeta dist,
porque si no te lo dejaría en la raíz,
si tú le quitas esto,
te dejaría el contenido que tenía el artefacto,
te lo dejaría en la raíz.
Que esto es súper interesante,
esto lo sé porque te peleas con los ls
y miras ahí cómo te lo ha dejado y todo esto,
pero bueno, en este caso así funcionaría correctamente.
Con esto ya podríamos ejecutar el test y tal.
¿Pero qué pasa con esto?
Antes de continuar,
que este trabajo test, tal y como está,
se va a ejecutar en paralelo con el de build
y nosotros no queremos eso.
Queremos que el de test solo se ejecute
una vez que haya pasado tanto la build como el linter.
Una vez que sepamos que el linter está bien
y que la build se ha hecho correctamente,
entonces ejecutamos el test.
Para ello tenemos que utilizar aquí needs,
que es un array que le decimos
este trabajo necesita el de lint y el de build.
Una vez que tenemos el de lint y el de build,
entonces ejecuta este job.
Ya tenemos el de test normal,
vamos a pasar con el de end to end.
Así que vamos a poner end to end test.
Vamos a poner runs.
Vale, esto lo elimino de aquí
y vamos a copiar todo esto.
¿Qué le pasa al end to end test?
Le pasa exactamente lo mismo.
Los tests end to end,
cuando hace el npm start test,
no funciona si no tiene la aplicación empaquetada.
Pues nada, vamos a descargar el artefacto
y esto, una vez que se hace el npm install,
vamos a hacerlo aquí,
justo antes del end to end test.
¿Vale?
Ya tendríamos los end to end.
Vamos a quitar esto.
Install dependencies, este lo dejamos.
Y ahora nos faltaría el tema del deploy.
Más, perdón,
que el end to end test también depende de algo, ¿no?
No lo podemos dejar así.
¿Qué pasa?
Que el end to end test y los tests unitarios
se pueden hacer en paralelo.
Lo único importante es que necesita
tanto el linter como la build,
pero no necesita el test.
O sea, que se puede hacer
tanto el test unitario como los de end to end
se pueden hacer en paralelo.
Así que dejamos las mismas dependencias
que tenían los tests.
O sea, los tests de antes,
o sea, los dejamos para los end to end.
Y ahora tenemos por fin el deploy,
que seguramente es el más interesante de todos.
¿Qué es lo que necesita el deploy para funcionar?
Necesita que haya pasado los tests
y también los end to end test.
En este caso voy a poner el end to end
más fácil porque no sé si el guión,
no sé si el guión no le gusta.
Vale, el deploy necesita los tests y los end to end.
Y lo que va a hacer es ejecutar todo esto.
No necesita instalar las dependencias.
La verdad es que no necesita instalar...
Yo creo que no necesita tampoco hacer actualización de Node.
Yo creo que esto no lo necesita.
Si no, bueno, si falla, pues ya lo veremos.
Porque creo que el deploy to Heroku,
esto ya hace el npm install de forma interna,
que es una de las cosas que justamente no me gusta.
Pero bueno, lo importante de esto es que necesita los tests,
los end to end y tal.
Esto lo veremos cuando emergimos a master
porque esto hace un skip en...
Justamente hace un skip en la pull request.
Pero bueno, con esto lo que hemos logrado,
aunque hemos tenido que repetir mucho código y todo esto,
pero con esto lo que hemos logrado
es justamente paralelizarlo todo.
Hemos creado un pipeline que es mucho más complejo,
pero que es realmente mucho más realista
de cómo funciona el mundo real,
el trabajo real cuando se utiliza el GitHub Actions.
Así que vamos a hacer un Parallelize CI
y vamos a ver si funciona.
A ver si no la he liado.
Nos vamos a Actions.
Vale, esto...
Uy, esto casillo.
Aquí ha fallado algo.
Vale, it's not valid.
Dove deploy depends on un nob test.
Vale, la he liado.
Pero fíjate lo rápido, ¿eh?
Súper, súper rápido.
Acabo de pushear y ya se está quejando.
Bueno, he puesto que depende de un test.
¿Ves?
He puesto test y aquí he puesto tests.
Pero una de las cosas que me gusta mucho de GitHub Actions
es que realmente te dice,
oye, esto no está bien y tal.
Travis suele ser un poco más problemático.
Grown Job Tests.
Vale, venga, vamos a ello.
A ver ahora.
Vamos a Actions.
Ahora debería aparecer aquí en un momentito.
Aquí lo tenemos.
Y fíjate qué bonito, qué bonito ha quedado ahora, ¿no?
Ahora tenemos aquí en paralelo estos tres.
Mientras hace una void redundancy por un lado, ¿no?
Para ver si hay alguno que tiene que cancelar a un workflow.
Y como es anterior, no necesita depender de nada aquí,
ni paralelizar, o sea, ni parar este, ¿no?
Entonces, estos tres segundos son tres segundos que hemos ganado,
que sé que parece poco, pero tres segundos.
Piensa en miles y miles de ejecuciones de tu código.
Tres segundos son la vida.
Entonces, estos tres segundos lo que ha hecho de forma paralela
es cancelar builds anteriores.
El link y la build se han hecho en paralelo.
De hecho, lo podemos mirar.
Aquí el link, lo que ha hecho es solo el link.
Es verdad que ha tardado 15 segundos por instalar las dependencias,
que esto también se puede cachear de otra forma y tal.
De hecho, se le podría hacer un paso para cachear las dependencias.
Una vez que ha terminado el link y el build,
lo que ha hecho es hacer los tests.
Y justamente la dependencia de los tests,
ahora dice, vale, pues cuando termina el link y build,
hago los tests y los send to end, y los hago en paralelo.
O sea, no hago primero los tests unitarios y luego los send to end,
sino que los hago en paralelo.
De forma que los segundos, aunque sean...
Esto es un ejemplo muy pequeñito,
pero en el mundo real, los tests unitarios,
a lo mejor, te pueden tardar tres o cuatro minutos.
Esto puede marcar la diferencia totalmente.
Puedes pasar de hacer continuous integration en 20 minutos
a hacer continuous integration que tardan siete minutos.
Donde son siete minutos porque ha sido el que más tarda,
el que más tiempo ha tardado,
que a lo mejor normalmente son los tests end to end,
pues a lo mejor tardan siete minutos.
Pero es que todo lo demás lo has hecho en paralelo.
Entonces, fíjate que ahora, cuando termine este,
deberíamos ver cómo pasa el deploy.
Como digo, es un ejemplo muy sencillo,
porque en este caso no vamos a ver ganancias de tiempo,
y seguramente incluso puede ser que veamos un impacto negativo,
porque la instalación tiene un gran peso,
aunque son 15 segundos,
que podríamos mirar de intentar cachearla.
Una vez que termine los send to end,
ves, el deploy todavía no ha empezado,
porque dice, no, no, es que el deploy,
ahora sí, porque el deploy depende de los dos tests.
Entonces, hasta que los dos tests no pasen,
no se desplega.
Así de claro.
Y entonces, ahora que sí ha terminado,
ahora sí que está desplegando.
Pero el despliegue, bueno, se lo salta porque hace un skip.
Por eso aquí nos aparece como que ha tardado tres segundos.
No es que haya tardado tres segundos,
es que se lo ha saltado.
Es verdad que, ¡ah!
Una cosa muy bonita de esto.
Una cosa muy bonita de lo que acabamos de hacer, ¿vale?
Que esto es, mmm, palamerlo.
El tema es que en la pull request, ahora,
fíjate lo bonito que quedan los checks.
Lo que hemos hecho, además de mejorar el tiempo,
nos ayuda a determinar mejor
qué paso del continuous integration ha fallado.
Porque aquí, en los checks, fíjate aquí,
que me ha dividido todo.
Este, que además ha tardado tres segundos.
Tú puedes ir a la pull request
y ver cuál es el paso que está haciendo.
El linter, el build, el test, el end to end.
Y aquí los puedes ver todos y cada uno de ellos.
Para que lo veas más claro,
vamos a volver a hacerlo
y vamos a ponerlo en esa vista
para que veamos cómo,
the version,
para que veas cómo se va actualizando.
Esto es genial porque lo que te hace en la pull request
es darte de un vistazo,
si te fallase solo uno de los jobs,
te diría, mira, este job es el que ha fallado.
¿Ves? Ahora mismo están ejecutando los tres en paralelo.
El de avoid, el de linked y el de build.
Entonces, cuando vaya, cuando termine uno,
¿ves? Este se pone en verde.
Entonces, se irán desbloqueando otros.
¿Qué falla uno?
Pues te aparece aquí
y además le podrías dar a details directamente
para ver exactamente por qué ha fallado ese.
Esto lo que hace es mejorar muchísimo la productividad.
No es lo mismo tenerlo todo en un solo paso
que te cuesta mucho decir,
ah, a ver qué ha fallado.
¿Sabes? A ver qué problema hay.
A verlo de esta forma mucho más granular.
De forma que cuando veas aquí,
uno, ver cuál es el paso en el que lo estás haciendo
y luego ver realmente cuál es el que ha fallado.
¿Ves? Ahora me dice, puedes ver completamente por dónde va.
Ahora doy cuenta que este es el test, el end to end y todo esto.
Puedes ir viendo cómo se va mejorando.
O sea, cómo va procesándose todo esto.
Y si falla uno, pues lo veríamos también.
Vamos a ver ahora de emergear esta, una vez que termine,
que debe terminar en algún momento,
para ver cómo lo vemos
y cómo se emergea
y si le hace el despliegue,
si el despliegue funciona correctamente y todo esto.
¿Vale?
A ver, que voy leyendo mientras esto termina.
Si quieres ahorrar tiempo en aplicaciones grandes,
¿no podrías hacer varios end to end
para distintas partes del sitio
y que corran en paralelo?
Claro, por supuesto, franco.
De hecho, en mi empresa lo que hacemos,
esto se hace de forma automática incluso.
Cypress tiene un servicio que es de pago
y en mi empresa lo hacemos
y para nosotros los test end to end
tardan un minuto o algo así.
Cypress tiene este servicio de paralelización.
¿Vale?
De forma gratis puedes ejecutar 500,
pero bueno, si eres una empresa
ya te puedes pagar y tienes 10.000 test
y lo que haces es paralelizar de forma automática
y tú le dices, vale, pues lo paralizo en cuatro procesos
y los procesos ellos mismos se comunican
de forma que lo que hacen es paralelizarlo por ti.
Tú no tienes que decirle, prueba esta parte,
prueba esta parte, tú no le dices eso,
sino que automáticamente lo hace por ti,
lo cual es muchísimo mejor.
Mucho, mucho, mucho, mucho mejor.
¿Vale?
También SetupNode provee de un parámetro width
que lo automatiza.
¿Que automatiza el qué?
No sé, ¿que automatiza el qué?
Ya no me he enterado.
CircleCI Jenkins, ¿cómo elegir la mejor opción?
¿Por cuál te vas?
Yo me quedo con Github Actions.
Jenkins no me gusta nada.
CircleCI estaba bien, pero me gustaba más Travis.
Si yo tuviera que elegir uno, elegiría Github Actions.
El único problema que tiene Github Actions es el tema de que,
obviamente, necesitas utilizar Github.
Si utilizas Github, yo creo que no hay ningún tipo de duda de
utilizar, de que deberías utilizar ese.
O sea, Github Actions.
Es que es demasiado, está muy bien integrado con Github.
Es brutal, es brutal.
Sí, el tema de la caché, que decías lo de Setup Actions.
Sí y no.
A ver, el problema que tiene el SetupNode, lo podemos probar,
lo podemos probar.
El problema es que no te lo caché exactamente muy bien.
Ahora cuando, mira, ya está.
Voy a mergearlo y lo probamos.
Pero cachear NPM es un rollazo.
Vamos a irnos a master.
Me voy a traer todos los cambios.
Sí, se supone que aquí, en el SetupNode,
aquí tú tienes uno que pone caché y le tienes que decir NPM.
El problema es que no funciona muy bien cuando es en paralelo.
¿Sabes?
O sea, no funciona muy bien.
Y, de hecho, hay una acción que es de Github que se llama Caché.
Actions Caché.
Se llama así.
Y tampoco funciona del todo bien.
Mira, ¿ves?
Es que yo he estado mirando ya aquí.
De hecho, mira, aquí hay alguien que ha creado una acción
que a lo mejor funciona mejor que la de...
Es que este es el problema.
Que es que hay que hacer todo esto.
Para cachear hay que hacer todo esto.
Y esto es un rollo.
Entonces, está bien que tenga su propia acción.
Pero el tema del Node Setup, ya te digo que lo que cachea
no es exactamente las dependencias y ya está.
Es un poco raro lo que hace.
Porque para cachearlo, ¿ves?
Hay que hacer el action Caché.
Para cachear bien hay que hacer esto.
Pero esto es un rollo hacerlo.
Entonces, me imagino que este lo hará este Caché en vista del Caché.
No sé si podemos ver cuándo es la última vez que se ha ejecutado esto.
Bueno, hace tres días.
Bueno, igual.
Ah, lo miramos.
Ya os digo que el de NPM, el Setup Node ese, el de la Caché,
no es exactamente lo que estamos buscando.
Vamos a mirarlo.
Caché.
The action will first check the local cache for a Sember match.
Claro, yo creo que esto es para la Caché.
Mira.
Ah, mira.
Aquí esto sí que...
Caching Package Dependencies.
Vamos a ver.
The action has a build cache input is optional.
Caching is turning up with default.
Bueno, igual con el Package Lock no funciona bien.
Vamos a probarlo.
Dependencies.
Vamos a probar.
Total, he puesto aquí el Caché en EPE.
Vamos a poner este.
Igual es algo nuevo de la versión 2 porque yo he utilizado la versión 1.
Support Caching for MonoreposantReposit.
Bueno, puede ser.
Caché, caché, caché.
A ver si han puesto...
Caché, caché, caché, caché.
Caché, caché.
PNP Dependencies.
Pues parece sí que...
Mira, me parece a mí que la han puesto hace relativamente hace poco.
Igual, joder, sería genial, ¿eh?
O sea, ya sería la bomba.
Sería la bomba.
A ver, vamos a buscar todos estos.
Pa, pa, pa, pa, pa.
Caché.
En PNP.
Porque ya os digo que esto antes no funcionaba muy bien.
Lo que cacheaba...
Cacheaba fatal.
Vale, esto está dos veces.
Y no funcionaba, básicamente.
Ojalá que sí.
Vamos a verlo.
Add caché to setup note.
Pero sí, parece que es algo bastante nuevo, ¿no?
Porque esto es del 30 de junio.
Puede ser que...
Caching the action is a build...
Yo creo que sí que es nuevo.
The cache input...
Pues nada, fantástico.
Vamos a probarlo y a ver qué tal.
A ver si mejoramos un poquito el tiempo de la action.
A ver, voy cerrando todo esto.
Vale.
Nuestra aplicación se deploya correctamente.
Vale.
Aquí hemos añadido la caché.
Aquí tendríamos...
Bueno, aquí se ha cancelado la anterior del pipeline.
Estaba tardando sobre los 3 minutos, más o menos.
3 minutos 10.
Vamos a ver ahora.
Hombre.
Ojo, ¿eh?
11 segundos.
11 segundos.
No sé si...
Setup note.
Pero aquí no ha encontrado la caché.
O sea, caché is not found.
Se supone que en la siguiente, en la de test, debería haber encontrado la caché.
A ver ahora si la encuentra la caché.
Aquí sí que ha encontrado la caché.
Bueno, nos ha ahorrado ahí 10 segundos.
Otra cosa sería hacer un solo paso que fuese para hacer el NPM install.
Pues sí, 10 segundos.
Parece que ahí sí que funciona bastante bien, ¿eh?
Porque aquí, claro, los primeros que hacen paralelo no tiene caché ninguno de los dos.
Por eso, es que da igual, porque podría, al hacerlo en paralelo, cualquiera de los dos, una cosa que se podría hacer es hacer primero el NPM install, cachearlo y luego hacer el link y el build.
Eso podríamos hacerlo.
O sea, podríamos hacer aquí.
Elaboy Redum sí.
Podríamos hacer aquí.
Install.
Haríamos el install.
Pa, pa, pa.
Esto haríamos esta parte de aquí, con steps.
Esta parte de aquí.
Esto, tenemos que poner que esto se ejecuta en Ubuntu.
¿Vale?
Checkout, caché, NPM.
Y ahora aquí le tenemos que decir que depende, a ver, no sé si esto nos va a dar mucho.
Depends on install.
Needs, perdón, no depends, es needs.
Needs install.
¿Vale?
Y le decimos que la build también necesita install.
Yo creo que esto no vale la pena, porque el tiempo que se gana es muy poco.
Y total, como se están haciendo los dos primeros en paralelo, pues ya está bien.
Pero esto lo que se le llama es calentar la caché.
Lo que quiere decir esto es calentar la caché.
¿Sabes?
Es hacer un paso solo para calentar la caché.
¿Está bien este paso?
La verdad es que la han puesto hace bastante poquito, porque ya te digo que la última vez que yo toqué el GitHub Actions en mi empresa,
esto no estaba y hacerlo era un percal y no funcionaba muy bien.
O sea, que genial.
Con la V1 tenías que hacerlo con Action.
¿Lo metieron en la versión 2?
Sí, pero lo metieron en la versión 2 y es nuevo.
O sea, lo metieron después, porque en la versión 2 sí que la he estado utilizando y todavía no estaba.
Hostia, pues no sé si es 3Droid, no sé.
No sé, no sabía que no había subido el de esto.
Entonces, diferente al Action caché de configurarlo en Node Setup.
Son dos cosas diferentes, ¿vale?
Porque tú tienes una acción para cachear y ahí puedes cachear lo que te dé la gana.
Es que puedes cachear, lo que pasa es que es como para cachear dependencias.
Claro, ¿qué pasa?
Que nosotros estamos pensando mucho en Node y en NPM, pero pensad que podéis utilizar un montón de lenguajes y frameworks diferentes.
Por ejemplo, Python.
Pues podéis utilizar el Action caché a lo mejor.
O Java, pues archivos de compilación y un montón de cosas así, ¿vale?
¿Me puedes compartir tu playlist de Spotify o dónde puedo encontrar tu música?
Pues busca Música para Programar y Midudev, que ahí salgo yo.
Ahí está una de la música, una de mis listas de reproducciones con música.
Vale, GitLab me gusta como plataforma porque tiene manejo de revag, pero GitHub es muy bueno.
Hombre, GitLab está súper chulo y además tiene Continuous Integration también.
Ahora, claro, anteriormente sí que es verdad que tenía una...
Tenía Continuous Integration y aquello era brutal, pero ahora GitHub Action la verdad que está muy, muy, muy bien.
Jenkins es muy poco intuitivo, parece una aplicación de 90.
Sí, yo no lo recomiendo nada.
No recomiendo nada.
Pensé que era un mico que le parecía eso un lío.
Sí, no, es un lío.
Es un lío.
A ver, ¿esto cuenta como ser DevOps?
Hombre, guay, como ser DevOps no, pero desde luego yo creo que es bastante importante.
A mí me sorprende el poco cariño que la gente tiene sobre estos conocimientos.
O sea, esto es súper, súper, súper mega importante dominarlo, entenderlo, saber hacerlo,
que con la clase de hoy estoy seguro que lo habéis entendido, lo habéis aprendido y tal,
pero que mucha gente lo ignora o no le importa.
No, yo quiero aprender JavaScript y React, que vale, que está muy bien.
Este conocimiento es vital para ser ingeniero de software.
O sea, súper vital, súper, súper importante.
Entonces, ser DevOps yo creo que te puede montar toda la infraestructura.
Esto es parte de algo que haría un DevOps, pero un DevOps llevaría mucho más, mucho, mucho, mucho más.
¿Cómo que última clase de full stack? Pensé que lo de full stack era interminable.
O eso, o termina con uno.
Hombre, petróleo se ha hecho hoy.
Muchas gracias por vuestro apoyo.
Gracias por toda la ayuda, por cada like, por cada vez que le dais a compartir, por todo.
Me ayudáis un montón, ¿vale?
No es necesario que os suscribáis, que os hagáis mecenas.
Si os hacéis, os quiero con locura, muchísimo.
O sea, de verdad, muchas gracias.
Pero también me ayudáis compartiendo mi contenido, dándole like, comentándolo, comentándosele al trabajo a la gente.
De verdad, eso me ayuda un montón.
Porque cuanto más seamos, más fácil será que le pueda dedicar más tiempo.
Así que, muchas gracias.
Espero que lo hayáis pasado muy bien.
Ha sido un viaje.
Pero, oh, qué viaje.
Ha sido tremendo.
Muchas gracias.
¿Seguirán los directos los domingos?
Me lo tengo que pensar.
Creo que en agosto no vamos a hacer más directos en domingo.
Pero lunes, miércoles y viernes sí haremos directos.
Para tu web a juicio.
Para seguir haciendo Meneadev, Codilink, aprendiendo cosas y todo esto.
Así que os mando un abrazo enorme.
Muchas gracias a todos.
Todos, sois unos cracks, todos y cada uno de ellos.
Todos adoramos la forma de ser de Mido.
El curso de Fullstack ha llegado a su fin.
Con Bond de Dragon Ball.
Qué granda.
Gracias Davor, Leito, Asessing, Gebo Beta, Perro Bomba, Miyazi, Andres, Efedaza, Kemilio, Luichidev, Egló, De Julio, Xitziar.
Muchas gracias, Xitziar, por tu ayuda y por ayudarme un montón con un montón de vídeos.
Mido Embajadores.
Eso sois, Mido Embajadores.
Claro que sí, Gebo Beta.
Gracias Davorpe, Waiko, Immanuel, De Zagiel, Ambe Kout, SeisGamePlayer.
Además me voy acordando de vuestros nombres y me hace mucha ilusión ver que vais repitiendo.
Carlos Neri, Iloinfi, Daddu06, Leito, Gastón, Joder, Héctor, Vimox, Sabe75, StripteM, Tibor, Alan Sánchez.
Muchas gracias.
Cuidado mucho, Maximineto, Jorge, David Pong.
Muchas gracias a todos mis subs.
A todos, cuidaos mucho, sed buenos y disfrutad lo que queda del fin de.
Un abrazo.
Os llevo en el corazón.
Os llevo en mis No Modules, que lo sepáis.
Hasta luego.
Chao.