Pipeline de Deploy - Web
Repositório: conceito-sankhya/force-web
Última atualização: 22 de outubro de 2025
Visão Geral
Sistema automatizado de CI/CD para o Web implementado através de GitHub Actions, garantindo build, testes, versionamento e deploy contínuo na AWS Elastic Beanstalk. O pipeline é dividido em duas workflows principais: validação em Pull Requests e deploy em produção.
Workflows Disponíveis
| Workflow | Arquivo | Trigger | Propósito |
|---|---|---|---|
| Validação de Build | build-check.yml | Pull Request | Valida que o código compila antes de fazer merge |
| Build, Release e Deploy | main.yml | Push na main | Compila, cria release no GitHub e faz deploy na AWS |
Workflow 1: Validação de Build (Pull Request)
Configuração e Triggers
name: Validate Build on Pull Request
on:
pull_request:
branches:
- dev
Quando executa: Toda vez que um Pull Request é aberto ou atualizado com destino à branch dev.
Objetivo: Garantir que o código proposto não quebra o build antes do merge.
Etapas do Processo
1. Setup do Ambiente
| Step | Ação | Detalhes |
|---|---|---|
| Checkout Repository | Clona o repositório | Usa fetch-depth: 1 para clonar apenas o último commit |
| Set up Node.js | Configura Node.js versão 22 | Utiliza cache do npm para acelerar instalações |
| Cache node_modules | Cache de dependências e build | Armazena ~/.npm, node_modules e .next/cache |
Estratégia de Cache
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
restore-keys: |
${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-
${{ runner.os }}-node-
O cache considera:
- Sistema operacional do runner
- Hash do
package-lock.json(detecta mudanças em dependências) - Hash de todos os arquivos de código (detecta mudanças no código)
2. Instalação de Dependências
npm ci --prefer-offline --no-audit --no-fund
Por que npm ci?
- ✅ Instalação mais rápida em ambientes CI
- ✅ Garante instalação exata baseada no
package-lock.json - ✅ Remove
node_modulesexistente antes de instalar - ✅ Flags otimizadas:
--prefer-offline,--no-audit,--no-fund
3. Build do Projeto
NODE_ENV=production npm run build
Variáveis de Ambiente:
| Variável | Valor | Propósito |
|---|---|---|
NODE_ENV | production | Ativa otimizações de produção |
NEXT_TELEMETRY_DISABLED | 1 | Desabilita telemetria do Next.js |
NODE_OPTIONS | --max-old-space-size=4096 | Aloca até 4GB de memória para o build |
4. Validação do Build
# Verifica se o diretório .next foi criado
if [ ! -d ".next" ]; then
echo "❌ Build failed: .next directory not found"
exit 1
fi
# Verifica se o BUILD_ID foi gerado
if [ ! -f ".next/BUILD_ID" ]; then
echo "❌ Build failed: BUILD_ID not found"
exit 1
fi
echo "✅ Build completed successfully"
echo "📁 Build size:"
du -sh .next/
Validações realizadas:
- ✅ Diretório
.nextexiste - ✅ Arquivo
.next/BUILD_IDfoi gerado - ✅ Exibe tamanho do build
Workflow 2: Build, Release e Deploy (Main)
Configuração e Triggers
name: Build and Deploy ForceWeb
on:
push:
branches:
- main
paths:
- "package.json"
Quando executa: Apenas quando há push na branch main E o arquivo package.json foi modificado.
O deploy só acontece quando há mudanças na versão do projeto (alterações no package.json), evitando deploys desnecessários.
Variáveis de Ambiente Globais
env:
NODE_VERSION: "18"
AWS_REGION: "sa-east-1"
APP_NAME: "force-web-env-1"
ENV_NAME: "force-web-env-1"
NODE_OPTIONS: "--max_old_space_size=6144"
| Variável | Valor | Uso |
|---|---|---|
NODE_VERSION | 18 | Versão do Node.js para build e deploy |
AWS_REGION | sa-east-1 | Região AWS (São Paulo) |
APP_NAME | force-web-env-1 | Nome da aplicação no Elastic Beanstalk |
ENV_NAME | force-web-env-1 | Nome do ambiente no Elastic Beanstalk |
NODE_OPTIONS | --max_old_space_size=6144 | Aloca até 6GB de memória para o build |
Job 1: Build Application
Outputs do Job
outputs:
version: ${{ steps.package_version.outputs.version }}
artifact_name: ${{ steps.package_version.outputs.artifact_name }}
Estes outputs são compartilhados com os jobs release e deploy.
Etapas Detalhadas
1. Setup e Preparação
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Clona histórico completo para tags
2. Verificação do Package Lock
if [ ! -f package-lock.json ]; then
echo "⚠️ package-lock.json not found. Running npm install to generate it..."
npm install --package-lock-only
fi
Garante que o package-lock.json existe, gerando-o se necessário.
3. Auditoria de Segurança
npm audit --audit-level=high
- Verifica vulnerabilidades de segurança nas dependências
--audit-level=high: Apenas vulnerabilidades de severidade alta ou críticacontinue-on-error: true: Não falha o build, apenas reporta
4. Execução de Testes
if npm run | grep -q "test"; then
npm run test -- --passWithNoTests
else
echo "No tests found, skipping..."
fi
- Verifica se existe script de teste no
package.json - Executa testes se disponíveis
--passWithNoTests: Não falha se não houver testescontinue-on-error: true: Build continua mesmo se testes falharem
5. Build da Aplicação
NODE_ENV=production npm run build
Configurações:
NODE_ENV=production: Otimizações de produçãoNODE_OPTIONS=--max_old_space_size=6144: 6GB de memória
6. Extração da Versão
VERSION=$(jq -r '.version' package.json)
ARTIFACT_NAME="ForceWeb${VERSION}"
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "artifact_name=${ARTIFACT_NAME}" >> $GITHUB_OUTPUT
Exemplo de saída:
- Versão:
2.5.3 - Nome do artefato:
ForceWeb2.5.3
7. Criação do Pacote de Deploy
Script Completo de Empacotamento
echo "🗂️ Creating deployment package for Next.js..."
# Listar estrutura atual
echo "📁 Current directory structure:"
ls -la
# Verificar se .next existe (crítico para Next.js)
if [ ! -d ".next" ]; then
echo "❌ ERROR: .next directory not found! Build may have failed."
exit 1
fi
echo "✅ .next directory found with size: $(du -sh .next | cut -f1)"
# Criar ZIP com arquivos necessários
echo "📦 Creating ZIP package..."
zip -r "${{ steps.package_version.outputs.artifact_name }}.zip" \
.platform \
.next \
pages \
public \
styles \
package.json \
package-lock.json \
next.config.js \
tsconfig.json \
-x "node_modules/*" "*.git*" "*.log" ".env*" "coverage/*" "*.test.*"
# Verificar criação do ZIP
if [ -f "${{ steps.package_version.outputs.artifact_name }}.zip" ]; then
echo "✅ ZIP created successfully!"
echo "📊 ZIP size: $(du -sh ${{ steps.package_version.outputs.artifact_name }}.zip | cut -f1)"
echo ""
echo "📋 ZIP contents:"
unzip -l "${{ steps.package_version.outputs.artifact_name }}.zip" | head -30
else
echo "❌ ERROR: Failed to create ZIP file!"
exit 1
fi
Arquivos Incluídos no Pacote
| Arquivo/Diretório | Descrição | Obrigatório |
|---|---|---|
.platform/ | Configurações AWS Elastic Beanstalk | ✅ Sim |
.next/ | Build otimizado do Next.js | ✅ Sim |
pages/ | Páginas da aplicação | ✅ Sim |
public/ | Assets estáticos | ✅ Sim |
styles/ | Arquivos CSS/SCSS | ✅ Sim |
package.json | Dependências e scripts | ✅ Sim |
package-lock.json | Lock de versões de dependências | ✅ Sim |
next.config.js | Configurações do Next.js | ✅ Sim |
tsconfig.json | Configurações do TypeScript | ✅ Sim |
Arquivos Excluídos
-x "node_modules/*" "*.git*" "*.log" ".env*" "coverage/*" "*.test.*"
node_modules/*: Dependências serão instaladas no servidor*.git*: Arquivos do Git*.log: Arquivos de log.env*: Variáveis de ambiente sensíveiscoverage/*: Relatórios de cobertura de testes*.test.*: Arquivos de teste
8. Upload do Artefato
- name: Upload Build Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ steps.package_version.outputs.artifact_name }}
path: ${{ steps.package_version.outputs.artifact_name }}.zip
retention-days: 30
compression-level: 6
Configurações:
retention-days: 30: Artefato fica disponível por 30 diascompression-level: 6: Nível médio de compressão (balanço entre tamanho e velocidade)
Job 2: Create GitHub Release
Dependências: Requer que o job build seja concluído com sucesso.
needs: build
Etapas do Release
1. Download do Artefato
- name: Download Build Artifact
uses: actions/download-artifact@v4
with:
name: ${{ needs.build.outputs.artifact_name }}
path: .
Baixa o artefato criado no job anterior.
2. Criação do Release no GitHub
- name: Create GitHub Release
id: create_release
uses: softprops/action-gh-release@v2
with:
tag_name: V${{ needs.build.outputs.version }}
name: ForceWeb V${{ needs.build.outputs.version }}
files: ${{ needs.build.outputs.artifact_name }}.zip
draft: false
prerelease: false
generate_release_notes: true
Estrutura do Release
Tag: V2.5.3 (exemplo)
Título: ForceWeb V2.5.3
Corpo da Release:
## 🚀 ForceWeb Release V2.5.3
**Branch:** `main`
**Commit:** abc123def456...
**Build Date:** 2025-10-22T14:30:00Z
### Changes
feat: Implementação de nova funcionalidade X
### Build Info
- ✅ Built with Node.js 18
- ✅ Memory allocation: --max_old_space_size=6144
- ✅ Target Region: sa-east-1
- 📦 Artifact: ForceWeb2.5.3.zip
---
_Auto-generated from main branch_
Anexos:
ForceWeb2.5.3.zip(pacote completo de deploy)
Job 3: Deploy to AWS
Dependências: Requer que os jobs build e release sejam concluídos.
needs: [build, release]
Etapas do Deploy
1. Download e Verificação do Artefato
echo "📦 Downloaded artifact: ForceWeb2.5.3.zip"
ls -la ForceWeb2.5.3.zip
echo "Size: $(du -h ForceWeb2.5.3.zip | cut -f1)"
2. Deploy no AWS Elastic Beanstalk
- name: Deploy to AWS Elastic Beanstalk
uses: einaregilsson/beanstalk-deploy@v22
with:
aws_access_key: ${{ secrets.AWS_ACCESS_KEY }}
aws_secret_key: ${{ secrets.AWS_SECRET_KEY }}
application_name: ${{ env.APP_NAME }}
environment_name: ${{ env.ENV_NAME }}
version_label: ${{ needs.build.outputs.version }}_${{ github.run_number }}
region: ${{ env.AWS_REGION }}
deployment_package: ${{ needs.build.outputs.artifact_name }}.zip
wait_for_deployment: true
wait_for_environment_recovery: 300
use_existing_version_if_available: false
Parâmetros de Deploy
| Parâmetro | Valor/Fonte | Descrição |
|---|---|---|
aws_access_key | secrets.AWS_ACCESS_KEY | Chave de acesso AWS (configurada nos secrets) |
aws_secret_key | secrets.AWS_SECRET_KEY | Chave secreta AWS (configurada nos secrets) |
application_name | force-web-env-1 | Nome da aplicação no Elastic Beanstalk |
environment_name | force-web-env-1 | Nome do ambiente a ser atualizado |
version_label | 2.5.3_123 (versão + número do run) | Identificador único da versão |
region | sa-east-1 | Região AWS (São Paulo) |
deployment_package | ForceWeb2.5.3.zip | Caminho do pacote de deploy |
wait_for_deployment | true | Aguarda conclusão do deploy antes de finalizar |
wait_for_environment_recovery | 300 | Aguarda até 5 minutos pela recuperação do ambiente |
use_existing_version_if_available | false | Sempre cria nova versão, mesmo se já existir |
3. Notificações de Deploy
Em caso de sucesso:
echo "🎉 ForceWeb Deployment Successful!"
echo "Version: 2.5.3"
echo "Environment: force-web-env-1"
echo "Region: sa-east-1"
echo "Version Label: 2.5.3_123"
Em caso de falha:
echo "❌ ForceWeb Deployment Failed!"
echo "Please check the logs above for details."
echo "Version attempted: 2.5.3"
exit 1
Job 4: Finally (Cleanup e Status)
Dependências: Executa sempre, independente do resultado dos outros jobs.
needs: [build, release, deploy]
if: always()
echo "Build status: success"
echo "Release status: success"
echo "Deploy status: success"
Secrets Necessários
Configure os seguintes secrets no GitHub (Settings → Secrets and variables → Actions):
| Secret | Descrição | Onde obter |
|---|---|---|
AWS_ACCESS_KEY | Chave de acesso da AWS | AWS IAM Console |
AWS_SECRET_KEY | Chave secreta da AWS | AWS IAM Console |
GITHUB_TOKEN | Token de acesso ao GitHub | Fornecido automaticamente pelo GitHub |
Nunca commite credenciais no código. Sempre use GitHub Secrets para armazenar informações sensíveis.
Fluxograma do Pipeline
Troubleshooting
Build Falha: ".next directory not found"
Problema: O diretório .next não foi criado após o build.
Soluções:
- Verifique se há erros de compilação no código
- Confirme que o comando
npm run buildestá correto nopackage.json - Verifique se há problemas de memória (aumentar
NODE_OPTIONS)
Deploy Falha: "Version already exists"
Problema: Tentativa de deploy com versão já existente no Elastic Beanstalk.
Soluções:
- Incremente a versão no
package.json - Verifique se
use_existing_version_if_available: falseestá configurado - Delete a versão antiga manualmente no console AWS (se necessário)
Erro: "AWS credentials not found"
Problema: Secrets da AWS não estão configurados corretamente.
Soluções:
- Verifique se
AWS_ACCESS_KEYeAWS_SECRET_KEYestão nos Secrets do GitHub - Confirme que as credenciais têm permissões adequadas no IAM
- Teste as credenciais localmente com AWS CLI
Pull Request Check Falha
Problema: Validação de build falha em PR.
Soluções:
- Execute
npm run buildlocalmente para reproduzir o erro - Verifique logs da action para identificar o erro específico
- Confirme que todas as dependências estão no
package.json - Limpe cache e tente novamente
Referências
- GitHub Actions Documentation
- AWS Elastic Beanstalk
- Next.js Deployment
- einaregilsson/beanstalk-deploy