Skip to content

Latest commit

 

History

History
379 lines (305 loc) · 8.74 KB

File metadata and controls

379 lines (305 loc) · 8.74 KB

Guia GitHub Actions

Visão Geral

GitHub Actions permite automatizar workflows de desenvolvimento diretamente no GitHub. É uma ferramenta poderosa para CI/CD (Integração Contínua/Entrega Contínua).

Cookbook

1. Estrutura Básica de Workflow

# Workflow completo para uma aplicação Node.js
name: CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]
  schedule:
    - cron: '0 0 * * *'  # Execução diária à meia-noite

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'
      
      - name: Install Dependencies
        run: npm ci
      
      - name: Lint
        run: npm run lint
        
      - name: Type Check
        run: npm run type-check
      
      - name: Test
        run: npm test -- --coverage
        
      - name: Upload Coverage
        uses: codecov/codecov-action@v3
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

2. Secrets e Variáveis de Ambiente

name: Deploy Application

env:
  # Variáveis globais
  APP_NAME: minha-aplicacao
  
jobs:
  deploy:
    runs-on: ubuntu-latest
    # Variáveis por ambiente
    environment:
      name: production
      url: ${{ steps.deploy.outputs.url }}
    
    env:
      # Variáveis do job
      DEPLOY_ENV: production
      
    steps:
      - uses: actions/checkout@v3
      
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}
          
      - name: Deploy to ECS
        id: deploy
        env:
          # Variáveis do step
          CONTAINER_IMAGE: ${{ secrets.ECR_REGISTRY }}/${{ env.APP_NAME }}:${{ github.sha }}
        run: |
          aws ecs update-service --cluster prod-cluster \
            --service ${{ env.APP_NAME }} \
            --force-new-deployment

3. Matriz de Build

name: Cross-Platform Tests

jobs:
  test:
    strategy:
      fail-fast: false  # Continua mesmo se um job falhar
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [16, 18, 20]
        include:
          # Configurações extras para casos específicos
          - os: ubuntu-latest
            node-version: 18
            experimental: true
            npm-flags: '--legacy-peer-deps'
        exclude:
          # Excluir combinações problemáticas
          - os: windows-latest
            node-version: 16
    
    runs-on: ${{ matrix.os }}
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          
      - name: Install Dependencies
        run: npm ci ${{ matrix.npm-flags }}
        
      - name: Run Tests
        run: npm test

4. Cache e Otimização

name: Optimized Build

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v3
      
      # Cache do Node.js
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'
      
      # Cache do build
      - name: Cache Build
        uses: actions/cache@v3
        with:
          path: |
            dist
            .next
            build
            public/build
          key: ${{ runner.os }}-build-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
          restore-keys: |
            ${{ runner.os }}-build-
      
      # Cache do ESLint
      - name: Cache ESLint
        uses: actions/cache@v3
        with:
          path: .eslintcache
          key: ${{ runner.os }}-eslint-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
      
      - name: Install Dependencies
        run: npm ci
      
      - name: Build
        run: npm run build

5. Deployments

name: Production Deploy

on:
  push:
    tags:
      - 'v*'

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://minha-app.com
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Create GitHub Release
        id: release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: Release ${{ github.ref }}
          draft: false
          prerelease: false
      
      - name: Deploy to Production
        id: deploy
        uses: my-org/deploy-action@v1
        with:
          environment: production
          token: ${{ secrets.DEPLOY_TOKEN }}
      
      - name: Verify Deployment
        run: |
          ./scripts/verify-deployment.sh
      
      - name: Rollback on Failure
        if: failure()
        run: |
          ./scripts/rollback.sh ${{ github.event.before }}

6. Integrações

name: Multi-Service Integration

jobs:
  integrate:
    runs-on: ubuntu-latest
    
    steps:
      # Docker Build e Push
      - name: Login to DockerHub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      
      - name: Build and Push
        uses: docker/build-push-action@v4
        with:
          push: true
          tags: user/app:latest
      
      # Deploy no Kubernetes
      - name: Setup kubectl
        uses: azure/setup-kubectl@v3
        
      - name: Deploy to K8s
        run: |
          kubectl apply -f k8s/
          kubectl rollout status deployment/minha-app
      
      # Integração com AWS
      - name: Configure AWS
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      
      # Monitoramento com Datadog
      - name: Notify Datadog
        run: |
          curl -X POST "https://api.datadoghq.com/api/v1/events" \
            -H "Content-Type: application/json" \
            -H "DD-API-KEY: ${DD_API_KEY}" \
            -d @- << EOF
            {
              "title": "Deployment Completed",
              "text": "Version ${{ github.sha }} deployed",
              "tags": ["env:prod", "service:api"]
            }
            EOF

7. Workflows Reutilizáveis

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

on:
  workflow_call:
    inputs:
      node-version:
        required: false
        type: string
        default: '18'
    secrets:
      npm-token:
        required: true

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: ${{ inputs.node-version }}
          registry-url: 'https://registry.npmjs.org'
      
      - name: Build and Test
        run: |
          npm ci
          npm run build
          npm test
        env:
          NODE_AUTH_TOKEN: ${{ secrets.npm-token }}

# Uso do workflow reutilizável
name: Main Pipeline

on: [push]

jobs:
  call-build:
    uses: ./.github/workflows/reusable-build.yml
    with:
      node-version: '20'
    secrets:
      npm-token: ${{ secrets.NPM_TOKEN }}

8. Monitoramento e Logs

name: Debug Workflow

jobs:
  monitor:
    runs-on: ubuntu-latest
    
    steps:
      - name: Setup tmate session
        if: ${{ failure() }}
        uses: mxschmitt/action-tmate@v3
        
      - name: Setup Problem Matchers
        run: |
          echo "::add-matcher::.github/problem-matchers/tsc.json"
          echo "::add-matcher::.github/problem-matchers/eslint.json"
      
      - name: Annotate Build
        run: |
          echo "::warning file=src/app.ts,line=10,col=5::Possível memory leak"
          echo "::error file=src/api.ts,line=15::Endpoint inseguro detectado"
      
      - name: Notify Slack
        if: always()
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          fields: repo,message,commit,author,action,eventName,ref,workflow,job,took
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
      
      - name: Export Metrics
        run: |
          echo "workflow_duration_seconds{status=\"${{ job.status }}\"} ${{ steps.measure.outputs.duration }}" >> metrics.txt
        
      - name: Upload Logs
        if: always()
        uses: actions/upload-artifact@v3
        with:
          name: workflow-logs
          path: |
            ./**/*.log
            ./metrics.txt