mirror of
https://github.com/melgarafael/DeskcommCRM.git
synced 2026-10-02 01:28:34 +08:00
docs(ci): onde os jobs rodam, e o e2e verde que não prova tela
- CLAUDE.md/AGENTS.md: o `e2e` roda em todo PR que ALCANÇA o que ele mede; em PR só de documentação/teste de outra suíte as partes pulam e o verde não prova tela. Novo parágrafo "Onde os jobs rodam": Pro (40 simultâneos, 39 medidos em 18/09), executor próprio atrás de EXECUTOR_PROPRIO, a guarda contra fork mora na máquina, a publicação nunca vai para ela, e a merge queue do GitHub não está disponível (422 medido, controle aceito). - infra/executor-proprio/README.md. - Testes de desfechos herdam process.env (ProcessEnv exige NODE_ENV), como o conserto do #1190; a guarda sobrescreve as três GITHUB_* que lê. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H4wfiPiZoHuH22wXn4spAj
This commit is contained in:
@@ -350,7 +350,9 @@ cabeçalho passava a mentir por todos eles.
|
||||
- Arquivos de invariante de banco em `tests/invariants/` — RLS/isolamento cross-tenant, RBAC,
|
||||
governança (G1–G6). Excluídos do `test:unit` de propósito; rodam via `pnpm test:db` **e no job
|
||||
`invariants` do CI**. Quantos: `git ls-files 'tests/invariants/*.test.ts' | wc -l`.
|
||||
- Specs Playwright em `tests/e2e/`, quase todas no CI (via `e2e.yml`, **obrigatório**). As que
|
||||
- Specs Playwright em `tests/e2e/`, quase todas no CI (via `e2e.yml`, **obrigatório**), em todo PR que
|
||||
alcança o que elas medem — PR só de documentação/teste de outra suíte pula as partes
|
||||
(`scripts/pr-alcanca-o-e2e.sh`), e ali o `e2e` verde não prova tela. As que
|
||||
ficam de fora estão declaradas em `FORA_DO_CI`, **com o motivo escrito ao lado**. Esta linha
|
||||
já afirmou "menos uma" depois de deixarem de ser uma — por isso não conta mais. A issue #63,
|
||||
que originou a discussão, está **fechada** e o título dela descreve um estado que já não vale.
|
||||
|
||||
@@ -428,7 +428,7 @@ Checks **obrigatórios** na branch protection da `main` (verificado na configura
|
||||
- **`verify`** (`ci.yml`) — typecheck + lint + test:unit.
|
||||
- **`invariants`** (`ci.yml`) — **job de fachada**: ele não roda suíte nenhuma; reprova quando a matriz `invariants-majors` não fecha em `success`. Quem roda é a matriz, uma perna por major do Postgres que o produto diz suportar, e cada perna faz duas passadas: `pnpm test:db` (baseline em modo install com `ON_ERROR_STOP=1` e update, mais os invariantes, incluindo o isolamento RLS entre 2 organizações) e `pnpm test:db:update` (atualização de um banco COM dados). Para saber quais majors hoje, pergunte ao arquivo em vez de a esta linha: `awk '/^ invariants-majors:/,/^ [a-z-]+:/' .github/workflows/ci.yml | grep -A6 'matrix:'`.
|
||||
- **`build-and-size`** (`perf.yml`) — `pnpm build` em Node 22.
|
||||
- **`e2e`** (`e2e.yml`) — sobe Supabase local, aplica o `baseline.sql` e roda **todas as specs Playwright menos as que `FORA_DO_CI` declara**. O número saiu daqui de propósito: ele apodreceu **cinco** vezes (a quinta em 2026-08-24, quando `inbox-quem-manda.spec.ts` entrou), e a condição que o PR #242 pôs para parar de recontar já tinha vencido na quarta. Quem precisa do número roda o comando abaixo — comando não envelhece. Quais ficam de fora, e por quê, é o que a própria variável diz — **não confie nesta linha, leia-a**:
|
||||
- **`e2e`** (`e2e.yml`) — sobe Supabase local, aplica o `baseline.sql` e roda **todas as specs Playwright menos as que `FORA_DO_CI` declara** — **em PR que alcança algo que ele mede**. PR só de documentação, teste de outra suíte, fragmento ou workflow alheio pula as partes (regra em `scripts/pr-alcanca-o-e2e.sh`, na dúvida roda), e ali o `e2e` verde **não prova tela nenhuma**. O número saiu daqui de propósito: ele apodreceu **cinco** vezes (a quinta em 2026-08-24, quando `inbox-quem-manda.spec.ts` entrou), e a condição que o PR #242 pôs para parar de recontar já tinha vencido na quarta. Quem precisa do número roda o comando abaixo — comando não envelhece. Quais ficam de fora, e por quê, é o que a própria variável diz — **não confie nesta linha, leia-a**:
|
||||
|
||||
```bash
|
||||
git show origin/main:.github/workflows/e2e.yml | \
|
||||
@@ -465,6 +465,25 @@ seguiu dizendo "quatro". Uma triagem que leia qualquer uma dessas versões mede
|
||||
que é o modo de falha nº 1 do procedimento de triagem. **Reconfira na fonte antes de confiar em
|
||||
qualquer lista aqui**, com o comando acima.
|
||||
|
||||
**Onde os jobs rodam.** A conta tem o plano Pro: até **40** jobs simultâneos nas máquinas do GitHub
|
||||
(medidos 39 em 18/09/2026, com 180 na fila). Os jobs pesados do trabalho **nosso** (push na `main`
|
||||
e PR de branch deste repositório) podem ir para o **executor próprio** (`infra/executor-proprio/`)
|
||||
quando a variável de repositório `EXECUTOR_PROPRIO` vale `ligado`; PR de fork roda sempre no GitHub,
|
||||
e a publicação da `main` também. Duas regras que não se negociam:
|
||||
|
||||
- **A guarda contra fork mora na máquina, não no YAML.** Em PR de fork o GitHub roda o workflow do
|
||||
fork, que pode reescrever `runs-on:`. Quem recusa é `infra/executor-proprio/so-o-que-e-nosso.sh`,
|
||||
gravado na imagem como hook de entrada do runner. Mudar a expressão de `runs-on` não é mudar a
|
||||
segurança — e afrouxar a guarda é.
|
||||
- **Imagem que o parque instala nunca se constrói na máquina nossa.** `build-and-push` e
|
||||
`promover-stable` ficam em `ubuntu-latest`; os jobs `*-sobe` só vão para a máquina em PR.
|
||||
|
||||
Vigiado por `tests/unit/executor-proprio-so-roda-o-que-e-nosso.test.ts`. Botão de emergência:
|
||||
apagar a variável `EXECUTOR_PROPRIO` — os jobs novos voltam na hora para o GitHub. **A fila de merge
|
||||
(merge queue) do GitHub não está disponível** neste repositório (conta pessoal; medido em 18/09/2026:
|
||||
a regra é recusada com 422 e uma regra comum no mesmo formato é aceita) — a integração em lote da
|
||||
triagem (`triagem/TRIAGEM.md` §3-quinquies) é o que cumpre esse papel.
|
||||
|
||||
Ao mexer em schema, RLS, RBAC, atribuição, escopo, roteamento, follow-up, webhooks ou automações: rode `pnpm test:db` **localmente** antes de abrir PR. É o único caminho que exercita o `baseline.sql` que o self-hoster realmente aplica.
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# Executor próprio do CI
|
||||
|
||||
Uma máquina nossa que roda os jobs pesados do trabalho **nosso** — push na `main` e PR de
|
||||
branch deste repositório — para a fila do GitHub ficar para quem contribui de fora.
|
||||
|
||||
Não muda nada até a variável de repositório `EXECUTOR_PROPRIO` valer `ligado`
|
||||
(Settings → Secrets and variables → Actions → Variables). Apagar a variável é o botão de
|
||||
emergência: os jobs novos voltam na hora para as máquinas do GitHub.
|
||||
|
||||
## Peças
|
||||
|
||||
| arquivo | o que é |
|
||||
|---|---|
|
||||
| `instalar.sh` | instala Docker + Sysbox numa Ubuntu 24.04 amd64 dedicada, pede o token, liga as vagas e a atualização semanal |
|
||||
| `vaga.sh` | uma vaga: pede ao GitHub um runner JIT (um job, uso único), roda um contêiner limpo com ele, repete |
|
||||
| `Dockerfile` | a imagem da vaga — o que os jobs pressupõem do `ubuntu-latest` |
|
||||
| `entrypoint.sh` | sobe o Docker de dentro da vaga e entrega ao runner |
|
||||
| `so-o-que-e-nosso.sh` | a guarda de entrada: recusa todo job que não seja nosso, antes do primeiro passo |
|
||||
|
||||
## Por que a guarda mora aqui
|
||||
|
||||
O repositório é público, e num `pull_request` de fork o GitHub roda o workflow **do fork** — que
|
||||
pode reescrever `runs-on:` para mirar esta máquina. A expressão de `runs-on` dos nossos workflows
|
||||
só decide para quem não a edita. A guarda é gravada na imagem e registrada como
|
||||
`ACTIONS_RUNNER_HOOK_JOB_STARTED`; script de entrada que falha faz o job não rodar.
|
||||
|
||||
Aceita: `push`, `workflow_dispatch`, `schedule`, `merge_group`, e `pull_request` cuja branch mora
|
||||
neste repositório. Recusa o resto, inclusive `pull_request_target` e payload ilegível.
|
||||
|
||||
## Por que uma vaga por contêiner (Sysbox)
|
||||
|
||||
O `e2e` sobe o Supabase em portas fixas (54321/54322) e o teste de imagem usa `:3000` e nomes fixos
|
||||
de contêiner: dois jobs no mesmo Docker colidem. Cada vaga tem o próprio Docker e a própria rede,
|
||||
sem `--privileged`, e o contêiner é descartado ao fim do job.
|
||||
|
||||
## Tamanho
|
||||
|
||||
Uma vaga = 4 núcleos e 14 GB, como o `ubuntu-latest`. Medido em 15–18/09/2026: o trabalho nosso
|
||||
ocupava ~5 jobs em média e mais de 10 em 17% do tempo (sob o teto de 20 da época, então a demanda
|
||||
real é maior). 8 vagas cobrem os picos.
|
||||
|
||||
## Operação
|
||||
|
||||
```bash
|
||||
journalctl -u deskcomm-vaga@1 -f # log de uma vaga
|
||||
sudo bash /opt/deskcomm-executor/instalar.sh atualizar # reconstrói a imagem agora
|
||||
systemctl list-timers deskcomm-executor-atualizar.timer # próxima atualização automática
|
||||
```
|
||||
|
||||
Vigiado por `tests/unit/executor-proprio-so-roda-o-que-e-nosso.test.ts`.
|
||||
@@ -50,7 +50,7 @@ for EVENTO in pull_request push; do
|
||||
done
|
||||
true`;
|
||||
return execFileSync("bash", ["-c", programa], {
|
||||
env: { PATH: process.env.PATH ?? "", SCRIPT_DO_JOB: SCRIPT, GITHUB_STEP_SUMMARY: "/dev/null" },
|
||||
env: { ...process.env, SCRIPT_DO_JOB: SCRIPT, GITHUB_STEP_SUMMARY: "/dev/null" },
|
||||
encoding: "utf-8",
|
||||
})
|
||||
.split("\n")
|
||||
|
||||
@@ -27,7 +27,9 @@ function guarda(evento: string, payload: unknown, repo = REPO): number {
|
||||
writeFileSync(caminho, typeof payload === "string" ? payload : JSON.stringify(payload));
|
||||
try {
|
||||
execFileSync("bash", [GUARDA], {
|
||||
env: { PATH: process.env.PATH ?? "", GITHUB_REPOSITORY: repo, GITHUB_EVENT_NAME: evento, GITHUB_EVENT_PATH: caminho },
|
||||
// Herda o ambiente (ProcessEnv exige NODE_ENV) e SOBRESCREVE as três que a
|
||||
// guarda lê — no CI elas existem e descreveriam o job de verdade.
|
||||
env: { ...process.env, GITHUB_REPOSITORY: repo, GITHUB_EVENT_NAME: evento, GITHUB_EVENT_PATH: caminho },
|
||||
stdio: "pipe",
|
||||
});
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user