The lint job moves out of tests.yml into lint.yml, unchanged in what it runs. Lint is the fastest check in the pipeline and the one most often broken, and reporting it as one job among the suites made a lint failure and a test failure look alike at a glance. The split left two comments in the wrong place, both artifacts of the copy rather than of the intent. tests.yml kept the six-line note explaining the lint policy — that only defect-catching rules fail the build, that everything else warns, and why no --max-warnings flag appears. With the job gone it sat directly above backend-unit, where a reader would fairly take it as describing the unit tests. It has moved to lint.yml, with the job it actually describes. lint.yml inherited tests.yml's header about backend-integration living in its own manual workflow after it held the runner for three hours. That is worth saying where someone might expect integration tests to run; in a workflow that only runs ESLint it explains the absence of something nobody was looking for. Replaced with why this workflow exists at all. Verified by parsing both files rather than by reading them: lint.yml declares one job, lint; tests.yml declares backend-unit and frontend-e2e. No job was lost in the move and none is now declared twice, which is the failure a copy-and-delete edit invites. Refs #113 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
137 lines
3.9 KiB
YAML
137 lines
3.9 KiB
YAML
name: Tests
|
|
|
|
# backend-integration lives in its own manual workflow
|
|
# (.gitea/workflows/backend-integration.yml) rather than running here. It held
|
|
# the runner for 3h12m on 2026-08-18 — 87 seconds of tests followed by a hang
|
|
# after the run completed — and blocked frontend-e2e behind it for the same
|
|
# three hours. Run it from Actions before merging anything that touches the API
|
|
# or the database.
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
types: [opened, synchronize, reopened]
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
backend-unit:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
|
|
- name: Install deps
|
|
run: npm install
|
|
working-directory: backend
|
|
|
|
- name: Run unit tests
|
|
id: unit
|
|
continue-on-error: true
|
|
run: npm run test:unit:json
|
|
working-directory: backend
|
|
|
|
- name: Summarize
|
|
if: always()
|
|
run: node scripts/summarize-jest.js backend/unit-results.json "Backend Unit Test"
|
|
|
|
- name: Fail job if tests failed
|
|
if: steps.unit.outcome == 'failure'
|
|
run: exit 1
|
|
|
|
frontend-e2e:
|
|
runs-on: ubuntu-latest
|
|
services:
|
|
postgres:
|
|
image: postgres:16
|
|
env:
|
|
POSTGRES_USER: redefined_test
|
|
POSTGRES_PASSWORD: redefined_test
|
|
POSTGRES_DB: redefined_test
|
|
options: >-
|
|
--health-cmd "pg_isready -U redefined_test"
|
|
--health-interval 5s
|
|
--health-timeout 5s
|
|
--health-retries 10
|
|
env:
|
|
PGHOST: postgres
|
|
PGPORT: 5432
|
|
PGUSER: redefined_test
|
|
PGPASSWORD: redefined_test
|
|
PGDATABASE: redefined_test
|
|
PORT: 3000
|
|
DEMO_MODE: 'true'
|
|
UPLOADS_DIR: /tmp/redefined-uploads
|
|
# NODE_ENV is deliberately unset: `npm install` omits devDependencies when
|
|
# NODE_ENV=production, which strips tsc/vite/@playwright/test and breaks the
|
|
# build. It would also flip the session cookie to Secure, which the e2e run
|
|
# serves over plain http.
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '20'
|
|
|
|
- name: Install backend deps
|
|
run: npm install
|
|
working-directory: backend
|
|
|
|
- name: Run migrations
|
|
run: node migrate.js up
|
|
working-directory: backend
|
|
|
|
- name: Build backend
|
|
run: npm run build
|
|
working-directory: backend
|
|
|
|
- name: Start backend
|
|
run: |
|
|
mkdir -p /tmp/redefined-uploads
|
|
node dist/server.js > /tmp/backend.log 2>&1 &
|
|
for i in $(seq 1 30); do
|
|
if node -e "require('http').get('http://localhost:3000/api/config', r => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"; then
|
|
echo "Backend ready after ${i}s"
|
|
exit 0
|
|
fi
|
|
sleep 1
|
|
done
|
|
echo "Backend did not become ready within 30s:"
|
|
cat /tmp/backend.log
|
|
exit 1
|
|
working-directory: backend
|
|
|
|
- name: Install frontend deps
|
|
run: npm install
|
|
working-directory: frontend
|
|
|
|
- name: Install Playwright browsers
|
|
run: npx playwright install --with-deps chromium
|
|
working-directory: frontend
|
|
|
|
- name: Run Playwright tests
|
|
id: e2e
|
|
continue-on-error: true
|
|
env:
|
|
PLAYWRIGHT_JSON_OUTPUT_NAME: playwright-results.json
|
|
run: npx playwright test --reporter=json
|
|
working-directory: frontend
|
|
|
|
- name: Backend log
|
|
if: steps.e2e.outcome == 'failure'
|
|
run: cat /tmp/backend.log
|
|
|
|
- name: Summarize
|
|
if: always()
|
|
run: node scripts/summarize-playwright.js frontend/playwright-results.json
|
|
|
|
- name: Fail job if tests failed
|
|
if: steps.e2e.outcome == 'failure'
|
|
run: exit 1 |