Files
ESPDocs/.gitea/workflows/ci.yml
T
Lucas RayanandClaude Sonnet 5.5 3a1a095e97
CI / Lint e auditorias (push) Successful in 42s
CI / Trivy (dependências e segredos) (push) Successful in 8s
CI / Imagem Docker (linux/arm64) (push) Successful in 2m11s
ci: a real smoke test for the localized routes, and a single redirect from the root
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 10:33:40 -03:00

124 lines
4.9 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: CI
# Documentação e configuração de ferramenta não mudam nada que a suíte teste.
# Na main não roda por push: o release.yml é quem a chama, e só quando a imagem
# precisa ser reconstruída; rodar nos dois repetiria a mesma suíte no mesmo commit.
# Sem gatilho de pull_request: o push da branch já valida o mesmo commit, e os
# dois juntos rodariam tudo duas vezes (o repositório não recebe PR de fork).
#
# A imagem é construída aqui uma única vez, em arm64 (a arquitetura do servidor),
# testada e publicada como inputs-<hash>. Ao fazer o merge, o release encontra
# essa tag e só aplica os nomes novos, sem rodar nem construir nada de novo.
on:
push:
branches-ignore: [main]
paths-ignore: ['**.md', 'LICENSE', '.claude/**', '.superset/**', '.wolf/**', 'scripts/release-notes.sh']
workflow_call:
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
verificar:
name: Lint e auditorias
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
- run: npm ci
# eslint + auditoria do design system (tokens, contraste AAA) + auditoria de páginas
- run: npm run check
# 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"
# Só começa depois das verificações baratas: um lint quebrado não gasta um
# build de imagem. Roda no runner arm64, o mesmo tipo do servidor, então o
# que é escaneado e testado é a imagem que vai ao ar.
imagem:
name: Imagem Docker (linux/arm64)
needs: [verificar, seguranca]
runs-on: ubuntu-24.04-arm
env:
REGISTRY: git.lucasrguerra.dev.br
steps:
- uses: actions/checkout@v4
# Conteúdo já publicado (re-push, tag num commit já validado): nada a fazer.
- id: plano
run: scripts/plano-imagem.sh "$REGISTRY" "${{ gitea.repository }}" >> "$GITHUB_OUTPUT"
- if: ${{ steps.plano.outputs.reuse != 'true' }}
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ gitea.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
# `docker build` simples, no daemon persistente do runner: as camadas e os
# cache mounts do Dockerfile (npm e compilação do Next) sobrevivem entre
# execuções. Um buildx criaria um BuildKit novo, e vazio, a cada job.
- name: Build
if: ${{ steps.plano.outputs.reuse != 'true' }}
run: docker build -t espdocs:ci .
- name: Trivy na imagem
if: ${{ steps.plano.outputs.reuse != 'true' }}
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
# Rotas por idioma, redirects e regras do livro (scripts/smoke-imagem.sh).
# Um curl só na raiz não basta: ela redireciona, e uma página interna
# quebrada ainda passaria.
- name: A imagem sobe e responde
if: ${{ steps.plano.outputs.reuse != 'true' }}
run: |
docker run -d --name espdocs-ci --network host -e PORT=3999 espdocs:ci
status=0
scripts/smoke-imagem.sh http://127.0.0.1:3999 || status=1
docker logs espdocs-ci | tail -15
# O Next registra falhas de render no log mesmo quando responde.
if docker logs espdocs-ci 2>&1 | grep -q '⨯'; then echo "O servidor registrou erro de render"; status=1; fi
docker rm -f espdocs-ci >/dev/null
exit "$status"
# Passou em tudo: publica a mesma imagem que foi testada, sem reconstruir.
- name: Publica inputs-<hash>
if: ${{ steps.plano.outputs.reuse != 'true' }}
run: |
tag="${{ steps.plano.outputs.image }}:inputs-${{ steps.plano.outputs.inputs }}"
docker tag espdocs:ci "$tag"
docker push "$tag"