A fines del año 2019, Github anuncio su servicio de CI/CD, este nuevo servicio se llama Github Actions y vino para darle batalla a los servicios ya existentes como Travis CI, Cicle CI, entre otros.
La verdad que Actions anda muy bien y es una de las grandes herramientas que le faltaba a Github para su ecosistema.
En este artículo vamos a ver como puedes comenzar a utilizar Actions en tus proyectos Laravel.
Un repaso rápido sobre ¿qué es CI/CD?
Si ya sabes que es CI/CD, puedes pasar a la siguiente sección.
Las siglas CI/CD se refieren a Integración Continua para cuando hablamos de CI y cuando hablamos de CD nos podemos referir a dos practicas, a la Distribución Continua y al Despliegue Continuo. Vamos a comentar cada uno de ellas.
CI – Integración continua
Integración continua es la automatización de las acciones de: ejecutar los tests y «mergear» el código que subimos a nuestro repositorio de Github. También podríamos incluir la compilación de assets o de código fuente, si es que estamos utilizando un código que se debe compilar.
Hoy en día es muy común que el desarrollo se haga entre varias personas y a la hora de subir el código a los repositorios, es una gran idea ejecutar estas acciones para que alerten en el caso de cualquier problema.
CD – Distribución continua
Una vez que el código ya fue testeado y mergeado gracias al CI, la distribución continua se encarga de informar que las modificaciones ya están listas para desplegarse en producción.
CD – Despliegue continuo
La otra CD corresponde al Despliegue Continuo y se refiere a la instalación automática en producción para que los usuarios puedan utilizar las nuevas modificaciones que fueron agregadas.
Como aplicar CI/CD con Github Actions y Laravel
¿De que se trata esto de Actions? Bueno, la verdad que es muy simple. Lo que debemos hacer es crear un archivo YAML en nuestro proyecto Laravel, donde vamos a ir especificando las acciones que queremos que haga Github Actions cuando subimos una modificación a nuestro repositorio.
Lo que hará Github Actions es montar una maquina virtual gracias a una imagen Docker que le pasemos, y en esta se instalara y ejecutara todo lo que nosotros especifiquemos. Veamos como se hace esto.
Creando un archivo archivo de prueba para Actions
Lo primero que tenemos que hacer es crear la siguiente estructura en la raíz de nuestro proyecto Laravel:
Y es obligatorio respectar los nombres de las carpetas .github/
y workflows/
ya que es ahí donde Github Actions buscara los archivos YAML.
En el archivo tests.yml
que creamos vamos a poner lo siguiente:
name: CICD on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Run composer install run: composer install -n --prefer-dist - name: Run yarn run: yarn && yarn dev - name: Run tests run: ./vendor/bin/phpunit env: APP_ENV: testing - name: Upload artifacts uses: actions/upload-artifact@master if: failure() with: name: Logs path: ./storage/logs - name: Slack Notification uses: 8398a7/action-slack@v2 with: status: ${{ job.status }} author_name: Integration Test # default: 8398a7@action-slack env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # required SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} # required if: always() # Pick up events even if the job fails or is canceled.
Y comentare linea por linea que significan para que se entienda que estamos haciendo. Primero, le ponemos un nombre a nuestro Action gracias a la clase name
. Luego, con la clave on
decimos que la ejecución de este Action se debe hacer cuando hacemos un push a nuestro repositorio.
Luego, empezamos a especificar los jobs
. Los jobs engloban las acciones que se van a ir ejecutando. Podemos tener más de un job en el mismo archivo para acelerar ciertos procesos, ya lo veremos más adelante.
Construyendo el entorno
A este job le vamos a ponemos la clave build
y dentro de esta clave vamos a poner todo lo que se ejecutará para esta clave.
jobs: build: runs-on: ubuntu-latest
Vamos a decirle a Github Actions que corra este job en la última versión de Ubuntu, gracias a la clave runs-on
y el valor ubuntu-latest
. También podrías utilizar Windows o macOS.
Luego utilizamos la clave steps
para especificar todos los pasos que queremos que se ejecuten en este job.
steps: - uses: actions/checkout@v2 - name: Run composer install run: composer install -n --prefer-dist - name: Run yarn run: yarn && yarn dev
Primero importamos un comando gracias a la clave uses
. Podemos importar varios comandos que nos provee Github Actions para realizar distintas cosas. En este caso, es obligatorio importar el comando actions/checkout@v2 ya que vamos a hacer cosas con nuestro código del repositorio.
Luego instalamos Composer, ya que la imagen de Ubuntu que instalamos esta «pelada». Y También instalamos yarn (podrías utilizar npm si lo deseas) porque Laravel muchas veces lo requiere para ejecutar los tests.
Ejecutando los tests
Ahora vamos a agregar el paso de ejecutar nuestros tests ya que es una de las premisas de CI. Agregamos lo siguiente a nuestro archivo.
- name: Run tests run: ./vendor/bin/phpunit env: APP_ENV: testing
Este step es bastante claro. Lo que hace es ejecutar las pruebas que tengamos en nuestro proyecto. Y si nuestras pruebas fallan, podemos enviar los resultados a un log gracias al ultimo step.
- name: Upload artifacts uses: actions/upload-artifact@master if: failure() with: name: Logs path: ./storage/logs
Enviando notificaciones por Slack
Lo genial de Github Actions es que ya disponemos de un Marketplace con varias funcionalidades ya desarrolladas por otras personas para que podamos utilizar y hagamos nuestro CI/CD más poderoso.
Por ejemplo, podemos utilizar un action de Slack para que notifique cuando finalice Github Actions. Para esto debemos agregar a nuestro archivo (o a uno nuevo) el siguiente step:
- name: Slack Notification uses: 8398a7/action-slack@v2 with: status: ${{ job.status }} author_name: Integration Test env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} if: always()
Como ven, para importar desde el Marketplace de Github Actions también debemos utiliza la clave uses
y luego el valor especifico del action.
Esto nos notificara cuando el proceso de CI/CD haya fallado o funcionado correctamente. Esto seria la Distribución Continua.
Toda esta configuraciones del action de Slack lo pueden ver en el Marketplace: https://github.com/marketplace/actions/action-slack.
Desplegando nuestro código
Puede implementar fácilmente su código automáticamente SOLO si todas sus pruebas están aprobadas. Esto correspondería al Despliegue Continuo.
Si estas utilizando Laravel Forge puedes agregar lo siguiente al final del archivo YAML.
- name: Deploy en Laravel Forge
run: curl ${{ secrets.FORGE_DEPLOYMENT_WEBHOOK }}
En este caso, debes registrar la variable FORGE_DEPLOYMENT_WEBHOOK
en tu repositorio.
O, si estas utilizando Laravel Vapor, puedes agregar lo siguiente:
- name: Deploy en Laravel Forge
run: |
export VAPOR_API_TOKEN="${{ secrets.VAPOR_API_TOKEN }}"
vapor deploy staging
Y, por supuesto, registrar VAPOR_API_TOKEN
en el repositorio.
Ejecutando nuestro CI/CD
¡Ahora es el momento de la verdad! Subí estas modificaciones a tu repositorio de Github. Dirigite a la pagina del repositorio en Github y veras el botón «Actions». Haz click y veras como se ejecutan todos nuestros pasos 😉.
Precio de Github Actions
Para los repositorios públicos Github Actions es totalmente gratis. Github nos brinda 2000 minutos por mes para este tipo de repositorios (este es uno de los motivos por los cuales tus tests deben ser rápidos como comente en la publicación de tests unitarios). Y para los repositorios privados Github nos brinda distintas cantidades de minutos, según el plan que tengamos contratado. Si quieres ver los precios y minutos por mes de cada plan visita la sección de precios de Github.
Conclusión
¡Bienvenidas las Actions de GitHub! Creo que son una gran herramienta para nuestro ecosistema de desarrollo y algo que le faltaba a Github para seguir siendo genial. Próximamente seguiré publicando más cosas sobre Actions. Comenta si ya lo has utilizado y que te ha parecido. Nos vemos en la próxima!
Muy buen artículo sobre github actions, una cosa que no se menciona es como se despliega en caso no usemos vapor o forge, para alguien que tiene un servidor normalito, que opciones existen?
Saludos y sigue publicando,.
Existe https://deployer.org/ es facil de utilizar
Ah mira genial, no lo he usado, vendría bien un tutorial si eso para aquellos que empiezan.
Gracias por todo
Gracias a vos por comentar Eduardo
Muy bueno este artículo gracias.
Hola Matias, excelente aporte, tengo una consulta, cuando el workflow falla en algún punto, se bloquea por decirlo así el commit que estamos subiendo, hasta que todo funciona bien, o sencillamente se sube el commit y CI/CD solo nos notifica que existe algún error?
Hola Cristian, como estas?
Podes configurarlo de ambas formas. Pero lo mejor es que bloquee el deploy si hubo algun step que falló.
Saludos.
Gracias Matias, si es una maravilla, aplique el if para 2 entornos diferentes, hice los procesos necesarios y ahora está todo automatizado, muchas gracias por seguir compartiendo el conocimiento, eres un crack.