Concurrencia en flujos de Github Actions
Tags: github, ci, devops, spanish
Published: 2021-12-18 21:02:15


En algunos casos se espera que un flujo de trabajo sea ejecutado una única vez (_e.g. despliegues_) o ejecutar la versión más actual (_e.g. el último commit de un Pull Request_) pero a simple vista no es tan sencillo de configurar utilizando [GitHub Actions](https://github.com/features/actions).

El gasto de actions es una de las razones principales por la se requiere optimizar al máximo la configuración de los flujos de trabajos. Una de las tareas más comunes que se quiere evitar es la de ejecutar multiples veces flujos cada vez que realizamos una acción.

Para este caso:

![ejemplo-multiples-ejecuciones-mismo-job](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/73w0kz4v3o4ag398apue.png)

```yaml
on:
  push:
    branches:
    - staging # Despliegue de aplicación
  pull_request:
    branches:
    - staging # Validaciones por cada commit agregado en un Pull Request
```

Para cualquiera de las opciones anteriores, se espera que sólo se tenga en cuenta la versión más reciente de los cambios y no se requiere que se ejecuten todos los flujos que se encolen.

1. Actions creados por terceros: [cancel-workflow-action](https://github.com/marketplace/actions/cancel-workflow-action) es una alternativa que funciona pero nunca va a ser tan respaldada como una "opción nativa" porque un action creado por un tercero requiere más configuración y tiempo de ejecución.
Ésta fue una gran opción hasta el inicio del año 2021 ya que no se tenia una configuración del propio GitHub. Por eso es una opción valida.

```yaml
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Cancel Previous Runs
        uses: styfle/cancel-workflow-action@0.9.1
        with:
          access_token: ${{ github.token }}
      ...
```

Agregando el action `cancel-workflow-action` como un paso en el job será suficiente para ejecutar una única vez el job por flujo. Se utiliza `access_token` (_credencial generada en GitHub_) para acceder a la API de GitHub y consultar información sobre ejecuciones activas y poder cancelarlas de ser necesario.

> Opción efectiva pero "costosa" en tiempo y recursos.

2. Configuración del flujo de trabajo (**Recomendada**): Establecer las opciones de [Concurrencia](https://github.blog/changelog/2021-04-19-github-actions-limit-workflow-run-or-job-concurrency/).

```yaml
concurrency:
  group: ci-${{ github.ref }} # Grupo filtrado por nombre de la rama github.ref
  cancel-in-progress: true
```

Concurrencia se refiere a la cantidad de ejecuciones del mismo tipo que se realizan simultáneamente. Es decir, las ejecuciones marcadas como `group` (_tag para agrupar cierto tipo de jobs_) se podrían ejecutar al mismo tiempo o ser ejecutadas de a una.

Por defecto, la opción `cancel-in-progress` está activada y por esto obtenemos el resultado esperado: Cancelar todas las ejecuciones menos la más reciente.

![ejemplo-multiples-ejecuciones-mismo-job-cancelar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rogbqkejwk48dvle8wo1.png)

Si `cancel-in-progress` se desactiva, cada uno de las ejecuciones encoladas se pausará y terminarán una a la vez hasta llegar a la más reciente.

![ejemplo-multiples-ejecuciones-mismo-job-cola](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qf58wkbptc5byn3tn9bt.png)

> De momento es la opción recomendada: Al ejecutarse en la sección de configuración del flujo de trabajo es más rápida y ahorra recursos ya que en este punto aún no se han desplegado los requerimientos de los jobs.