From df8cc8136f89bde440bf454e9d3cf29d93facce9 Mon Sep 17 00:00:00 2001 From: Devin Foley Date: Thu, 19 Mar 2026 19:19:32 -0700 Subject: [PATCH 1/3] ci: add e2e tests to PR checks Add a PR E2E workflow that runs the Playwright onboarding test on every PR targeting master. Generates a minimal config file and lets Playwright manage the server lifecycle. Runs in skip_llm mode so no secrets are required. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/pr-e2e.yml | 70 ++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .github/workflows/pr-e2e.yml diff --git a/.github/workflows/pr-e2e.yml b/.github/workflows/pr-e2e.yml new file mode 100644 index 00000000..f1616a47 --- /dev/null +++ b/.github/workflows/pr-e2e.yml @@ -0,0 +1,70 @@ +name: PR E2E + +on: + pull_request: + branches: + - master + +concurrency: + group: pr-e2e-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + e2e: + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9.15.4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: pnpm + + - name: Install dependencies + run: pnpm install --no-frozen-lockfile + + - name: Build + run: pnpm build + + - name: Install Playwright + run: npx playwright install --with-deps chromium + + - name: Generate Paperclip config + run: | + mkdir -p ~/.paperclip/instances/default + cat > ~/.paperclip/instances/default/config.json << 'CONF' + { + "$meta": { "version": 1, "updatedAt": "2026-01-01T00:00:00.000Z", "source": "onboard" }, + "database": { "mode": "embedded-postgres" }, + "logging": { "mode": "file" }, + "server": { "deploymentMode": "local_trusted", "host": "127.0.0.1", "port": 3100 }, + "auth": { "baseUrlMode": "auto" }, + "storage": { "provider": "local_disk" }, + "secrets": { "provider": "local_encrypted", "strictMode": false } + } + CONF + + - name: Run e2e tests + env: + PAPERCLIP_E2E_SKIP_LLM: "true" + CI: "" + run: pnpm run test:e2e + + - name: Upload Playwright report + uses: actions/upload-artifact@v4 + if: always() + with: + name: playwright-report + path: | + tests/e2e/playwright-report/ + tests/e2e/test-results/ + retention-days: 14 From 652fa8223e7bbcfe512248d32ff0e4b9bc18f089 Mon Sep 17 00:00:00 2001 From: Devin Foley Date: Fri, 20 Mar 2026 13:49:03 -0700 Subject: [PATCH 2/3] fix: invert reuseExistingServer and remove CI="" workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The playwright.config.ts had `reuseExistingServer: !!process.env.CI` which meant CI would reuse (expect) an existing server while local dev would start one. This is backwards — in CI Playwright should manage the server, and in local dev you likely already have one running. Flip to `!process.env.CI` and remove the `CI: ""` env override from the workflow. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/pr-e2e.yml | 1 - tests/e2e/playwright.config.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/pr-e2e.yml b/.github/workflows/pr-e2e.yml index f1616a47..599b3649 100644 --- a/.github/workflows/pr-e2e.yml +++ b/.github/workflows/pr-e2e.yml @@ -56,7 +56,6 @@ jobs: - name: Run e2e tests env: PAPERCLIP_E2E_SKIP_LLM: "true" - CI: "" run: pnpm run test:e2e - name: Upload Playwright report diff --git a/tests/e2e/playwright.config.ts b/tests/e2e/playwright.config.ts index fd7e8b59..33022502 100644 --- a/tests/e2e/playwright.config.ts +++ b/tests/e2e/playwright.config.ts @@ -25,7 +25,7 @@ export default defineConfig({ webServer: { command: `pnpm paperclipai run`, url: `${BASE_URL}/api/health`, - reuseExistingServer: !!process.env.CI, + reuseExistingServer: !process.env.CI, timeout: 120_000, stdout: "pipe", stderr: "pipe", From da9b31e393ed002ccea4268235ad98ea79410b93 Mon Sep 17 00:00:00 2001 From: Devin Foley Date: Fri, 20 Mar 2026 14:20:46 -0700 Subject: [PATCH 3/3] fix(ci): use --frozen-lockfile in e2e workflow Align with e2e.yml and ensure CI tests exactly the committed dependency tree. The pr-policy job already blocks lockfile changes in PRs, so frozen-lockfile is safe here. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/pr-e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-e2e.yml b/.github/workflows/pr-e2e.yml index 599b3649..47046932 100644 --- a/.github/workflows/pr-e2e.yml +++ b/.github/workflows/pr-e2e.yml @@ -30,7 +30,7 @@ jobs: cache: pnpm - name: Install dependencies - run: pnpm install --no-frozen-lockfile + run: pnpm install --frozen-lockfile - name: Build run: pnpm build