CI / Lint e auditorias (push) Successful in 45s
CI / Trivy (dependências e segredos) (push) Successful in 8s
CI / Imagem Docker (linux/arm64) (push) Successful in 4m11s
Release / Plano (reaproveitar a imagem?) (push) Successful in 5s
Release / ci (push) Skipped
Release / Publica a imagem (linux/arm64) (push) Successful in 2m40s
Release / Cria a release no Gitea (push) Skipped
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
121 lines
4.6 KiB
YAML
121 lines
4.6 KiB
YAML
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
|
|
|
|
- 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
|
|
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
|
|
|
|
# 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"
|