Ejecutar múltiples combinaciones de parámetros en un solo workflow de GitHub Actions

Una de las características que más me gusta de GitHub Actions es la forma que tiene de reutilizar los workflows. Hoy quiero hablarte de cómo a través de las matrices puedes lanzar un mismo workflow con múltiples combinaciones de los parámetros que necesitas.

Creando una estrategia

Lo primero que debes saber es qué posibles combinaciones vas a querer para tu jobs y para qué. Empecemos con algo sencillo: quiero que mi workflow se ejecute en las últimas versiones de los sistemas operativos más comunes. Para ello, puedes crear una estrategia que incluya una matriz llamada os con los sistemas operativos que quieres probar:

name: 'Playing with matrix'

on: push

jobs:
  test:
    strategy:
    #A job matrix can generate a maximum of 256 jobs per workflow run     
      matrix:        
        os: [ubuntu-latest, macos-latest, windows-latest]      
    runs-on: ${{ matrix.os }}
    steps:
    - name: Print a greeting
      run: |
        echo Wake up Neo...

Como ves, dentro del job test he definido un apartado llamado strategy, con un apartado más a su vez llamado matrix, donde puedo incluir todas las matrices que necesite, teniendo en cuenta que se pueden generar como máximo 256 jobs por cada ejecución. En este ejemplo solo he definido que quiero probar el job test en las últimas versiones de Ubuntu, MacOS y Windows. Si ejecuto este flujo verás que el resultado es como el que sigue:

Una ejecución por cada valor de la matriz

Como ves, con un solo workflow, y un solo job, es posible lanzar los mismos pasos con diferentes configuraciones de una forma súper sencilla.

También podemos combinar múltiples matrices dentro del job. Por ejemplo, podemos utilizar diferentes versiones de Node.js:

name: 'Playing with matrix'

on: push

jobs:
  test:
    strategy:
    #A job matrix can generate a maximum of 256 jobs per workflow run     
      matrix:        
        os: [ubuntu-latest, macos-latest, windows-latest]
        node: [6,8,10]
    runs-on: ${{ matrix.os }}
    steps:
    - name: Print a greeting
      run: |
        echo Wake up Neo...
    - uses: actions/[email protected]
      with:
        node-version: ${{ matrix.node }}

El resultado en este caso será la combinación de la primera matriz y la segunda ya que, por ejemplo, tendrás una ejecución de Ubuntu por cada versión de Node.js que tengas, esto es 3 ejecuciones, 9 en total.

Combinaciones entre dos matrices

Puede ocurrir también que aunque quieras que todas las combinaciones de sistemas operativos se aprovechen del mismo flujo definido, haya combinaciones que quizás no se puedan dar. Es por ello que tienes la opción de excluir, incluso incluir, algunas de ellas. Por ejemplo, si quisiera excluir la combinación windows-latest y node 6 lo haría de la siguiente manera:

name: 'Playing with matrix'

on: push

jobs:
  test:
    strategy:
    #A job matrix can generate a maximum of 256 jobs per workflow run     
      matrix:        
        os: [ubuntu-latest, macos-latest, windows-latest]
        node: [6,8,10]    
        exclude:
        - os: windows-latest
          node: 6
    runs-on: ${{ matrix.os }}
    steps:
    - name: Print a greeting     
      run: |
        echo Wake up Neo...
    - uses: actions/[email protected]
      with:
        node-version: ${{ matrix.node }}

Si revisas la ejecución podrás comprobar que para windows-latest solo se han lanzado dos, la 8 y la 10.

Excluir combinaciones

Todo esto no solo aplica a sistemas operativos y versiones sino que incluso podemos utilizarlo para otras tareas. Por ejemplo, puedo utilizarla en la action que te mostré el otro día, para lanzar diferentes pruebas de carga con diferentes URLs con el mismo flujo:

name: Testing ab-action

on: push

jobs:
  benchmarking:
    name: Test my site
    runs-on: ubuntu-latest
    strategy:
      matrix:
        URL:
        - https://bethanysshopapi.azurewebsites.net/api/country
        - https://bethanysshopapi.azurewebsites.net/api/employee
        - https://bethanysshopapi.azurewebsites.net/api/jobcategory   
      
    steps:
      - uses: actions/[email protected]
      - uses: ./ab-action
        with:
          URL: ${{ matrix.URL }}
          

Como es de esperar, el resultado será una ejecución por cada una de las URLs:

Reutilizar el workflow de Apache Benchmark con N URLs

Existen algunos parámetros adicionales a las estrategias que también es importante que conozcas:

  • fail-fast (por defecto a true): GitHub por defecto cancela todos jobs que estén ejecutándose en el momento que uno falla.
  • max-parallel: por defecto GitHub intentará todos los que pueda en ese momento pero puedes limitarlo.

¡Saludos!