# Suite de navegador (Playwright) + smoke REST contra un stack EFÍMERO. # # POR QUÉ NOCTURNO Y NO EN CADA PUSH: esto construye el bundle de producción # entero (`meteor build`, lo mismo que hace la imagen) y además baja un Chromium. # aaron es un host compartido con `capacity: 1`: si esto corriera en cada push, # la forja se quedaría sin turno. Los tests de servidor (build-image.yml) sí van # en cada push y son los que bloquean la imagen. # # POR QUÉ NO USA docker compose: el runner no tiene socket de Docker (ver la nota # de build-image.yml) — así que en vez de levantar docker-compose.e2e.yml, este # job construye el bundle y lo arranca dentro de su propio contenedor, con Mongo # como service container. El compose sigue siendo la forma de correrlo en local. # # ⚠️ Las dos siembras (smoke/seed.js y e2e/seed.js) BORRAN colecciones. Aquí eso # es seguro porque el Mongo es un service container que muere con el job. Jamás # apuntes esto a testfuegos.comunes.org. name: e2e on: schedule: # 04:15 UTC, con el runner libre. - cron: '15 4 * * *' workflow_dispatch: jobs: e2e: runs-on: docker container: image: node:22-bookworm # El pico es el `meteor build`, igual que en el job de la imagen. options: --memory=4g --memory-swap=4g --cpus=3 services: mongo: image: mongo:7 # Nodo suelto, sin replica set: los service containers no dejan cambiar # el comando de arranque. Sin oplog Meteor cae a polling (cada 10s), así # que los tests que esperan a la unión tardan más — por eso sus timeouts # son de 60s. En local (docker-compose.e2e.yml) sí hay replica set. options: >- --health-cmd "mongosh --quiet --eval 'db.adminCommand({ping:1}).ok'" --health-interval 5s --health-timeout 5s --health-retries 20 env: METEOR_ALLOW_SUPERUSER: '1' NODE_OPTIONS: --dns-result-order=ipv4first --no-network-family-autoselection METEOR_RELEASE: '3.1' MONGO_URL: mongodb://mongo:27017/fuegos ROOT_URL: http://localhost:3000 PORT: '3000' BASE_URL: http://localhost:3000 E2E_BASE_URL: http://localhost:3000 SETTINGS: settings-ci.json steps: - name: Herramientas run: | set -e apt-get update -qq apt-get install -y --no-install-recommends \ curl ca-certificates git python3 python-is-python3 make g++ >/dev/null # mongosh por npm: el cliente no viene en node:22 y el service container # de mongo no es accesible con `docker exec` desde el job. npm install -g mongosh@2 >/dev/null - name: Descargar el código env: TOKEN: ${{ github.token }} run: | set -e mkdir -p src wget -q -O src.tar.gz \ "http://x-access-token:${TOKEN}@forgejo:3000/api/v1/repos/${GITHUB_REPOSITORY}/archive/${GITHUB_SHA}.tar.gz" tar xzf src.tar.gz -C src --strip-components=1 rm -f src.tar.gz - name: Instalar meteor-tool run: curl -fsSL "https://install.meteor.com/?release=${METEOR_RELEASE}" | sh - name: Construir el bundle de producción run: | set -e cd src meteor npm ci --no-audit --no-fund meteor build /tmp/build --directory --server-only cd /tmp/build/bundle/programs/server && npm install --omit=dev --no-audit --no-fund - name: Arrancar el servidor run: | set -e cd /tmp/build/bundle METEOR_SETTINGS="$(cat "${GITHUB_WORKSPACE}/src/settings-ci.json")" \ node main.js > /tmp/server.log 2>&1 & for i in $(seq 1 90); do wget -qO /dev/null "http://127.0.0.1:3000/" && break sleep 2 done wget -qO /dev/null "http://127.0.0.1:3000/" || { echo "El servidor no arrancó:"; tail -50 /tmp/server.log; exit 1; } # El smoke va primero y con su propia siembra: compara respuestas byte a # byte contra snapshots, así que cualquier dato que dejen los e2e (una # suscripción, la unión recalculada) lo haría fallar. - name: Smoke REST run: | set -e cd src mongosh --host mongo --quiet fuegos smoke/seed.js node smoke/run.js - name: Suite e2e run: | set -e cd src mongosh --host mongo --quiet fuegos e2e/seed.js # Dentro de e2e/: playwright busca su playwright.config.js en el # directorio de trabajo, y `npx --prefix` resuelve el binario pero NO # cambia el cwd (correría sin config y sin encontrar los tests). cd e2e npm ci --no-audit --no-fund npx playwright install --with-deps chromium npx playwright test # Sin `actions/upload-artifact` (action JS, ver fase 9 §3): al menos el log # del servidor y la lista de trazas quedan en la salida del job. - name: Diagnóstico en caso de fallo if: failure() run: | echo "===== últimas 200 líneas del servidor =====" tail -200 /tmp/server.log || true echo "===== trazas de Playwright =====" ls -R src/e2e/test-results 2>/dev/null | head -50 || true