Actualmente muchas empresas se han movido al continuous paradigm en donde este te permite tener lanzamientos y entregas a tus clientes de manera continua y rápida, permitiendo moverse con las exigencias que pone actualmente el mercado, trayendo consigo beneficios dentro de los equipos de desarrollo como: mayor productividad, encontrar errores mas rapido, y sustentabilidad es decir trabajar de forma inteligente automatizando tareas que desgasta a los equipos, por esa razón si actualmente los días de despliegue son días que no te gustaria estar o que te generan sensación de terror, probablemente te identifiques con la Figura 1

Figura 1: Ciclo emocional de los despliegues manuales obtrenido de https://www.atlassian.com/continuous-delivery/principles/business-value

Github Actions

Los github actions son una parte interesante que se puede utilizar para abordar todo lo relacionado con el continuous paradigm, aunque github actions es más que CI/CD ya que ofrece varios servicios, este es el uso que más se le da, en términos sencillos los github actions son event-driven es decir una acción que se ejecuta después de que ocurre un evento, en este caso puede ser un un push a una rama o un commit, dentro de la terminología nos encontramos 4 definiciones importantes que utilizare dentro del post

  • Workflow es un proceso que contiene ciertos pasos y acciones que planeas automatizar, por ejemplo si quieres testear tu código cuando hagas un merge a main este proceso es el workflow de testing
  • Events un evento que ocurre y que hace que el workflow se ejecute, por ejemplo un evento puede ser hacer un merge de una rama a la rama principal
  • Step son pasos o tareas individuales que se ejecutan, generalmente pueden ser comandos, por ejemplo un ste puede ser ejecutar el comando pytest
  • Jobs estos permiten agrupar los steps para ejecutarlos de forma más ordenada o eventualmente existe la posibilidad de ejecutar comandos al mismo tiempo o de forma secuencial, por ejemplo primero  ejecutar todos los steps de testeo de código y luego los de despliegue.

Un concepto importante para entender mejor el universo de los actions, es comprender que cada workflow y cada job básicamente se ejecutan en una máquina virtual que github reserva, es decir se pueden utilizar máquinas con diferentes sistemas operativos para ejecutar estos procesos, por ejemplo se puede utilizar un ubuntu y al utilizarlo se pueden ejecutar comandos que se utilizarían en el cualquier máquina con ubuntu, como instalar dependencias, clonar el repositorio y ejecutar tests, por eso los github actions tienen un costo dependendiendo de los minutos de máquina que uses Ver Figura 2 (cada workflow demora un tiempo de ejecución hasta que termine) para repositorios públicos este servicio es Free

Figura 2: Precios por usar Github Actions

Bueno con la terminología básica clara,  ahora si podemos pasar al código, primero que nada se debe definir el workflow que será el proceso que se ejecutará cuando suceda el evento de push, para ello se crea dentro del proyecto un folder .github y dentro de este se crea un  folder .workflows, los workflows utilizan yaml  por lo que se crearan con extension .yaml/.yml, en mi caso crearé un workflow llamado ci.yml con el siguiente código (el proyecto completo lo pueden encontrar aquí)

name: Test
on: push

jobs:
  test_project:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v2
        with:
            python-version: 3.8
      - uses: abatilo/actions-poetry@v2.0.0
        with:
            poetry-version: 1.1.0
      - name: Install all of the dependencies
        run: |
          poetry install
      - name: Run test
        run: |
          poetry run pytest tests/ -v

En el código anterior se tiene lo siguiente

  • name indica el nombre del workflow
  • on indica la acción que activa el action
  • jobs indica el inicio de los jobs en este caso solo creo uno llamado test_project
  • runs-on indica al job en que SO se ejecutará
  • steps indica los steps que se declaran en este caso hay 5
  • uses este es un step que permite usar pasos que ya se han escrito por alguien más (una analogía podría ser con las imágenes de docker), por ejemplo el step checkout@v2 permite clonar o hacer pull del repositorio a la máquina donde se está ejecutando el job, recuerden que los jobs se ejecutan en un servidor diferente de github, por lo tanto debe clonarse el repositorio para poder seguir trabajando sobre él, estos actions que se "importan" los pueden encontrar aquí muchos de ellos permiten recibir parámetros utilizando with, en el caso de python permite decirle al action que versión se desea utilizar, estos parámetros los indican cada action en su documentación,  para el caso de el action poetry le indico con with la versión de poetry que deseo usar, estos actions son muy importantes por que ahorran demasiado trabajo, por ende antes de escribir todos los comandos para hacer alguna tarea es buena idea pasarse por estos actions y ver si alguien ya lo hizo y permite implementarla de manera rápida y sencilla
  • name son steps que declaró yo propiamente y generalmente siempre ejecutan comandos dentro del SO que está ejecutado el job, en este caso ejecuto comandos como poetry install, poetry run pytest tests/ -v

ahora para ejecutar y probarlo debemos llevar el proyecto a un repositorio de github, yo he dejado este proyecto para que lo prueben, es sencillo de código solo tiene unas funciones que se prueban utilizando pytest, sin embargo en desarrollo de software siempre ocurren bugs, errores, algo pudo haber quedado mal escrito y se necesita tener un feedback rápido, subir el codigo a un repo solamente para probar que el action funciona puede ser tedioso, por ello les recomendare la siguiente herramienta que "simula" los actions de github para probar que todo va bien y después de ello si subirlo a github (sucede mucho que se empiezan a hacer push y push solamente para probar los actions)

Act github actions localmente

"Think globally, act locally" act es una herramienta CLI construida en go y que utiliza contenedores de docker para simular los ambientes de github actions, permitiendo a los desarrolladores poder probar antes de subir el código a github, lo cual permite tener un feedback rápido, encontrar errores sintácticos y de nombres en los actions sin necesidad de subir cambios al repositorio, para instalarla en sistemas linux ejecuto el siguiente comando

curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash

act depende de docker por lo tanto es importante tener instalado docker en la maquina, para ejecutarlo deben ubicarse en el folder donde se encuentra su proyecto con los workflows creados y ejecutan el siguiente comando

act -s GITHUB_TOKEN=your_github_token

y se obtiene el siguiente resultado

Figura 3: Ejecución localmente del step instalar dependencias
Figura 4: Ejecución localmente del step testear código

como vieron se ejecutan los steps y jobs tal cual como se definieron, algo importante es que dentro de los github actions se pueden utilizar variables de entorno, en este caso como el repositorio es privado cuando se clone en la máquina del job, en este caso simulado se requiere un token para poder acceder al repositorio privado, por esto yo le paso el token respectivo, en otro artículo mostraré como trabajar con variables de entorno en los actions, ya que seguramente de requirara desplegar en otros servicios como AWS lambda o Google Cloud Container y ellos requieren claves de ingreso. Ahora con todo probado y sabiendo que no hay errores hago push al repositorio y automáticamente se ejecuta el action, esto lo podemos ver en la pestaña actions del repositorio

Figura 5: Ejecución de los steps en github actions

Figura 6: Ejecución del step probar código en github action

Conclusión

Realizar despliegue e integración continua es algo que se hace dia dia  por razones como: cambios que se solicitan, solución de errores, monitoreo etc automatizar estas entregas y despliegues es algo fundamental para la mejora de la productividad, sin duda github action es una opción bastante robusta y sólida para apoyar este proceso, tiene una muy buena documentación y si ya se está trabajando github para alojar el código el proceso será más sencillo, sin embargo si no te convence github hay varias opciones como CircleCI, Gitlab y Bitbucket  que igualmente son muy buenas