name: "DevSecOps Enterprise Pipeline - Next.js" on: push: branches: [ main ] jobs: security-gate-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v3 with: fetch-depth: 0 # ========================================== # STAGE 1: STATIC SECURITY TESTING (SAST, SCA) # ========================================== - name: Gitleaks Scan (Secret Scanning) run: | curl -sL https://github.com/gitleaks/gitleaks/releases/download/v8.18.2/gitleaks_8.18.2_linux_x64.tar.gz | tar -xz -C /tmp /tmp/gitleaks protect --source . --verbose --redact --staged --exit-code 1 || true - name: Install pnpm & Dependencies run: | npm install -g pnpm pnpm install --frozen-lockfile - name: Software Composition Analysis (pnpm audit) run: pnpm audit --audit-level=high || true - name: Scan Infrastructure Vulnerabilities (Trivy FS) run: | curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin # Faz scan ao Dockerfile e package.json local em vez do nginx trivy fs --severity HIGH,CRITICAL . || true - name: SonarQube Analysis (SAST) run: | curl -sL https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip -o sonar-scanner.zip unzip -q sonar-scanner.zip ./sonar-scanner-5.0.1.3006-linux/bin/sonar-scanner \ -Dsonar.projectKey=WebSite-secure \ -Dsonar.sources=. \ -Dsonar.host.url=https://sonar.each-cs.com \ -Dsonar.token=${{ secrets.SONAR_TOKEN }} \ -Dsonar.qualitygate.wait=true # ========================================== # STAGE 2: PRODUCTION DEPLOYMENT # ========================================== - name: Deploy Next.js App (Docker Compose) run: | # O Docker Compose trata de parar a versão antiga, fazer build da nova e levantar docker compose up -d --build # Aguarda que a aplicação inicie completamente sleep 10 # ========================================== # STAGE 3: DYNAMIC APPLICATION SECURITY TESTING (DAST) # ========================================== - name: OWASP ZAP Baseline Scan run: | mkdir -p qatests docker rm -f zap-scanner || true docker volume rm zap-reports || true docker volume create zap-reports # Corre o ZAP contra o host local (assumindo que a app Next.js expôs a porta 80 ou 3000) # Nota: Substituir 'localhost:3000' pela porta real que está no docker-compose.yml docker run --user root --name zap-scanner \ --network host \ -v zap-reports:/zap/wrk/:rw \ -t ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \ -t http://localhost:3000 \ -r report.html \ -I || true docker cp zap-scanner:/zap/wrk/report.html qatests/report.html docker rm -f zap-scanner || true docker volume rm zap-reports || true # ========================================== # STAGE 4: ARTIFACT MANAGEMENT & REPORTING # ========================================== - name: Archive ZAP Report (Raw HTML) if: always() uses: actions/upload-artifact@v3 with: name: owasp-zap-report path: qatests/report.html - name: Pipeline Status Notification if: always() run: | echo "Pipeline finished with status: ${{ job.status }}"