Forgejo Actions PR pipeline (#13) #34

Merged
james merged 3 commits from 13-ci-pipeline into main 2026-06-13 12:52:30 +00:00
Owner

Closes #13.

Summary

Single workflow file at .forgejo/workflows/pr.yml, triggered on PRs to main. Five jobs run in parallel:

Job Does
Lint eslint .
Typecheck tsc --noEmit
Build next build
Test (sqlite) full vitest suite, SQLite in-process :memory:
Test (postgres) full vitest suite, against postgres:16 service

The test job is a matrix on engine with fail-fast: false, so a parity bug that turns one engine red still surfaces the other engine's result. The matrix env conditional sets TEST_POSTGRES_URL only on the postgres leg; the sqlite leg gets an empty string, and the harness in tests/db/_engines.ts skips its Postgres suite cleanly.

Implementation notes

  • npm cache via actions/setup-node@v4 (cache: npm). Caches ~/.npm rather than node_modules directly — npm ci still reinstalls, but from the cache, which dodges the well-known stale-node_modules failure modes.
  • Concurrency group cancels in-flight runs on the same PR when a newer commit lands. Keeps runner time bounded under force-push iteration.
  • Postgres service container uses pg_isready health check so the test step doesn't start until the service is accepting connections. Avoids the flaky-first-test-fails pattern.

Acceptance criteria

  • A failing test fails the PR check — verified by the structure of npm test exit code → job failure → PR check fails.
  • Both DB engines show up in job logs with real DB tests — Test (sqlite) and Test (postgres) are distinct job runs in the UI; the latter runs the Postgres half of describePerEngine. Confirmed locally end-to-end (18/18 across engines).
  • Green PR run reproducible from a fresh clone with npm ci && npm run build && npm test — that's literally what each job runs.

Runner prerequisite

This workflow requires a Forgejo Actions runner registered with forge.wynning.tech. If no runner is configured the workflow will queue indefinitely without running.

Closes #13. ## Summary Single workflow file at `.forgejo/workflows/pr.yml`, triggered on PRs to `main`. Five jobs run in parallel: | Job | Does | | ---------------- | ----------------------------------------------------- | | `Lint` | `eslint .` | | `Typecheck` | `tsc --noEmit` | | `Build` | `next build` | | `Test (sqlite)` | full vitest suite, SQLite in-process `:memory:` | | `Test (postgres)`| full vitest suite, against `postgres:16` service | The test job is a matrix on engine with `fail-fast: false`, so a parity bug that turns one engine red still surfaces the other engine's result. The matrix env conditional sets `TEST_POSTGRES_URL` only on the postgres leg; the sqlite leg gets an empty string, and the harness in `tests/db/_engines.ts` skips its Postgres suite cleanly. ## Implementation notes - **npm cache via `actions/setup-node@v4` (`cache: npm`).** Caches `~/.npm` rather than `node_modules` directly — `npm ci` still reinstalls, but from the cache, which dodges the well-known stale-`node_modules` failure modes. - **Concurrency group cancels in-flight runs** on the same PR when a newer commit lands. Keeps runner time bounded under force-push iteration. - **Postgres service container** uses `pg_isready` health check so the test step doesn't start until the service is accepting connections. Avoids the flaky-first-test-fails pattern. ## Acceptance criteria - [x] A failing test fails the PR check — verified by the structure of `npm test` exit code → job failure → PR check fails. - [x] Both DB engines show up in job logs with real DB tests — `Test (sqlite)` and `Test (postgres)` are distinct job runs in the UI; the latter runs the Postgres half of `describePerEngine`. Confirmed locally end-to-end (18/18 across engines). - [x] Green PR run reproducible from a fresh clone with `npm ci && npm run build && npm test` — that's literally what each job runs. ## Runner prerequisite This workflow requires a Forgejo Actions runner registered with `forge.wynning.tech`. If no runner is configured the workflow will queue indefinitely without running.
Add Forgejo Actions PR pipeline (#13)
Some checks failed
pr.yml / Add Forgejo Actions PR pipeline (#13) (pull_request) Failing after 0s
5843034749
Five jobs run in parallel on every PR targeting main:

- Lint (eslint .)
- Typecheck (tsc --noEmit)
- Build (next build)
- Test (sqlite) — in-process :memory:
- Test (postgres) — postgres:16 service container

The test job is a matrix on engine, fail-fast: false, so a parity bug
that turns one engine red doesn't hide the other engine's result.
Both legs run the full vitest suite; the sqlite leg gets an empty
TEST_POSTGRES_URL so its Postgres tests skip cleanly, the postgres
leg points at the service container at localhost:5432.

Each job uses actions/setup-node@v4 with cache: npm — that caches the
npm download cache (~/.npm), so `npm ci` reinstalls quickly without
risking the staleness pitfalls of caching node_modules itself.

A concurrency group cancels in-flight runs when a PR is force-pushed,
keeping runner time bounded under rapid iteration.

The DB matrix only meaningfully exercises both engines once #8 is on
the base branch — which it now is, post-merge. New PRs will see real
DB-touching tests across SQLite and Postgres in CI from this point on.

Closes #13

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fix workflow
Some checks failed
PR / Test (postgres) (pull_request) Failing after 15s
PR / Build (pull_request) Successful in 1m36s
PR / Typecheck (pull_request) Successful in 1m51s
PR / Test (sqlite) (pull_request) Successful in 2m14s
PR / Lint (pull_request) Successful in 3m20s
eab610bec7
Wait for Postgres explicitly in CI instead of via service health check
All checks were successful
PR / Lint (pull_request) Successful in 1m18s
PR / Typecheck (pull_request) Successful in 1m19s
PR / Test (postgres) (pull_request) Successful in 1m24s
PR / Test (sqlite) (pull_request) Successful in 1m25s
PR / Build (pull_request) Successful in 1m44s
f25e5584b6
The first CI run on #13 failed because the Forgejo act_runner reported
the Postgres service container "not healthy" after a single probe and
gave up — its handling of --health-retries diverges from GitHub
Actions, where 10 retries at 5s intervals would have been honoured.

Switching strategies: drop --health-cmd from the service spec
entirely, and gate the test step on an explicit Node poll that opens
a real connection and runs SELECT 1. This sidesteps the runner's
healthcheck loop and gives deterministic readiness gating that
doesn't depend on which act_runner version is installed.

The poll uses the same pg client we already depend on (no extra
installs), runs only on the postgres matrix leg, and bounds itself to
60 seconds. Verified locally against postgres:16 in podman — script
returns "postgres ready" once the server accepts queries.
james merged commit 7964ab78e6 into main 2026-06-13 12:52:30 +00:00
Sign in to join this conversation.
No description provided.