name: CI on: pull_request: push: branches: [main] # O release.yml roda esta mesma suíte antes de publicar a imagem. workflow_call: permissions: contents: read concurrency: group: ci-${{ github.ref }} cancel-in-progress: true jobs: verificar: name: Lint, design e build runs-on: ubuntu-latest timeout-minutes: 15 env: # O Puppeteer só é usado em scripts locais (slides, capturas); não precisa do Chrome na CI. PUPPETEER_SKIP_DOWNLOAD: "true" NEXT_TELEMETRY_DISABLED: "1" steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 cache: npm # Next.js guarda aqui o resultado da compilação anterior; sem isso, cada # execução recompila todas as páginas do zero. - name: Cache de build do Next uses: actions/cache@v4 with: path: .next/cache key: next-${{ runner.arch }}-${{ hashFiles('package-lock.json') }}-${{ hashFiles('app/**', 'components/**', 'lib/**') }} restore-keys: | next-${{ runner.arch }}-${{ hashFiles('package-lock.json') }}- next-${{ runner.arch }}- - run: npm ci # eslint + auditoria do design system (tokens, contraste AAA) + auditoria de páginas - run: npm run check - run: npm run build # Trivy roda pela imagem oficial: o trivy-action clona o repositório do Trivy # do mesmo servidor do workflow, que aqui é o Gitea, e não o GitHub. # O workspace do job é um volume que o daemon não enxerga, então os arquivos # entram no container com `docker cp` em vez de `-v`. seguranca: name: Trivy (dependências e segredos) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Repositório run: | cid=$(docker create --network host -v trivy-cache:/root/.cache/ -w /src aquasec/trivy:0.70.0 \ fs --scanners vuln,secret,misconfig --severity HIGH,CRITICAL --exit-code 1 .) docker cp . "$cid:/src" docker start -a "$cid" status=$(docker inspect -f '{{.State.ExitCode}}' "$cid") docker rm "$cid" >/dev/null exit "$status" imagem: name: Imagem Docker runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # `docker build` simples: o cache de camadas fica no volume persistente do # daemon do runner, e o buildx criaria um BuildKit novo a cada job. - name: Build run: docker build -t espdocs:ci . - name: Trivy na imagem run: | docker run --rm --network host -v trivy-cache:/root/.cache/ -e DOCKER_HOST=tcp://127.0.0.1:2375 aquasec/trivy:0.70.0 \ image --severity HIGH,CRITICAL --exit-code 1 espdocs:ci - name: A imagem sobe e responde run: | docker run -d --name espdocs-ci --network host -e PORT=3999 espdocs:ci for i in $(seq 1 30); do curl -fsS http://127.0.0.1:3999/ >/dev/null && ok=1 && break sleep 2 done docker logs espdocs-ci | tail -5 docker rm -f espdocs-ci >/dev/null test "${ok:-0}" = 1