GitHub Actions Matrix Strategy: Testando Múltiplas Versões Simultaneamente

Testar seu código em apenas uma versão de Node.js, Python ou Ruby é arriscado. E se seu código quebrar no Python 3.9 mas funcionar no 3.12? E se houver bugs específicos do Windows que você não detecta no Linux? Matrix Strategy do GitHub Actions resolve isso de forma elegante.

O Problema: Compatibilidade Multi-Versão

Imagine este cenário comum:

YAML
# Workflow simples
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm test
Clique para expandir e ver mais

Problemas:

Para testar em 3 versões do Node × 3 SOs = 9 combinações, você precisaria de 9 jobs separados. Muito código duplicado!

A Solução: Matrix Strategy

Matrix Strategy permite definir múltiplas dimensões de teste em um único job:

YAML
jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [16, 18, 20]
    
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm test
Clique para expandir e ver mais

Resultado: 9 jobs executados em paralelo automaticamente! 🚀

Como Funciona a Matrix

Sintaxe Básica

YAML
strategy:
  matrix:
    # Cada chave define uma dimensão
    language: [node, python, go]
    version: [latest, stable]
Clique para expandir e ver mais

GitHub Actions cria produto cartesiano de todas as combinações:

Total: 3 × 2 = 6 jobs

Acessando Valores da Matrix

Use ${{ matrix.variavel }} para acessar o valor atual:

YAML
steps:
  - name: Print current combination
    run: |
      echo "Testing ${{ matrix.language }} version ${{ matrix.version }}"
Clique para expandir e ver mais

Exemplos Práticos

1. Teste Multi-Versão Node.js

YAML
name: Node.js CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [16.x, 18.x, 20.x, 21.x]
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run tests
        run: npm test
      
      - name: Run lint
        run: npm run lint
Clique para expandir e ver mais

Resultado: Testa em Node 16, 18, 20 e 21 simultaneamente.

2. Teste Cross-Platform

YAML
name: Cross-Platform Tests

on: [push, pull_request]

jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        python-version: ['3.9', '3.10', '3.11', '3.12']
    
    runs-on: ${{ matrix.os }}
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
      
      - name: Run tests
        run: pytest
Clique para expandir e ver mais

Resultado: 3 SOs × 4 versões Python = 12 jobs em paralelo

3. Matrix com Múltiplas Dimensões

YAML
strategy:
  matrix:
    os: [ubuntu-latest, windows-latest]
    node-version: [18, 20]
    database: [postgres, mysql, sqlite]
    include:
      # Adiciona combinação específica
      - os: macos-latest
        node-version: 20
        database: postgres

steps:
  - name: Start database
    run: |
      echo "Starting ${{ matrix.database }} on ${{ matrix.os }}"
Clique para expandir e ver mais

Resultado: (2 × 2 × 3) + 1 = 13 jobs

Recursos Avançados

1. Include - Adicionar Combinações Específicas

YAML
strategy:
  matrix:
    os: [ubuntu-latest]
    node-version: [18, 20]
    include:
      # Testa Node 16 apenas no Ubuntu
      - os: ubuntu-latest
        node-version: 16
      
      # Testa Node 20 no macOS também
      - os: macos-latest
        node-version: 20
        
      # Adiciona variáveis extras para combinação específica
      - os: ubuntu-latest
        node-version: 20
        experimental: true
Clique para expandir e ver mais

2. Exclude - Remover Combinações Indesejadas

YAML
strategy:
  matrix:
    os: [ubuntu-latest, windows-latest, macos-latest]
    node-version: [16, 18, 20]
    exclude:
      # Node 16 não suportado no Windows
      - os: windows-latest
        node-version: 16
      
      # Economizar runners - pular macOS para Node 18
      - os: macos-latest
        node-version: 18
Clique para expandir e ver mais

Resultado: (3 × 3) - 2 = 7 jobs ao invés de 9

3. Fail-Fast (Padrão: true)

YAML
strategy:
  fail-fast: false  # Continua outros jobs mesmo se um falhar
  matrix:
    version: [1, 2, 3, 4, 5]
Clique para expandir e ver mais

fail-fast: true (padrão): Cancela todos os jobs se um falhar
fail-fast: false: Roda todos independentemente

4. Max-Parallel - Limitar Execuções Simultâneas

YAML
strategy:
  max-parallel: 3  # Apenas 3 jobs por vez
  matrix:
    version: [1, 2, 3, 4, 5, 6, 7, 8]
Clique para expandir e ver mais

Útil para:

Casos de Uso Reais

1. Biblioteca NPM Multi-Versão

YAML
name: NPM Package CI

on: [push, pull_request]

jobs:
  test:
    strategy:
      matrix:
        node-version: [16, 18, 20, 22]
        os: [ubuntu-latest, windows-latest, macos-latest]
        exclude:
          # Node 22 ainda experimental
          - os: windows-latest
            node-version: 22
    
    runs-on: ${{ matrix.os }}
    
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      
      - run: npm ci
      - run: npm test
      - run: npm run build
      
      - name: Test installation
        run: |
          npm pack
          npm install -g *.tgz
Clique para expandir e ver mais

2. Aplicação com Múltiplos Bancos

YAML
strategy:
  matrix:
    database:
      - type: postgres
        version: '14'
        port: 5432
      - type: postgres
        version: '15'
        port: 5432
      - type: mysql
        version: '8.0'
        port: 3306
      - type: mariadb
        version: '10.11'
        port: 3306

steps:
  - name: Start ${{ matrix.database.type }}
    run: |
      docker run -d \
        -p ${{ matrix.database.port }}:${{ matrix.database.port }} \
        ${{ matrix.database.type }}:${{ matrix.database.version }}
  
  - name: Run migrations
    env:
      DATABASE_URL: ${{ matrix.database.type }}://localhost:${{ matrix.database.port }}/test
    run: npm run migrate
  
  - name: Run tests
    run: npm test
Clique para expandir e ver mais

3. Build Multi-Arquitetura

YAML
strategy:
  matrix:
    include:
      - arch: amd64
        os: ubuntu-latest
      - arch: arm64
        os: ubuntu-latest
      - arch: armv7
        os: ubuntu-latest

steps:
  - uses: actions/checkout@v4
  
  - name: Set up QEMU
    uses: docker/setup-qemu-action@v3
  
  - name: Build for ${{ matrix.arch }}
    run: |
      docker buildx build \
        --platform linux/${{ matrix.arch }} \
        -t myapp:${{ matrix.arch }} \
        .
Clique para expandir e ver mais

Naming e Identificação

Nome Dinâmico do Job

YAML
jobs:
  test:
    name: Test on ${{ matrix.os }} with Node ${{ matrix.node-version }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node-version: [18, 20]
    runs-on: ${{ matrix.os }}
Clique para expandir e ver mais

Resultado na UI:

Matrix com Outputs

Você pode usar outputs de uma matrix em jobs subsequentes:

YAML
jobs:
  build:
    strategy:
      matrix:
        version: [v1, v2, v3]
    outputs:
      # Não funciona diretamente - precisa workaround
      artifact-name: myapp-${{ matrix.version }}
    steps:
      - run: echo "Building ${{ matrix.version }}"
  
  # Alternativa: usar artefatos nomeados
  deploy:
    needs: build
    steps:
      - uses: actions/download-artifact@v4
        with:
          pattern: myapp-*
Clique para expandir e ver mais

Performance e Custos

Minutos de Consumo

Exemplo: Matrix com 12 combinações, cada uma rodando 5 minutos.

fail-fast: true (se nenhum falhar): 5 minutos × 12 = 60 minutos de runner
fail-fast: true (se um falhar em 2min): ~2-5 minutos (cancela os outros)
fail-fast: false: Sempre 60 minutos

Otimizações

  1. Use cache agressivamente:
YAML
- uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }}
Clique para expandir e ver mais
  1. Priorize combinações importantes:
YAML
include:
  - os: ubuntu-latest
    node-version: 20
    priority: high  # Rode isso primeiro
Clique para expandir e ver mais
  1. Use max-parallel para controlar custo:
YAML
strategy:
  max-parallel: 2  # Máximo 2 jobs por vez em contas free
Clique para expandir e ver mais

Debugging Matrix

Ver Todas as Combinações

YAML
jobs:
  debug:
    strategy:
      matrix:
        os: [ubuntu, windows, macos]
        version: [1, 2, 3]
    steps:
      - name: Print matrix
        run: |
          echo "OS: ${{ matrix.os }}"
          echo "Version: ${{ matrix.version }}"
          echo "Runner: ${{ runner.os }}"
Clique para expandir e ver mais

Testar Uma Combinação

Use workflow_dispatch com inputs:

YAML
on:
  workflow_dispatch:
    inputs:
      os:
        type: choice
        options: [ubuntu-latest, windows-latest, macos-latest]
      node-version:
        type: choice
        options: [16, 18, 20]

jobs:
  test:
    runs-on: ${{ inputs.os }}
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
Clique para expandir e ver mais

Best Practices

  1. Sempre teste versões LTS + latest
  2. Use fail-fast: false em PRs para ver todos os problemas
  3. Documente quais combinações são obrigatórias
  4. Use exclude para economizar em combinações não importantes
  5. Nomeie jobs descritivamente
  6. Evite matrices muito grandes (>20 combinações)
  7. Não duplique lógica - use matrix

Conclusão

Matrix Strategy transforma:

YAML
# De 100+ linhas de código duplicado
test-node-16-ubuntu: ...
test-node-18-ubuntu: ...
test-node-20-ubuntu: ...
test-node-16-windows: ...
# ... etc
Clique para expandir e ver mais

Para:

YAML
# 20 linhas elegantes
strategy:
  matrix:
    os: [ubuntu, windows, macos]
    node: [16, 18, 20]
Clique para expandir e ver mais

Benefícios:


Já usa Matrix Strategy? Compartilhe nos comentários quantas combinações você testa!

#GitHubActions #CI #Testing #DevOps

Advertisement

Comments

Iniciar busca

Digite palavras-chave para buscar

↑↓
ESC
⌘K Atalho