From 4007b01da921b68c2cbc043195c3b226d1915d55 Mon Sep 17 00:00:00 2001 From: openhands Date: Fri, 4 Sep 2026 13:32:51 +0200 Subject: [PATCH] ci: run e2e smoke against deployed app and ignore playwright artifacts - Add e2e job (needs deploy, main/master only) that installs the Playwright browser and smoke-tests the live container on :3002 - Keep deploy-job contract slice from bleeding into the e2e job - Cover the e2e job in the CI workflow contract test - Ignore Playwright output dirs (test-results, playwright-report, blob-report) --- .gitea/workflows/ci.yaml | 28 ++++++++++++++++++++++++ .gitignore | 5 +++++ src/lib/ci-workflow-contract.test.ts | 7 ++++++ src/lib/deploy-workflow-contract.test.ts | 6 ++++- 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index d404a554..26892add 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -158,3 +158,31 @@ jobs: docker rm epicnext-cms-app 2>/dev/null || true docker compose -f /var/www/atom-nexst/docker-compose.yml up -d --no-build 2>&1 || true exit 1 + + # ───────────────────────────────────────────── + # E2E smoke against the freshly deployed container. + # Runs after a successful deploy on main/master only + # (on PRs the deploy job is skipped, so this is skipped too). + # Public read-only endpoints only — safe against production. + # ───────────────────────────────────────────── + e2e: + needs: deploy + if: gitea.event_name == 'push' && (gitea.ref_name == 'main' || gitea.ref_name == 'master') + runs-on: self-hosted + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + repository: ${{ gitea.repository }} + token: ${{ gitea.token }} + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Install Playwright browser + run: pnpm exec playwright install chromium + + - name: Smoke test deployed app + env: + PLAYWRIGHT_BASE_URL: "http://127.0.0.1:3002" + run: pnpm test:e2e diff --git a/.gitignore b/.gitignore index 1ca97329..fa734ee4 100644 --- a/.gitignore +++ b/.gitignore @@ -33,4 +33,9 @@ public/tmp/ # Test coverage reports coverage/ + +# Playwright test artifacts +test-results/ +playwright-report/ +blob-report/ .aider* diff --git a/src/lib/ci-workflow-contract.test.ts b/src/lib/ci-workflow-contract.test.ts index 930da870..23f874f0 100644 --- a/src/lib/ci-workflow-contract.test.ts +++ b/src/lib/ci-workflow-contract.test.ts @@ -57,4 +57,11 @@ describe("CI workflow", () => { it("has tag trigger", () => { expect(workflow).toContain('tags: ["v*"]'); }); + + it("has e2e job that smoke-tests the deployed app", () => { + expect(workflow).toContain("e2e:"); + expect(workflow).toContain("needs: deploy"); + expect(workflow).toContain("pnpm test:e2e"); + expect(workflow).toContain("PLAYWRIGHT_BASE_URL"); + }); }); diff --git a/src/lib/deploy-workflow-contract.test.ts b/src/lib/deploy-workflow-contract.test.ts index 64af80e6..7ff2a0eb 100644 --- a/src/lib/deploy-workflow-contract.test.ts +++ b/src/lib/deploy-workflow-contract.test.ts @@ -7,7 +7,11 @@ const workflow = readFileSync( "utf8", ); const deployStart = workflow.indexOf("\n deploy:"); -const deployJob = deployStart > -1 ? workflow.slice(deployStart) : ""; +const e2eStart = workflow.indexOf("\n e2e:"); +const deployJob = + deployStart > -1 + ? workflow.slice(deployStart, e2eStart > deployStart ? e2eStart : undefined) + : ""; describe("deploy job", () => { it("runs on self-hosted for Docker access", () => {