ci: imagem construída do código, esteira para os runners do Gitea e changelog
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
47586bcc7b
commit
ab7f532456
18 files changed
+520
-45
No files matched your search
@@ -0,0 +1,118 @@
|
||||
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', 'CITATION.cff', 'paper.md', 'references.bib', 'docs/**', '.claude/**', '.wolf/**', '.superset/**', 'scripts/release-notes.sh']
|
||||
schedule:
|
||||
- cron: '0 9 * * 1' # toda segunda: reavalia com a base de vulnerabilidades nova
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ gitea.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
verificar:
|
||||
name: Tipos e testes
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
|
||||
- run: npm ci
|
||||
|
||||
# tsc -b é o mesmo que o build faz antes do Vite; aqui falha antes de gastar a imagem.
|
||||
- run: npx tsc -b
|
||||
- run: npm test
|
||||
|
||||
# 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 teste 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 o
|
||||
# cache mount do npm 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 pss: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 pss:ci
|
||||
|
||||
# A SPA sobe, cai no index nas rotas internas e entrega os assets com
|
||||
# cache imutável (scripts/smoke-imagem.sh).
|
||||
- name: A imagem sobe e responde
|
||||
if: ${{ steps.plano.outputs.reuse != 'true' }}
|
||||
run: |
|
||||
docker run -d --name pss-ci -p 127.0.0.1:3998:80 pss:ci
|
||||
status=0
|
||||
scripts/smoke-imagem.sh http://127.0.0.1:3998 || status=1
|
||||
docker rm -f pss-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 pss:ci "$tag"
|
||||
docker push "$tag"
|
||||
Reference in new issue
Block a user