kb.erickguedes.com
GitHub Actions: CI/CD Moderno

Ambientes, Secrets e Variáveis

Aula 3 de 5

Ambientes (Environments)

Ambientes controlam deployment rules, secrets e protection gates.

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy-prod:
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://app.empresa.com
    steps:
      - run: echo "Deploying to production"

  deploy-staging:
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - run: echo "Deploying to staging"

Protection Rules

# Ambiente production no GitHub:
# Settings > Environments > production
# - Required reviewers: 2
# - Wait timer: 5 minutos
# - Deployment branches: main

Secrets

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # Secret do repositório
      - run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u ${{ secrets.DOCKER_USER }} --password-stdin

      # Secret do ambiente
      - run: ./deploy.sh
        env:
          API_KEY: ${{ secrets.API_KEY }}

      # Secret do org (herdado)
      - run: echo "${{ secrets.ORG_NPM_TOKEN }}" > .npmrc

Como Criar Secrets

# Via GitHub UI:
# Settings > Secrets and variables > Actions > New repository secret

# Via GitHub CLI:
gh secret set DOCKER_PASSWORD --body "senha123"
gh secret set API_KEY --app actions --env production

Variáveis

# Variáveis são como secrets mas expostas (não sensíveis)
on:
  workflow_dispatch:
    inputs:
      tag:
        description: 'Tag to deploy'
        required: true
        type: string
        default: 'latest'

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      NODE_ENV: ${{ vars.NODE_ENV }}
    steps:
      # Variável do workflow
      - run: echo "Building $IMAGE_NAME:${{ github.event.inputs.tag }}"

      # Variável do repositório/org (Settings > Variables)
      - run: echo "NPM registry: ${{ vars.NPM_REGISTRY }}"

      # Variável do ambiente
      - run: echo "Deploying to ${{ vars.URL }}"

Configuration Variables

# Criar via CLI
gh variable set NODE_ENV --body "production"
gh variable set NODE_ENV --env production

# Escopo (do mais específico ao geral):
# 1. Environment variable
# 2. Repository variable
# 3. Organization variable

Caching

jobs:
  build:
    steps:
      - uses: actions/cache@v4
        id: npm-cache
        with:
          path: |
            ~/.npm
            node_modules
          key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
          restore-keys: |
            npm-${{ runner.os }}-

      - if: steps.npm-cache.outputs.cache-hit != 'true'
        run: npm ci

Artifacts — Persistência entre Jobs

jobs:
  build:
    steps:
      - run: npm run build
      - uses: actions/upload-artifact@v4
        with:
          name: build-output
          path: dist/
          retention-days: 5   # padrão 90

  deploy:
    needs: build
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: build-output
          path: dist/

Lab: CI/CD Pipeline Completo

name: CI/CD

on:
  push:
    branches: [main, develop]
    paths-ignore:
      - 'docs/**'
      - '*.md'

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
      - run: npm ci
      - run: npm run lint
      - run: npm run typecheck
      - run: npm test -- --coverage
      - uses: actions/upload-artifact@v4
        with:
          name: coverage
          path: coverage/

  build-and-push:
    needs: quality
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    outputs:
      image: ${{ steps.build.outputs.image }}
    steps:
      - uses: actions/checkout@v4
      - uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - id: build
        uses: docker/build-push-action@v6
        with:
          push: true
          tags: |
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest

  deploy-staging:
    needs: build-and-push
    if: github.ref == 'refs/heads/develop'
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - uses: actions/checkout@v4
      - uses: ./.github/actions/k8s-deploy
        with:
          image: ${{ needs.build-and-push.outputs.image }}
          namespace: staging

Ambientes controlam deployment rules (approvals, wait timer). Secrets são criptografados e não aparecem em logs. Use vars para config não sensível. Caching acelera builds em ~70%.