Files
adaptador-planilhas/docs/spreadsheet-adapter/22-gitea-actions.md
T
camilafagundesandClaude Opus 5 b8586ba0aa
ci / lint, typecheck, testes e build (push) Has been cancelled
ci / Postgres e Redis reais (push) Has been cancelled
ci / imagem Docker Linux (push) Has been cancelled
Registra os três runs em espera e que concurrency não funciona no Gitea
Depois do push, o Gitea criou `ci.yml #3` e `runner-check.yml #4`, ambos em
Waiting com a mesma mensagem de runner ausente. Com o `ci.yml #2` anterior, são
três runs enfileirados esperando o runner — nenhum precisa ser republicado.

Duas correções de expectativa que valem registro:

O `concurrency` que eu declarei para evitar fila não tem efeito nesta versão: o
run 667 deveria ter cancelado o 666, do mesmo grupo, e não cancelou. A fila vai
crescer a cada push até existir runner. Fica documentado para ninguém contar
com um cancelamento que não acontece.

A barra lateral de Workflows mostra apenas `ci.yml` porque lista o que existe
na branch padrão, onde `runner-check.yml` ainda não está. Isso não impediu o
run de ser criado a partir de `homologacao`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-15 21:18:23 -03:00

9.4 KiB

Gitea Actions — diagnóstico e ativação do runner

Repositório cferraz/adaptador-planilhas em gitea.fatorxtech.com, Gitea 1.26.2.

Causa confirmada da ausência de execuções

Os runs existem. O que não existe é runner para executá-los. A falha está na atribuição, não no enfileiramento.

Evidência Resultado
ci.yml detectado por Gitea sim, listado em Workflows
Gatilho de ci.yml on: push sem filtro de branch — contempla homologacao
Actions no repositório habilitado (has_actions: true)
Actions na instância habilitado (a página /actions responde e lista workflows)
Runs criados pelos pushes sim, três
Estado de todos Waiting, duração 0s
Mensagem do Gitea em cada um No matching online runner with label: ubuntu-latest
Run Workflow Commit Branch Estado
668 runner-check.yml #4 c5790ab301 homologacao Waiting
667 ci.yml #3 c5790ab301 homologacao Waiting
666 ci.yml #2 5b11496cd9 homologacao Waiting
584 ci.yml #1 419325db12 main Canceled

Listagem: https://gitea.fatorxtech.com/cferraz/adaptador-planilhas/actions

Dois detalhes observados na prática:

  • a barra lateral de Workflows mostra só ci.yml, porque lista os workflows da branch padrão (main), onde runner-check.yml ainda não existe. Isso não impediu o run 668 de ser criado a partir de homologacao;
  • concurrency não tem efeito no Gitea 1.26.2. O run 667 deveria ter cancelado o 666, que está no mesmo grupo, e não cancelou. A fila de runs em Waiting vai crescer a cada push enquanto não houver runner. Não é problema: quando o runner subir, cancele os antigos pela interface ou deixe-os rodar em sequência.

Por que a API parecia dizer "zero execuções"

GET /api/v1/repos/cferraz/adaptador-planilhas/actions/tasks devolve {"workflow_runs":[],"total_count":0}. Esse endpoint lista tasks, isto é, jobs que um runner aceitou. Nenhum runner aceitou nada, então a lista é vazia — mas os runs estão criados e esperando. GET /actions/runs responde token is required, e foi por isso que a primeira leitura passou a impressão errada.

Consequência prática: nada precisa ser republicado. O run 666 está em Waiting e começa sozinho no momento em que um runner com a label compatível ficar online.

Runners encontrados e labels

Runners com label ubuntu-latest online nenhum (é o que o Gitea reporta)
Outros runners na instância não determinado

Listar runners exige token de owner ou admin: GET /api/v1/repos/{owner}/{repo}/actions/runners, ou a interface em Settings → Actions → Runners (nível repositório, organização ou admin). Os números de run (584, 666) sugerem que a instância já teve atividade de Actions em outros repositórios, então é possível que existam runners com outra label. Confira antes de instalar um novo:

  • se já houver runner Linux com Docker e outra label (linux_amd64, ubuntu-22.04, docker), não instale nada: basta ajustar o runs-on dos workflows. Diga qual é a label e a troca é de uma linha em três arquivos;
  • se não houver, siga a instalação abaixo.

Configuração recomendada do runner

Máquina Linux dedicada a homologação, sem nenhuma relação com o Docker de produção do Elo Pro.

Por que Docker-in-Docker, e não o socket do host

O repositório é público. Montar /var/run/docker.sock do host dá ao workflow controle do Docker da máquina — e, num repositório público, código de terceiro poderia chegar lá por pull request de fork. A imagem -dind-rootless sobe um Docker próprio dentro do contêiner do runner: o job image constrói e executa contêineres sem alcançar o Docker do host.

Instalação

Versão fixada, compatível com o Gitea 1.26.2 (0.6.1 é a mais recente publicada; as alternativas semver são 0.1.4 a 0.6.1):

# 1. Token de registro: Settings → Actions → Runners → Create new runner,
#    no NÍVEL DO REPOSITÓRIO (escopo restrito, não use token de admin).
#    Grave o token num arquivo com permissão 600 — nunca em commit, nunca em log.
umask 077
printf '%s' 'COLE_O_TOKEN_AQUI' > /etc/gitea-runner.token

# 2. Suba o runner com Docker-in-Docker rootless.
docker run -d \
  --name gitea-runner-hml \
  --restart always \
  --privileged \
  -e GITEA_INSTANCE_URL=https://gitea.fatorxtech.com \
  -e GITEA_RUNNER_REGISTRATION_TOKEN_FILE=/run/secrets/token \
  -e GITEA_RUNNER_NAME=hml-adaptador \
  -e GITEA_RUNNER_LABELS='ubuntu-latest:docker://node:24-bookworm' \
  -v /etc/gitea-runner.token:/run/secrets/token:ro \
  -v gitea-runner-hml-data:/data \
  docker.io/gitea/act_runner:0.6.1-dind-rootless

Notas que importam:

  • GITEA_RUNNER_REGISTRATION_TOKEN_FILE em vez da variável com o valor: o token não aparece em docker inspect nem no histórico do shell.
  • --privileged é exigência do Docker-in-Docker. É justamente por isso que a máquina precisa ser dedicada.
  • A label tem de ser ubuntu-latest, que é o runs-on dos três jobs. O mapeamento docker://node:24-bookworm já entrega node e npm na versão certa.
  • psql e python3 não vêm nessa imagem. O job services usa psql e a jornada assíncrona usa python3. Duas saídas: trocar o mapeamento para uma imagem que os tenha, ou deixar que o runner-check reporte a ausência e então instalá-los num passo do workflow. Rode o runner-check primeiro: ele faz esse inventário.
  • Rede de saída necessária: gitea.fatorxtech.com (fila e logs), github.com (o Gitea resolve actions/checkout@v4, actions/setup-node@v4 e docker/* via proxy), registry.npmjs.org e docker.io.

Conferir que subiu

docker logs -f gitea-runner-hml        # espere "runner registered successfully"

Depois, em Settings → Actions → Runners, o runner aparece online com a label ubuntu-latest. O run 666, que está em Waiting, começa sozinho.

Ordem de validação

Nenhum destes foi executado ainda. Não marque nada como aprovado sem o log.

  1. runner-check — dispare manualmente. Não faz checkout, não instala nada, não usa segredo. Confirma a ligação e inventaria node, npm, docker, psql, python3.
  2. verify — lint, typecheck, 102 testes, build.
  3. services — Postgres e Redis efêmeros: as quatro migrations, idempotência, --dry-run sem efeito, shim recusado com ADAPTER_APPLY_IDENTITY_SHIM=0, app_user sem BYPASSRLS, FORCE RLS, isolamento entre workspaces, auditoria não alterável.
  4. image — build Linux, conteúdo da imagem, usuário não-root, ausência de .env/docs/testes, os oito scripts operacionais transformando e executando, fail-fast com código diferente de zero na web e no worker, liveness com cabeçalhos, compose até ready, heartbeat do worker, jornada assíncrona entre processos e desligamento gracioso exigindo SIGTERM recebido em menos de 25 s.

Segurança revisada

Risco Estado
Repositório público com Actions ci.yml, runner-check e os três jobs têm guarda: PR de fork não executa (head.repo.full_name == github.repository). Push continua rodando
Código não confiável com acesso privilegiado O runner usa Docker-in-Docker rootless, sem o socket do host. A máquina é dedicada e não alcança o Docker de produção
Deploy automático deploy-staging.yml tem gatilho único workflow_dispatch. Nenhum push, tag ou merge dispara deploy
Aprovação manual de deploy Os ambientes hml-migracao, hml-deploy e hml-flag são conceito do GitHub. O Gitea não os implementa da mesma forma: se o deploy for rodar aqui, as aprovações deixam de existir e isso precisa ser resolvido antes de apontar o workflow ao servidor
Permissão do token de Actions permissions: contents: read nos dois workflows
Fila de runs esperando runner concurrency por ref declarado, sem efeito no Gitea 1.26.2 (verificado: o run 667 não cancelou o 666). Cancele os antigos pela interface quando o runner subir
SSH de produção não configurado. Nenhum segredo de produção foi adicionado
Branch main preservada em 419325d
Token de registro do runner por arquivo com permissão 600, fora de commit e de log

Vale decidir também se este repositório deve seguir público. Auditei os commits e não há segredo algum — só modelos com campos vazios — mas um repositório privado remove de uma vez o risco de PR de fork.

Pendências

Para o CI rodar: um runner Linux online com a label ubuntu-latest, Docker-in-Docker e saída de rede. Nada além disso.

Para homologação, depois do CI verde: projeto Supabase de homologação com contas de teste e bucket privado; DATABASE_URL e a decisão do ADAPTER_APPLY_IDENTITY_SHIM; Redis com senha; DSN do Sentry; DNS, TLS e Nginx de hml-ada.elopro.app; smoke real e ensaio de rollback. O procedimento está em 20-homologacao-runbook.md e o estado item a item em 21-checklist-validacao.md.