fix(cloud): ensure-postgres bootstrap before teqo readiness check
Warm Cloud snapshots often have PostgreSQL online without the teqo role/DBs. start_postgres previously gated on teqo_ready, exited before bootstrap_databases, and marked the environment INSTALL_FAILED even though agents still ran. Also pin DATABASE_URL and assert migrations in cloud-setup so a silent no-op migrate cannot slip through. Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
This commit is contained in:
parent
7a876ec334
commit
503a775b9f
3 changed files with 66 additions and 15 deletions
|
|
@ -20,16 +20,35 @@ if [ ! -f .env ]; then
|
|||
echo "[cloud-setup] wrote .env from .env.example (local-only values)"
|
||||
fi
|
||||
|
||||
TEQO_URL='postgresql://teqo:teqo@localhost:5432/teqo'
|
||||
TEQO_TEST_URL='postgresql://teqo:teqo@localhost:5432/teqo_test'
|
||||
|
||||
assert_migrated() {
|
||||
local db_url="$1"
|
||||
local label="$2"
|
||||
local count
|
||||
count="$(PGPASSWORD=teqo psql "${db_url}" -Atc 'SELECT COUNT(*) FROM payload_migrations' 2>/dev/null || echo 0)"
|
||||
if [ "${count}" -lt 1 ]; then
|
||||
echo "[cloud-setup] ERROR: ${label} has no payload_migrations after migrate (got '${count}')" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "[cloud-setup] ${label}: ${count} migrations applied"
|
||||
}
|
||||
|
||||
# Dev database (teqo) and test database (teqo_test).
|
||||
# Pin DATABASE_URL on both — do not rely on dotenv alone (JIT snapshots have
|
||||
# seen a silent no-op migrate when the URL was only in a freshly written .env).
|
||||
echo "[cloud-setup] migrating teqo..."
|
||||
pnpm migrate
|
||||
DATABASE_URL="${TEQO_URL}" pnpm migrate
|
||||
assert_migrated "${TEQO_URL}" teqo
|
||||
echo "[cloud-setup] migrating teqo_test..."
|
||||
DATABASE_URL=postgresql://teqo:teqo@localhost:5432/teqo_test pnpm migrate
|
||||
DATABASE_URL="${TEQO_TEST_URL}" pnpm migrate
|
||||
assert_migrated "${TEQO_TEST_URL}" teqo_test
|
||||
|
||||
echo "[cloud-setup] seeding teqo..."
|
||||
pnpm db:seed:minimal
|
||||
DATABASE_URL="${TEQO_URL}" pnpm db:seed:minimal
|
||||
echo "[cloud-setup] seeding teqo_test..."
|
||||
DATABASE_URL=postgresql://teqo:teqo@localhost:5432/teqo_test pnpm db:seed:minimal
|
||||
DATABASE_URL="${TEQO_TEST_URL}" pnpm db:seed:minimal
|
||||
|
||||
echo "[cloud-setup] OK — minimal database ready (dev + test)."
|
||||
echo "[cloud-setup] gate:fast/gate:push need no DB; use pnpm push (not raw git push --no-verify)."
|
||||
|
|
|
|||
|
|
@ -1,15 +1,27 @@
|
|||
#!/usr/bin/env bash
|
||||
# Cursor Cloud VMs have no Docker and cannot run docker compose (overlayfs fails inside
|
||||
# the agent container). Native PostgreSQL matches the local DATABASE_URL contract.
|
||||
#
|
||||
# Important: "server accepting connections" ≠ "teqo role/DBs exist". A warm snapshot
|
||||
# often has the cluster online with no app databases yet. Never gate cluster start on
|
||||
# teqo readiness — bootstrap runs after the server is up.
|
||||
set -euo pipefail
|
||||
|
||||
PG_VERSION="${PG_VERSION:-16}"
|
||||
PG_CLUSTER="${PG_CLUSTER:-main}"
|
||||
# pg_ctlcluster / systemctl can report "started" before the postmaster accepts TCP.
|
||||
READY_ATTEMPTS="${PG_READY_ATTEMPTS:-15}"
|
||||
READY_SLEEP_SECS="${PG_READY_SLEEP_SECS:-1}"
|
||||
|
||||
pg_ready() {
|
||||
teqo_ready() {
|
||||
PGPASSWORD=teqo psql -h localhost -U teqo -d teqo -c 'SELECT 1' >/dev/null 2>&1
|
||||
}
|
||||
|
||||
server_ready() {
|
||||
pg_isready -h localhost -p 5432 >/dev/null 2>&1 \
|
||||
|| sudo -u postgres psql -c 'SELECT 1' >/dev/null 2>&1
|
||||
}
|
||||
|
||||
detect_pg_version() {
|
||||
if [ -d "/etc/postgresql" ]; then
|
||||
ls /etc/postgresql/ 2>/dev/null | sort -nr | head -1
|
||||
|
|
@ -18,8 +30,19 @@ detect_pg_version() {
|
|||
echo "${PG_VERSION}"
|
||||
}
|
||||
|
||||
wait_for_server() {
|
||||
local attempt
|
||||
for attempt in $(seq 1 "${READY_ATTEMPTS}"); do
|
||||
if server_ready; then
|
||||
return 0
|
||||
fi
|
||||
sleep "${READY_SLEEP_SECS}"
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
start_postgres() {
|
||||
if pg_ready; then
|
||||
if server_ready; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
|
|
@ -28,15 +51,17 @@ start_postgres() {
|
|||
|
||||
if command -v pg_ctlcluster >/dev/null 2>&1 && [ -n "${version}" ]; then
|
||||
sudo pg_ctlcluster "${version}" "${PG_CLUSTER}" start 2>/dev/null || true
|
||||
sleep 2
|
||||
pg_ready && return 0
|
||||
if wait_for_server; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
sudo systemctl start "postgresql@${version}-${PG_CLUSTER}" 2>/dev/null || \
|
||||
sudo systemctl start postgresql 2>/dev/null || true
|
||||
sleep 2
|
||||
pg_ready && return 0
|
||||
if wait_for_server; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "[ensure-postgres] ERROR: postgres is installed but not accepting connections" >&2
|
||||
|
|
@ -59,10 +84,17 @@ WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'teqo_test')\gexec
|
|||
SQL
|
||||
}
|
||||
|
||||
if command -v psql >/dev/null 2>&1 && [ -d "/etc/postgresql" ]; then
|
||||
ensure_ready() {
|
||||
start_postgres
|
||||
bootstrap_databases
|
||||
pg_ready
|
||||
if ! teqo_ready; then
|
||||
echo "[ensure-postgres] ERROR: teqo databases exist but connection as teqo/teqo failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
if command -v psql >/dev/null 2>&1 && [ -d "/etc/postgresql" ]; then
|
||||
ensure_ready
|
||||
echo "[ensure-postgres] OK (existing cluster)"
|
||||
exit 0
|
||||
fi
|
||||
|
|
@ -70,7 +102,5 @@ fi
|
|||
echo "[ensure-postgres] installing postgresql-${PG_VERSION} (Ubuntu package; local dev uses PG 17 via Docker)..."
|
||||
sudo apt-get update -qq
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "postgresql-${PG_VERSION}" "postgresql-client-${PG_VERSION}"
|
||||
start_postgres
|
||||
bootstrap_databases
|
||||
pg_ready
|
||||
ensure_ready
|
||||
echo "[ensure-postgres] OK"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ Conteúdo movido do `AGENTS.md` em 2026-07-30 (fatiamento do paradigma de agente
|
|||
|
||||
---
|
||||
|
||||
**Recently resolved (2026-07-31):** **Cloud `ensure-postgres` falso negativo no start** — o script tratava “role/DBs `teqo` prontos” como “Postgres aceitando conexões”. Em snapshot warm o cluster já está `online` sem role/DBs; `start_postgres` falhava com `postgres is installed but not accepting connections` **antes** de `bootstrap_databases`, o `start` do `environment.json` saía ≠0 e a UI marcava `INSTALL_FAILED` mesmo com o agente utilizável. Fix: separar `server_ready` (`pg_isready` / peer) de `teqo_ready`, bootstrap após o server up, retry no wait; `cloud-setup.sh` pina `DATABASE_URL` e asserta `payload_migrations` pós-migrate (no-op silencioso visto no JIT). Ruído cosmético no mesmo log (dirs de recording, `.installed` de plugins ENOENT) é race do exec-daemon — não é do Teqo.
|
||||
|
||||
**Recently resolved (2026-07-31):** **Pass 4 — auditoria de engenharia autônoma + guardrails das misses** — primeira execução em modo autônomo (Cursor Cloud) da skill engineering-audit, com precheck solitário (pool desligado) e primeiro harvest de `kind:agent-miss` (escopo OPS2: nasce `docs/GUARDRAILS.md`). **P0:** os 4 globals públicos (`site-settings`/`home`/`metadata`/`privacy-policy`) aceitavam qualquer autenticado no `update` — JWT de campanha (liderança inclusa) editava o site público via `/api/globals/*`; lockdown `payloadAdminOnly` + pins + guarda ([PR #91](https://github.com/fsolla/teqo/pull/91); editores perdem escrita nos globals de config deliberadamente). **P1:** `seed-posts.mjs` chamava `dieWithLabel` sem importar ([PR #92](https://github.com/fsolla/teqo/pull/92), com guarda de presença de import + `DAY_MS` single-source + ESLint lib→utilities sem type-import + guarda de `overrideAccess` omitido). **Misses:** #73 (deadlock `municipality_rels` — classe reproduzida: 7 violações int + 11 deep links e2e; migração para o alocador com teste de classe reescrito classe-agnóstico + guarda de 3 regras, [PR #93](https://github.com/fsolla/teqo/pull/93)); #52 (Drawer por célula em 3 listas de chips → `CampaignListSheetProvider` + invariante dev + guarda, [PR #94](https://github.com/fsolla/teqo/pull/94)); #53 (portão de readiness do autenticador virtual) + #54 (guarda de goto não assentado + convenção TESTING.md) em [PR #95](https://github.com/fsolla/teqo/pull/95); #83 fechada (guarda `agent:ship` já viva). **Registrado, não retry-fixed:** spec de chips de `campaignLeaderships` falha deterministicamente em dev na árvore limpa (nenhum POST dispara; prod 48/48 verde) — causa raiz via debug workflow (P4-L). Artefatos: seção Pass 4 no plano de qualidade, 15 linhas novas no ledger (2 stale fechadas: P3-A/P3-B), plano [`entrega-engenharia-p4.md`](docs/plans/entrega-engenharia-p4.md) com ondas P4-A→P4-L + mapa de guardas + defer+gatilho.
|
||||
|
||||
**Recently resolved (2026-07-31):** **CI build skip para diffs fora da árvore buildável** — `scripts/build-affected.mjs` + `classifyBuildScope` (núcleo em `test-affected-core.mjs`) decidem `run|none`; job `build-scope` barato no `ci-pr.yml` e o job `build` (Postgres + `pnpm build`) só roda em `mode=run`. Docs/tests/tooling/workflows pulam o build; `src/`, `public/` e configs do Next (`next.config`/`tsconfig`/`tailwind`/`postcss`/`components.json`/lockfile) forçam. `gate:ci` espelha. Push em `main` (`ci.yml`) continua sempre full.
|
||||
|
|
|
|||
Loading…
Reference in a new issue