DOMINE Reusable Workflows e Diga ADEUS ao Copia e Cola no seu CI/CD!

Se você trabalha com CI/CD no GitHub Actions, provavelmente já se pegou copiando e colando o mesmo código YAML entre diferentes workflows. E se eu te dissesse que existe uma forma muito mais elegante e profissional de fazer isso? Neste post, vou te mostrar como Reusable Workflows podem revolucionar seu pipeline de CI/CD.

O Problema: Copy-Paste Hell

Imagine esta situação familiar:

Você tem 10 repositórios, cada um com seu próprio workflow de CI/CD. Todos eles fazem basicamente a mesma coisa:

Agora você precisa atualizar a versão do Node.js usada em todos os workflows. O que acontece?

YAML
# repo-1/.github/workflows/ci.yml
- uses: actions/setup-node@v3
  with:
    node-version: '16'  # Precisa mudar para '18'
    
# repo-2/.github/workflows/ci.yml
- uses: actions/setup-node@v3
  with:
    node-version: '16'  # Precisa mudar aqui também
    
# repo-3/.github/workflows/ci.yml
- uses: actions/setup-node@v3
  with:
    node-version: '16'  # E aqui...
    
# ... mais 7 repositórios para atualizar manualmente
Clique para expandir e ver mais

Você acaba tendo que:

  1. Abrir 10 pull requests diferentes
  2. Atualizar manualmente cada arquivo
  3. Esperar que ninguém cometa erros no processo
  4. Lidar com inconsistências entre os repositórios

Isso não é produtivo, não é escalável, e definitivamente não é enterprise-grade.

A Solução: Reusable Workflows

Reusable Workflows são a resposta do GitHub Actions para o princípio DRY (Don’t Repeat Yourself) em CI/CD. Eles permitem que você:

Como Funcionam os Reusable Workflows

Estrutura Básica

Um Reusable Workflow é simplesmente um workflow normal do GitHub Actions com um gatilho especial: workflow_call.

YAML
# .github/workflows/reusable-build.yml
name: Reusable Build Workflow

on:
  workflow_call:
    inputs:
      node-version:
        description: 'Node.js version to use'
        required: false
        default: '18'
        type: string
    secrets:
      DEPLOY_TOKEN:
        description: 'Token for deployment'
        required: true

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run tests
        run: npm test
      
      - name: Build
        run: npm run build
Clique para expandir e ver mais

Usando o Reusable Workflow

Agora, em qualquer repositório, você pode simplesmente chamar este workflow:

YAML
# outro-repo/.github/workflows/ci.yml
name: CI Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    uses: minha-org/workflows/.github/workflows/reusable-build.yml@main
    with:
      node-version: '18'
    secrets:
      DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
Clique para expandir e ver mais

Pronto! Apenas 3 linhas e você tem todo o pipeline funcionando.

Recursos Avançados dos Reusable Workflows

1. Inputs Tipados

Os Reusable Workflows suportam diferentes tipos de inputs:

YAML
on:
  workflow_call:
    inputs:
      environment:
        type: string
        required: true
      
      enable-cache:
        type: boolean
        default: true
      
      max-parallel-jobs:
        type: number
        default: 4
Clique para expandir e ver mais

Isso garante type-safety e validação automática dos parâmetros.

2. Outputs

Workflows reutilizáveis podem retornar valores para quem os chamou:

YAML
on:
  workflow_call:
    outputs:
      build-version:
        description: "Version of the built artifact"
        value: ${{ jobs.build.outputs.version }}

jobs:
  build:
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.get-version.outputs.version }}
    steps:
      - id: get-version
        run: echo "version=$(cat package.json | jq -r .version)" >> $GITHUB_OUTPUT
Clique para expandir e ver mais

Depois você pode usar esse output:

YAML
jobs:
  build:
    uses: ./.github/workflows/reusable-build.yml
    
  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Deploy version ${{ needs.build.outputs.build-version }}
        run: echo "Deploying ${{ needs.build.outputs.build-version }}"
Clique para expandir e ver mais

3. Secrets Management

Secrets podem ser passados de forma segura:

YAML
jobs:
  production-deploy:
    uses: ./.github/workflows/deploy.yml
    secrets:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Clique para expandir e ver mais

Ou, se você quiser passar todos os secrets automaticamente:

YAML
jobs:
  deploy:
    uses: ./.github/workflows/deploy.yml
    secrets: inherit  # Passa todos os secrets do caller
Clique para expandir e ver mais

Padrões e Best Practices

1. Versionamento de Workflows

Sempre use tags ou branches específicas ao chamar workflows reutilizáveis:

YAML
# ✅ Bom - usa uma tag específica
uses: minha-org/workflows/.github/workflows/ci.yml@v1.2.0

# ✅ Bom - usa um branch específico
uses: minha-org/workflows/.github/workflows/ci.yml@main

# ❌ Evite - SHA específico é difícil de gerenciar
uses: minha-org/workflows/.github/workflows/ci.yml@a1b2c3d4
Clique para expandir e ver mais

2. Repositório Centralizado

Crie um repositório dedicado para seus workflows reutilizáveis:

PLAINTEXT
minha-org/github-workflows/
├── .github/
│   └── workflows/
│       ├── build-node.yml
│       ├── build-python.yml
│       ├── build-go.yml
│       ├── deploy-aws.yml
│       ├── deploy-gcp.yml
│       └── security-scan.yml
└── README.md
Clique para expandir e ver mais

3. Documentação Clara

Documente cada workflow reutilizável:

YAML
name: Node.js Build Workflow

# Descrição: Pipeline completo para aplicações Node.js
# 
# Inputs:
#   - node-version: Versão do Node.js (padrão: '18')
#   - run-tests: Executar testes (padrão: true)
#   - run-lint: Executar linter (padrão: true)
#
# Secrets necessários:
#   - NPM_TOKEN: Token para registry privado (opcional)
#
# Outputs:
#   - artifact-name: Nome do artefato gerado
#   - test-results: Status dos testes

on:
  workflow_call:
    # ...
Clique para expandir e ver mais

4. Granularidade Apropriada

Crie workflows com responsabilidades bem definidas:

YAML
# ✅ Bom - workflows específicos
- build-and-test.yml
- security-scan.yml
- deploy-to-aws.yml

# ❌ Evite - workflow monolítico
- do-everything.yml
Clique para expandir e ver mais

Casos de Uso Reais

1. Pipeline Multirepo Consistente

YAML
# Template para todos os microsserviços
jobs:
  ci:
    uses: company/workflows/.github/workflows/microservice-ci.yml@v2
    with:
      language: 'node'
      test-framework: 'jest'
    secrets: inherit
Clique para expandir e ver mais

Todos os 50 microsserviços usam o mesmo pipeline. Uma atualização -> 50 repos atualizados.

2. Ambientes de Deploy Padronizados

YAML
jobs:
  deploy-staging:
    uses: company/workflows/.github/workflows/deploy-k8s.yml@v1
    with:
      environment: 'staging'
      namespace: 'my-app-staging'
    secrets: inherit
    
  deploy-production:
    needs: deploy-staging
    uses: company/workflows/.github/workflows/deploy-k8s.yml@v1
    with:
      environment: 'production'
      namespace: 'my-app-prod'
    secrets: inherit
Clique para expandir e ver mais

3. Security Scanning Centralizado

YAML
jobs:
  security:
    uses: security-team/workflows/.github/workflows/security-scan.yml@main
    with:
      scan-type: 'full'
      fail-on: 'high'
Clique para expandir e ver mais

O time de segurança mantém o workflow. Todos os times se beneficiam das atualizações.

Comparação: Antes vs Depois

Antes (sem Reusable Workflows)

YAML
# 150 linhas de YAML duplicado em cada repo
name: CI
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '18'
      - run: npm ci
      - run: npm test
      # ... mais 30 linhas
  
  build:
    runs-on: ubuntu-latest
    # ... mais 40 linhas
    
  security:
    # ... mais 30 linhas
    
  deploy:
    # ... mais 50 linhas
Clique para expandir e ver mais

Problemas:

Depois (com Reusable Workflows)

YAML
# 10 linhas em cada repo
name: CI
on: [push]

jobs:
  pipeline:
    uses: company/workflows/.github/workflows/standard-pipeline.yml@v2
    with:
      app-name: 'my-app'
      environment: 'production'
    secrets: inherit
Clique para expandir e ver mais

Benefícios:

Matriz de Workflows Combinados

Você pode criar workflows compostos chamando múltiplos workflows reutilizáveis:

YAML
jobs:
  lint:
    uses: ./.github/workflows/lint.yml
    
  test:
    uses: ./.github/workflows/test.yml
    needs: lint
    
  build:
    uses: ./.github/workflows/build.yml
    needs: test
    
  security-scan:
    uses: ./.github/workflows/security.yml
    needs: build
    
  deploy-staging:
    uses: ./.github/workflows/deploy.yml
    needs: [build, security-scan]
    with:
      environment: 'staging'
    
  integration-tests:
    uses: ./.github/workflows/integration-tests.yml
    needs: deploy-staging
    
  deploy-production:
    uses: ./.github/workflows/deploy.yml
    needs: integration-tests
    with:
      environment: 'production'
Clique para expandir e ver mais

Cada step é um workflow reutilizável independente, permitindo composição flexível.

Monitoramento e Observabilidade

Reusable Workflows aparecem como jobs expandidos na UI do GitHub Actions, permitindo:

Limitações e Considerações

Limitações Atuais

  1. Depth Limit: Workflows reutilizáveis podem chamar outros workflows reutilizáveis, mas apenas até 4 níveis de profundidade.

  2. Environment Variables: Variáveis de ambiente não são automaticamente propagadas (use inputs explícitos).

  3. Contextos Limitados: Alguns contextos como github.token podem se comportar diferente em workflows reutilizáveis.

Workarounds

Para variáveis de ambiente:

YAML
# Caller workflow
env:
  GLOBAL_VAR: 'value'

jobs:
  call-workflow:
    uses: ./.github/workflows/reusable.yml
    with:
      env-var: ${{ env.GLOBAL_VAR }}  # Passe explicitamente
Clique para expandir e ver mais

Conclusão: Eleve seu CI/CD ao Próximo Nível

Reusable Workflows são uma das funcionalidades mais poderosas do GitHub Actions, mas ainda são subutilizadas. Ao adotá-los, você:

Checklist de Migração

Próximos Passos

No próximo post/vídeo, vou mostrar:

Recursos Úteis


Já usa Reusable Workflows? Compartilha nos comentários como você os utiliza! Tem dúvidas sobre implementação? Deixa sua pergunta abaixo!

#GitHubActions #CICD #DevOps #Automation #BestPractices

Advertisement

Comments

Iniciar busca

Digite palavras-chave para buscar

↑↓
ESC
⌘K Atalho