diff --git a/.github/workflows/README-CI-CD.md b/.github/workflows/README-CI-CD.md new file mode 100644 index 00000000..24fcc3ac --- /dev/null +++ b/.github/workflows/README-CI-CD.md @@ -0,0 +1,135 @@ +# CI/CD - Avanzato Tecnologia + +## Estrutura do Pipeline + +``` +Push para main/master + | + v ++------------------+ +------------------+ +------------------+ +| BUILD | --> | PRESERVAR ASSETS | --> | DEPLOY | +| | | | | | +| - Checkout | | - Logo | | - SCP para VPS | +| - npm install | | - Imagens | | - Limpar cache | +| - npm run build | | - Favicon | | - Notificar | ++------------------+ +------------------+ +------------------+ +``` + +--- + +## Configurar Secrets no GitHub + +Va em: **Settings > Secrets and variables > Actions > New repository secret** + +| Secret | Descricao | Exemplo | +|--------|-----------|---------| +| `SSH_HOST` | IP ou dominio do servidor | `201.45.120.30` ou `avanzato.com.br` | +| `SSH_USER` | Usuario SSH | `root` ou `deploy` | +| `SSH_PRIVATE_KEY` | Chave SSH privada | `-----BEGIN OPENSSH PRIVATE KEY-----...` | +| `SSH_PORT` | Porta SSH (opcional) | `22` | +| `DEPLOY_PATH` | Caminho no servidor | `/var/www/avanzato` | +| `STAGING_PATH` | Caminho staging (opcional) | `/var/www/avanzato-staging` | + +### Como gerar a chave SSH: + +```bash +# No seu computador (NAO no servidor): +ssh-keygen -t ed25519 -C "github-actions" -f ~/.ssh/github_actions + +# Copiar publica para o servidor: +ssh-copy-id -i ~/.ssh/github_actions.pub root@SEU_SERVIDOR + +# Copiar privada para o GitHub Secret: +cat ~/.ssh/github_actions +# Cole o conteudo inteiro no secret SSH_PRIVATE_KEY +``` + +--- + +## Estrutura de Branches + +``` +main/master --> Deploy automatico para producao +staging --> Deploy automatico para staging (se existir) +feature/* --> Apenas build (sem deploy) +hotfix/* --> Apenas build (sem deploy) +``` + +--- + +## Como Funciona + +### Cenario 1: Deploy Automatico +``` +1. Voce faz push para main +2. GitHub Actions executa automaticamente +3. Build + Deploy em ~2 minutos +4. Site atualizado! +``` + +### Cenario 2: Deploy Manual +``` +1. Va em Actions > Build e Deploy +2. Clique "Run workflow" +3. Escolha: production ou staging +4. Clique "Run" +``` + +### Cenario 3: Pull Request +``` +1. Cria PR para main +2. CI executa build (testa se compila) +3. NAO faz deploy +4. Merge aprovado? Deploy automatico! +``` + +--- + +## Assets Customizados (Logo, Imagens) + +Para preservar assets apos o deploy automatico: + +### 1. Commitar assets no repositorio + +```bash +git add custom-assets/logo/logo.png +git add custom-assets/images/ +git commit -m "Adiciona logo e imagens customizadas" +git push origin main +``` + +### 2. O pipeline faz sozinho + +O workflow executa automaticamente: +```bash +bash scripts/preserve-assets.sh dist/ +``` + +--- + +## Monitore os Deploys + +- **GitHub Actions**: https://github.com/SEU_USUARIO/avanzato-site/actions +- **Status**: Check verde = sucesso, X vermelho = falha +- **Logs**: Clique no workflow para ver detalhes + +--- + +## Troubleshooting + +### Deploy falhou? + +1. **Verifique os secrets**: Settings > Secrets > Actions +2. **Verifique a chave SSH**: `ssh -i ~/.ssh/github_actions root@SEU_SERVIDOR` +3. **Verifique permissoes**: O usuario precisa de acesso de escrita no DEPLOY_PATH +4. **Verifique logs**: Actions > Clique no workflow > Veja o passo que falhou + +### Assets nao preservados? + +1. Verifique se `custom-assets/` esta no repositorio +2. Verifique se os arquivos estao comitados: `git ls-files custom-assets/` +3. Verifique os logs do passo "Preservar assets customizados" + +--- + +*Configurado em: Maio 2026* diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..609e221a --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,162 @@ +# ============================================================================ +# CI/CD Pipeline - Avanzato Tecnologia +# ============================================================================ +# Este workflow automatiza o build e deploy do site. +# +# TRIGGER: Push na branch main ou manual (workflow_dispatch) +# ============================================================================ + +name: Build e Deploy + +on: + # Deploy automatico ao fazer push na main + push: + branches: [ main, master ] + + # Deploy manual pelo botao "Run workflow" no GitHub + workflow_dispatch: + inputs: + environment: + description: 'Ambiente' + required: true + default: 'production' + type: choice + options: + - production + - staging + + # Pull Request (apenas build, sem deploy) + pull_request: + branches: [ main, master ] + +# Permissoes necessarias +permissions: + contents: read + +jobs: + # ========================================================================== + # JOB 1: Build + # ========================================================================== + build: + name: Build + runs-on: ubuntu-latest + + steps: + # Passo 1: Checkout do codigo + - name: Checkout codigo + uses: actions/checkout@v4 + + # Passo 2: Setup Node.js + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + # Passo 3: Instalar dependencias + - name: Instalar dependencias + run: npm ci + + # Passo 4: Build + - name: Build + run: npm run build + + # Passo 5: Upload do artefato (para usar no job de deploy) + - name: Upload artefato + uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ + retention-days: 1 + + # ========================================================================== + # JOB 2: Deploy para Servidor (Producao) + # ========================================================================== + deploy-production: + name: Deploy - Producao + needs: build + runs-on: ubuntu-latest + # So executa na branch main/master ou manual com environment=production + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' || github.event.inputs.environment == 'production' + + steps: + # Passo 1: Download do artefato buildado + - name: Download artefato + uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + + # Passo 2: Preservar assets customizados (logo, imagens) + - name: Preservar assets customizados + run: | + if [ -d "custom-assets" ]; then + echo "Preservando assets customizados..." + bash scripts/preserve-assets.sh dist/ + else + echo "Nenhum asset customizado encontrado." + fi + + # Passo 3: Deploy via SCP (SSH) + - name: Deploy para servidor + uses: appleboy/scp-action@v0.1.7 + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USER }} + key: ${{ secrets.SSH_PRIVATE_KEY }} + port: ${{ secrets.SSH_PORT || '22' }} + source: "dist/*" + target: ${{ secrets.DEPLOY_PATH || '/var/www/avanzato' }} + strip_components: 1 + rm: true # Remove arquivos antigos antes de copiar + + # Passo 4: Notificar (opcional - webhook Discord/Slack) + - name: Notificar sucesso + if: success() + run: | + echo "Deploy para producao concluido com sucesso!" + echo "Site: https://avanzato.com.br" + + # ========================================================================== + # JOB 3: Deploy para Staging (Opcional) + # ========================================================================== + deploy-staging: + name: Deploy - Staging + needs: build + runs-on: ubuntu-latest + # So executa em push para branch staging ou manual + if: github.ref == 'refs/heads/staging' || github.event.inputs.environment == 'staging' + + steps: + - name: Download artefato + uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + + - name: Deploy para staging + uses: appleboy/scp-action@v0.1.7 + with: + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USER }} + key: ${{ secrets.SSH_PRIVATE_KEY }} + port: ${{ secrets.SSH_PORT || '22' }} + source: "dist/*" + target: ${{ secrets.STAGING_PATH || '/var/www/avanzato-staging' }} + strip_components: 1 + rm: true + + # ========================================================================== + # JOB 4: Notificacao de Falha + # ========================================================================== + notify-failure: + name: Notificar Falha + needs: [build, deploy-production] + runs-on: ubuntu-latest + if: failure() + + steps: + - name: Notificar falha + run: | + echo "ALERTA: O deploy falhou!" + echo "Verifique os logs em: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..3aa953db --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +# Build +dist +dist-ssr +*.local + +# Cache +.cache +.vite + +# Dependencias +node_modules + +# Ambiente (NUNCA commite!) +.env +.env.local +.env.*.local + +# Editor +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# OS +.DS_Store +Thumbs.db + +# Scripts de deploy local +scripts/.env.local diff --git a/DEPLOY-DOCKER.md b/DEPLOY-DOCKER.md deleted file mode 100644 index 9e3569d3..00000000 --- a/DEPLOY-DOCKER.md +++ /dev/null @@ -1,96 +0,0 @@ -# Deploy com Docker - Avanzato - -## O Problema - -O Nginx no Docker nao vem configurado para SPA React. Ao acessar `/avaliacao` diretamente, da 404. - -## A Solucao - -### Opcao 1: Configurar Nginx dentro do container (RECOMENDADO) - -**1. Criar um novo Dockerfile:** - -```dockerfile -FROM nginx:alpine - -# Copiar o site -COPY dist/ /usr/share/nginx/html/ - -# Copiar a configuracao customizada -COPY nginx-docker.conf /etc/nginx/conf.d/default.conf - -# Expor porta 80 -EXPOSE 80 - -# Iniciar Nginx -CMD ["nginx", "-g", "daemon off;"] -``` - -**2. Build e run:** - -```bash -# Build -npm run build -bash scripts/build-static-routes.sh dist -docker build -t avanzato-site . - -# Run -docker run -d -p 80:80 --name avanzato avanzato-site -``` - -### Opcao 2: Usar docker-compose - -**docker-compose.yml:** - -```yaml -version: '3.8' -services: - avanzato: - image: nginx:alpine - ports: - - "80:80" - volumes: - - ./dist:/usr/share/nginx/html:ro - - ./nginx-docker.conf:/etc/nginx/conf.d/default.conf:ro - container_name: avanzato-site -``` - -**Comandos:** - -```bash -npm run build -bash scripts/build-static-routes.sh dist -docker-compose up -d -``` - -### Opcao 3: Container ja rodando (hotfix) - -Se o container ja esta rodando: - -```bash -# Copiar config para dentro do container -docker cp nginx-docker.conf avanzato-site:/etc/nginx/conf.d/default.conf - -# Recarregar Nginx -docker exec avanzato-site nginx -s reload -``` - -## Verificar se funcionou - -```bash -# Testar -curl -I http://localhost/avaliacao -# Deve retornar HTTP 200, nao 404 -``` - -## A regra magica - -A unica coisa que importa e esta linha no Nginx: - -```nginx -location / { - try_files $uri $uri/ /index.html; -} -``` - -Isso diz ao Nginx: "se nao encontrar o arquivo, manda para index.html" — onde o React pega a rota. diff --git a/GUIA-NGINX.md b/GUIA-NGINX.md deleted file mode 100644 index 882748a5..00000000 --- a/GUIA-NGINX.md +++ /dev/null @@ -1,116 +0,0 @@ -# Guia Rapido - Configurar Nginx (SPA React) - -## O Problema - -URLs como `avanzato.com.br/avaliacao` dao 404 quando acessadas diretamente. -Funcionam apenas quando clica no menu (navegacao interna do React). - -## A Solucao - -O Nginx precisa redirecionar todas as rotas para `index.html`. - -## Passo a Passo - -### 1. Copiar a config do projeto para o servidor - -No seu Mac, envie o arquivo `nginx.conf` do projeto para o servidor: - -```bash -# Enviar o arquivo nginx.conf do projeto para o servidor -scp /Users/avanzato/Projetos/Avanzato/avanzato-site/app/nginx.conf root@SEU_SERVIDOR:/etc/nginx/sites-available/avanzato -``` - -Ou, se ja estiver logado no servidor: - -```bash -# Logar no servidor -ssh root@SEU_SERVIDOR - -# Criar o arquivo de config -cat > /etc/nginx/sites-available/avanzato << 'EOF' -server { - listen 80; - server_name avanzato.com.br; - - root /var/www/avanzato; - index index.html; - - # ESSA LINHA E A CHAVE - redireciona tudo para index.html - location / { - try_files $uri $uri/ /index.html; - } - - # Cache para assets - location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { - expires 6M; - add_header Cache-Control "public"; - } - - # Seguranca - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-Content-Type-Options "nosniff" always; - - # Bloquear arquivos ocultos - location ~ /\. { - deny all; - } -} -EOF -``` - -### 2. Ativar o site - -```bash -# Criar link simbolico (ativa o site) -ln -s /etc/nginx/sites-available/avanzato /etc/nginx/sites-enabled/avanzato - -# Remover o default (se existir) -rm -f /etc/nginx/sites-enabled/default -``` - -### 3. Testar e aplicar - -```bash -# Testar a configuracao (mostra erros se houver) -nginx -t - -# Se der OK, recarregar o Nginx -systemctl reload nginx -``` - -### 4. Verificar se funcionou - -```bash -# Testar uma rota direta -curl -I https://avanzato.com.br/avaliacao - -# Deve retornar HTTP 200, nao 404 -``` - ---- - -## Comandos Uteis - -| Comando | O que faz | -|---------|-----------| -| `nginx -t` | Testa a configuracao (sem aplicar) | -| `systemctl reload nginx` | Recarrega config sem derrubar o site | -| `systemctl restart nginx` | Reinicia o Nginx | -| `systemctl status nginx` | Verifica se esta rodando | -| `tail -f /var/log/nginx/error.log` | Ver erros em tempo real | - ---- - -## Importante - -Se voce usa **Apache** em vez de Nginx, a config esta no arquivo `.htaccess` que ja vai no `dist/`: - -```apache -RewriteEngine On -RewriteCond %{REQUEST_FILENAME} -f [OR] -RewriteCond %{REQUEST_FILENAME} -d -RewriteRule ^ - [L] -RewriteRule ^ index.html [L] -``` - -Basta garantir que o `.htaccess` esta na raiz do site e o `mod_rewrite` esta ativado. diff --git a/index.html b/index.html index 2346f776..35dc3e83 100644 --- a/index.html +++ b/index.html @@ -49,6 +49,10 @@ fbq('init', '1223271852059785'); fbq('track', 'PageView'); + - - -