Commit Graph

43 Commits

Author SHA1 Message Date
Marcel
bbbdf8cd09 ci: restrict push trigger to main — eliminate duplicate runs on feature branches
Some checks failed
CI / Unit & Component Tests (push) Failing after 1m5s
CI / OCR Service Tests (push) Successful in 17s
CI / Backend Unit Tests (push) Successful in 4m27s
CI / fail2ban Regex (push) Successful in 40s
CI / Compose Bucket Idempotency (push) Successful in 58s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 11:12:24 +02:00
Marcel
3de0d2f0fe fix(ci): add IMPORT_HOST_DIR stub to compose-idempotency env file
Some checks failed
CI / fail2ban Regex (push) Has been cancelled
CI / Compose Bucket Idempotency (push) Has been cancelled
CI / Unit & Component Tests (push) Has been cancelled
CI / OCR Service Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
Docker Compose interpolates all variables in the full file even when
only a subset of services is requested. The backend service uses
IMPORT_HOST_DIR with :? (hard-required), causing the idempotency job
to abort before any container starts. A dummy path satisfies the parser;
the backend service is never started in this job so the path need not exist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 10:58:38 +02:00
Marcel
0abbc147e2 ci(unit-tests): add negative self-test case to upload-artifact guard
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / OCR Service Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / fail2ban Regex (push) Has been cancelled
CI / Compose Bucket Idempotency (push) Has been cancelled
The previous self-test proved the regex catches @v5 (positive case).
This adds a negative case proving @v3 is NOT flagged — guards against
a false-positive that would break every CI run permanently.

Suggested by Sara Holt in review of PR #558.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 10:58:19 +02:00
Marcel
fa46492759 ci(workflows): downgrade upload-artifact v4 → v3 — Gitea act_runner limitation (ADR-014)
Reverts the re-regression introduced in 410b91e2. Gitea Actions
(act_runner) does not implement the v4 artifact protocol — jobs report
failure even when all tests pass. Pins all three call sites back to @v3
and adds load-bearing inline comments pointing to ADR-014 / #557.

This commit makes the grep guard added in the previous commit GREEN.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 10:58:19 +02:00
Marcel
3965541879 ci(unit-tests): add grep guard for (upload|download)-artifact@v4+
Adds a repo-invariant check in the same 'Assert' block as the ADR-012
birpc guard. Anchored to YAML `uses:` lines so the inline self-test
fixture does not false-positive. Fails with an actionable error
referencing ADR-014 / #557.

Guard is intentionally RED at this commit — the three v4 call sites
are downgraded in the next commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 10:58:19 +02:00
Marcel
67cd56acc7 ci(unit-tests): extend grep guard to async vi.mock with dynamic import
The pdfjs-dist literal grep added in 9260866f only caught one named
trigger of the birpc teardown race; the underlying mechanism (ADR 012 /
#553) is any async vi.mock factory whose body performs `await import(...)`.

Add a second PCRE-multiline grep matching that shape. Scoped to
**/*.{spec,test}.ts under frontend/src/, excluding __meta__ (which holds
the fixture strings exercising the meta-test). Defence in depth pairs with
the ESLint rule (saves at edit time) and the in-suite meta-test (catches
when tests run).

Verified locally with real GNU grep against a planted synthetic offender.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 22:11:09 +02:00
Marcel
9260866f47 ci(unit-tests): add early grep check for banned vi.mock pdfjs-dist pattern
Some checks failed
CI / Unit & Component Tests (push) Failing after 1m47s
CI / OCR Service Tests (push) Successful in 16s
CI / Backend Unit Tests (push) Successful in 4m11s
CI / fail2ban Regex (push) Successful in 38s
CI / Compose Bucket Idempotency (push) Failing after 11s
Adds a static grep step that runs after Lint and before the test suite.
Fails in ~1 s if any file under frontend/src/ contains the banned
vi.mock('pdfjs-dist' pattern, catching the regression before Playwright
spins up. Belt-and-suspenders with the ESLint rule (ADR 012).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 12:32:23 +02:00
Marcel
1ead1f293f ci(coverage): document that birpc guard covers coverage run only
Adds a comment above the assertion step so a future developer diagnosing
a birpc-related failure in `npm test` knows where to find the diagnostic.

Addresses Sara Holt + Tobias Wendt round-4 observation on PR #536.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 09:57:28 +02:00
Marcel
729f5c66d6 ci(coverage): use grep -F for birpc guard to avoid BRE escaping
-F (fixed string) matches the literal pattern [birpc] rpc is closed
without relying on BRE bracket escaping, making the intent explicit
and immune to accidental regex interpretation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 09:57:28 +02:00
Marcel
d40f477397 ci(coverage): include coverage log in artifact upload
The birpc guard step writes to /tmp/coverage-test-<run_id>.log and exits 1
when a race is detected. Without this file in the artifact, the evidence
disappears when the runner tears down — only the exit code remained visible.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 09:57:28 +02:00
Marcel
cf78957476 ci(coverage): harden coverage guard step
- Add explicit set -eo pipefail so npm test:coverage exit code
  propagates through the pipe (not just tee's always-0 exit)
- Scope log file to github.run_id to prevent stale-log false positives
  on retried steps sharing the same runner /tmp
- Tighten grep pattern to \[birpc\] rpc is closed to avoid matching
  unrelated log lines that happen to contain "rpc is closed"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 09:57:28 +02:00
Marcel
3594204214 ci(coverage): simplify coverage step and pin shell to bash
- removes unreachable `; exit ${PIPESTATUS[0]}` — already covered by pipefail (Tobias)
- adds explicit `shell: bash` to both new steps for clarity (Tobias)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 09:57:28 +02:00
Marcel
538adb43a9 ci(guard): fail unit-tests job if [birpc] rpc is closed appears in coverage run
Captures npm run test:coverage output with tee and adds an always-run step
that greps for the teardown-race fingerprint. Any future regression where a
vi.mock factory races with birpc teardown will now surface as an explicit CI
failure rather than a silent exit-1 after all tests report green (#535).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 09:57:28 +02:00
Marcel
e42c7b04c1 ci: drop redundant npm test step, coverage run covers it
The test:coverage step runs the full suite under Istanbul; running
`npm test` first executes every test twice for no extra signal.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 21:50:28 +02:00
Marcel
6ba7254344 test(ci): assert prerender output is only /hilfe/transkription
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / OCR Service Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / fail2ban Regex (push) Has been cancelled
CI / Compose Bucket Idempotency (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Has been cancelled
CI / OCR Service Tests (pull_request) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
CI / fail2ban Regex (pull_request) Has been cancelled
CI / Compose Bucket Idempotency (pull_request) Has been cancelled
Addresses Sara's review request on #515.

Without this gate, a future regression that turns prerender.crawl
back on (or adds a new prerender entry whose nav links into
protected routes) would silently bake /, /documents, /persons etc.
to "redirect-to-login" HTML and re-introduce #514.

Verified the script catches the current broken build state:
  $ find build/prerendered ... -not -path 'hilfe/*' ...
  build/prerendered/{index,documents,persons,geschichten,stammbaum}.html

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 17:00:54 +02:00
Marcel
e5363913ec fix(fail2ban): pin polling backend so jail actually reads Caddy access log
Some checks failed
CI / Unit & Component Tests (push) Failing after 2m49s
CI / OCR Service Tests (push) Successful in 16s
CI / Backend Unit Tests (push) Successful in 4m8s
CI / fail2ban Regex (push) Successful in 37s
CI / Compose Bucket Idempotency (push) Failing after 53s
CI / Unit & Component Tests (pull_request) Failing after 2m46s
CI / OCR Service Tests (pull_request) Successful in 15s
CI / Backend Unit Tests (pull_request) Successful in 4m14s
CI / fail2ban Regex (pull_request) Successful in 37s
CI / Compose Bucket Idempotency (pull_request) Failing after 50s
Closes #503.

Debian's fail2ban package ships defaults-debian.conf with
`[DEFAULT] backend = systemd`. Without an explicit override, our
familienarchiv-auth jail inherits the systemd backend at runtime,
reads from journald, and never inspects /var/log/caddy/access.log.
A live login brute-force would not be banned.

Add `backend = polling` to the jail and a CI step that links the jail
into /etc/fail2ban/ and asserts `fail2ban-client -d` resolves it to
the polling backend, not the inherited systemd backend.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 14:59:40 +02:00
Marcel
7e430998b8 security(fail2ban): widen jail to /forgot-password and rate-limit 429
The filter only watched /api/auth/login 401 — leaving the forgot-password
endpoint open to:

  - email enumeration (slow brute-force probing which addresses exist)
  - password-reset brute-force against accounts whose addresses leak

Widens the failregex to /api/auth/(login|forgot-password) and adds 429 to
the status alternation so a future in-app rate-limiter response is also
caught by the jail (defense in depth).

CI assertions extended to cover both new dimensions plus a negative case
on an unrelated 401 endpoint (/api/documents) — pins that the widening
did not over-match.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:10:08 +02:00
Marcel
156afa14a2 test(ci): add compose bucket-bootstrap idempotency job
The create-buckets service in docker-compose.prod.yml runs on every
`docker compose up` (one-shot, restart=no). A re-deploy that fails
because the user/bucket/policy already exists would block the whole
nightly/release pipeline — and the only way to find out today is to
run a second deploy.

This job runs the bootstrap twice against a throwaway minio stack and
asserts both invocations exit 0. Caught at PR time, not at the third
nightly deploy at 02:00.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:08:51 +02:00
Marcel
9652894aa4 test(ci): add fail2ban-regex regression job
Caddy 2.x emits JSON access logs; the failregex in
infra/fail2ban/filter.d/familienarchiv-auth.conf depends on the
"remote_ip" → "uri" → "status" key order being stable. A future Caddy
upgrade that reorders fields would break the jail silently (regex no
longer matches → fail2ban returns 0 hits → host stops banning
brute-force, discovered only at the next incident).

This job pins the contract: a sample /api/auth/login 401 line must
match (1 hit) and a /api/auth/login 200 line must not (0 hits).
Catches a regression at PR time instead of in production.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:03:04 +02:00
Marcel
eccecf35e3 ci: add combined coverage gate to unit-tests job
Some checks failed
CI / Unit & Component Tests (push) Failing after 5m54s
CI / Backend Unit Tests (push) Failing after 3m20s
CI / Unit & Component Tests (pull_request) Failing after 5m48s
CI / OCR Service Tests (push) Successful in 38s
CI / OCR Service Tests (pull_request) Successful in 33s
CI / Backend Unit Tests (pull_request) Failing after 3m21s
Runs test:coverage (server v8 + client Istanbul) after tests, hard-gates
on both 80% branch thresholds, and uploads coverage/ as an artifact.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 17:51:10 +02:00
Marcel
a158048f45 fix(ci): expose Docker socket env vars for Testcontainers in backend job
DOCKER_HOST makes the socket explicit rather than relying on runner
config propagation; TESTCONTAINERS_RYUK_DISABLED=true avoids Ryuk
watchdog start failures in nested container environments.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 16:03:36 +02:00
Marcel
ac999066dd fix(ci): add TZ=Europe/Berlin to frontend test step
date-buckets.spec.ts midnight tests pass timezone-aware dates (+02:00)
which are 22:00 UTC the prior day; setHours(0,0,0,0) uses local TZ.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 16:03:36 +02:00
Marcel
e2d74ff880 ci: add npm run build step to unit-tests job
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / OCR Service Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
The prerender fix only prevents regression if the build is actually run in
CI. Without this gate, a future prerendered route that becomes unreachable
behind auth would fail silently until someone runs the build manually.

Fits after the test step in the existing unit-tests job — no new job needed
since node_modules is already cached for the Playwright container.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 14:25:32 +02:00
Marcel
410b91e2a5 chore: upgrade upload-artifact action from v3 to v4
Some checks failed
CI / Unit & Component Tests (push) Failing after 3m34s
CI / OCR Service Tests (push) Successful in 43s
CI / OCR Service Tests (pull_request) Successful in 30s
CI / Backend Unit Tests (push) Failing after 3m15s
CI / Unit & Component Tests (pull_request) Failing after 3m30s
CI / Backend Unit Tests (pull_request) Failing after 3m14s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 14:54:29 +02:00
Marcel
84c09e41ef test(ocr): add /train-sender auth tests and run sender registry tests in CI
Add 503/403 auth tests for the /train-sender endpoint, matching the pattern
already used for /train and /segtrain. Also surface test_sender_registry.py
in CI (it needs no ML stack) and add pytest-asyncio to the install step.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 21:14:27 +02:00
Marcel
68b57918eb ci: add ocr-tests job for spell_check and confidence unit tests
Some checks failed
CI / Unit & Component Tests (push) Failing after 2m48s
CI / OCR Service Tests (push) Successful in 1m59s
CI / Backend Unit Tests (push) Failing after 2m53s
CI / Unit & Component Tests (pull_request) Failing after 2m52s
CI / OCR Service Tests (pull_request) Successful in 33s
CI / Backend Unit Tests (pull_request) Failing after 2m54s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 16:55:07 +02:00
Marcel
4b8e0637ce fix(ci): pin DOCKER_API_VERSION=1.43 for Testcontainers on NAS runner
Some checks failed
CI / Unit & Component Tests (pull_request) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
CI / Unit & Component Tests (push) Successful in 3m41s
CI / Backend Unit Tests (push) Failing after 2m41s
Testcontainers 2.0.2 (via Spring Boot 4.0) negotiates Docker API 1.44,
but the NAS runner has Docker Engine 24.x which caps at 1.43. Forcing
the client version down unblocks tests until Docker is upgraded on the NAS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 12:28:57 +02:00
Marcel
c18ad25514 remove e2e from pipeline. takes too long 2026-04-06 11:22:08 +02:00
Marcel
154f859efc feat(korrespondenz): address PR #164 review – blockers and suggestions
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Failing after 1m36s
CI / Backend Unit Tests (pull_request) Failing after 2m36s
CI / E2E Tests (pull_request) Failing after 1h49m0s
Blockers (14):
- B1: fix senderName/receiverName to use $derived instead of $state + sync $effect
- B2: migrate all korrespondenz components from messages-extra shim to paraglide m.*
- B3: i18n CorrespondenzEmptyState (heading, subtext, search placeholder)
- B4: add response.ok checks to admin layout server load
- B5: add response.ok checks to korrespondenz page server load
- B6: add page.server.spec.ts with 5 test suites for korrespondenz load function
- B7: add axe-core accessibility checks to all e2e korrespondenz tests
- B8: add Testcontainers JPQL tests for findSinglePersonCorrespondence (DISTINCT + sender)
- B9: hide auth reset-token endpoint from OpenAPI spec; remove from generated api.ts
- B11: replace amber hardcoded hex colors in SinglePersonHintBar with brand tokens
- B12: replace clipboard emoji with Heroicons SVG in SinglePersonHintBar
- B13: create DateInput component (German dd.mm.yyyy); use it in CorrespondenzFilterControls
- B14: add Paraglide compile step to CI workflow before lint/test

Suggestions (11):
- S1: make CorrespondentSuggestionsDropdown a pure display component; lift fetch to PersonBar
- S2: fix leftover messages-extra import in ConversationTimeline; use brand tokens for status dots
- S3: add intent comment to EntityNav openFlyout behavior
- S4: rename canManageGroups → canManagePermissions throughout admin
- S6: remove domFlush helper from DateInput spec; use expect.poll instead
- S7: replace test.skip with throw new Error in bilateral e2e tests
- S8: add inverse aria-disabled test for filter strip
- S9: remove sm:min-h-0 from sort button to preserve 44px touch target
- S10: add title attributes to tablet trigger buttons in EntityNav
- S11: delete messages-extra.ts shim entirely

Also: fix admin pages revealing blank strip at bottom (-mb-6 on admin layout)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 19:57:48 +02:00
Marcel
908221f04d feat(frontend): add forgot-password and reset-password pages
Some checks failed
CI / Unit & Component Tests (push) Successful in 2m7s
CI / Backend Unit Tests (push) Successful in 2m3s
CI / E2E Tests (push) Failing after 14m54s
CI / Unit & Component Tests (pull_request) Successful in 2m4s
CI / E2E Tests (pull_request) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
- /forgot-password: email form → sends POST /api/auth/forgot-password → success banner
- /reset-password: password form reads token from URL → sends POST /api/auth/reset-password
- Login page: add "Passwort vergessen?" link
- hooks.server.ts: add /forgot-password and /reset-password to PUBLIC_PATHS; skip auth
  injection for public auth API endpoints
- errors.ts: add INVALID_RESET_TOKEN error code
- i18n: add all new message keys in de/en/es
- playwright.config.ts: use E2E_BASE_URL for webServer check URL (allows reusing docker
  dev server at port 5173 locally)
- ci.yml: pass E2E_BACKEND_URL=http://localhost:8080 to E2E test step
- e2e/password-reset.spec.ts: 5 tests (4 pass locally, full flow requires e2e profile in CI)
- Regenerated OpenAPI types including new /api/auth/* endpoints

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 07:26:35 +01:00
Marcel
db2fc33e99 fix(frontend): enforce lint locally and in CI, fix all pre-existing violations
Some checks failed
CI / Unit & Component Tests (push) Successful in 1m59s
CI / E2E Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
## Pre-commit hook
- Add .husky/pre-commit at repo root: runs `cd frontend && npm run lint`
- Update prepare script in package.json to auto-configure git hooks path
  on npm install (git -C .. config core.hooksPath .husky)
- Add lint step to CI unit-tests job so it catches issues before tests run
- Add generated dirs to .prettierignore (paraglide_bak*, test-results, .auth)
- Add src/lib/paraglide_bak* to .gitignore so ESLint can ignore them

## ESLint fixes (all pre-existing)
- Disable svelte/no-navigation-without-resolve: false positive in SvelteKit
  (rule targets Svelte 5 standalone routing, not SvelteKit <a href>)
- Fix svelte/require-each-key: add (item.id)/(item) keys to all {#each} blocks
  across 10 files — improves Svelte reconciliation performance
- Fix svelte/prefer-writable-derived in PersonTypeahead: $state+$effect → $derived
- Fix svelte/prefer-svelte-reactivity: URLSearchParams → SvelteURLSearchParams,
  Map → SvelteMap (enables Svelte reactive tracking)
- Fix @typescript-eslint/no-unused-vars: remove dead imports/variables

## Prettier
- Run npm run format to bring all source files in line with .prettierrc

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 15:55:42 +01:00
Marcel
4142c7cd83 devops: fix upload-artifact and use Playwright Docker image for unit tests
Some checks failed
CI / Unit & Component Tests (pull_request) Successful in 1m54s
CI / Backend Unit Tests (pull_request) Successful in 2m4s
CI / E2E Tests (pull_request) Failing after 17m35s
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (push) Has been cancelled
- Switch unit-tests job to mcr.microsoft.com/playwright:v1.58.2-noble
  container; Chromium and all system deps are pre-installed so the
  browser install/cache dance is eliminated entirely (closes #13)

- Downgrade upload-artifact@v4 → v3 in both unit-tests and e2e-tests
  jobs; v4 is not supported on Gitea (GHES) and was causing jobs to
  report failure even when all tests passed, and prevented the
  Playwright browser cache from ever being saved (closes #14)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 17:17:53 +01:00
Marcel
db6dc28528 fix(ci): pin DOCKER_API_VERSION=1.43 for e2e job
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
The runner's Docker client negotiates API 1.53 but the daemon on the
NAS only supports up to 1.43. Pin the version for all docker commands
in the e2e job, including the new network connect step.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 15:13:17 +01:00
Marcel
208dc87d69 fix(ci): connect job container to compose network for DB/MinIO access
The act_runner job runs inside a Docker container. Docker Compose port
mappings bind to the Docker host, not the job container's localhost —
so localhost:5433 was always refused.

Fix: after compose starts, connect the job container (identified by
/etc/hostname) to the archive-net compose network. Then switch the
backend startup args to use service names db:5432 and minio:9000
instead of host-mapped ports.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 15:13:17 +01:00
Marcel
d943372ea7 fix(ci): pass docker-compose.ci.yml override to e2e compose commands
The e2e job was calling plain `docker compose up` without the CI
override file, so it used the base compose bind-mount for MinIO
(./data/minio) which doesn't exist on the runner. The CI override
replaces bind mounts with ephemeral named volumes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 15:13:17 +01:00
Marcel
553fa8a4b9 ci: cache Maven repository explicitly for both Java jobs
Some checks failed
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
CI / E2E Tests (pull_request) Has been cancelled
The built-in cache: maven in setup-java@v4 does not reliably work
on self-hosted act runners. Replace with an explicit actions/cache@v4
on ~/.m2/repository keyed on pom.xml hash.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 22:06:35 +01:00
Marcel
409e70078c ci: cache node_modules and Playwright browser binary
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
node_modules and the Playwright Chromium binary were downloaded fresh
on every run, making setup account for ~99% of pipeline runtime.

- Cache frontend/node_modules keyed on package-lock.json hash
- Cache ~/.cache/ms-playwright keyed on package-lock.json hash
- On cache hit: skip npm ci and browser download, only reinstall
  system deps (install-deps) which is much faster than a full install

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 22:03:40 +01:00
Marcel
5f36930b6b ci: use non-standard ports for DB and MinIO in e2e job
Some checks failed
CI / Unit & Component Tests (pull_request) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
CI / E2E Tests (pull_request) Has been cancelled
CI / Unit & Component Tests (push) Successful in 17m15s
CI / E2E Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
Avoids conflicts with any system services (PostgreSQL, MinIO) that
may already occupy 5432/9000/9001 on the runner host.
DB: 5433, MinIO API: 9100, MinIO console: 9101.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 21:44:09 +01:00
Marcel
b456c8f1bd ci: free host ports before starting e2e infrastructure
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Port 5432 was already in use after docker compose cleanup because a
system-level PostgreSQL service on the runner host holds the port.
Also kill any stray containers binding to 5432/9000/9001.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 21:41:58 +01:00
Marcel
3f987ca48f ci: add backend unit test job to pipeline
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
CI / E2E Tests (pull_request) Has been cancelled
CI / Unit & Component Tests (pull_request) Has been cancelled
Runs ./mvnw clean test in a dedicated job — no DB or S3 needed
since all tests use Mockito or WebMvcTest slices.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 21:37:50 +01:00
Marcel
f4e6fe587c fix(ci): tear down leftover containers before e2e run
Some checks failed
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (push) Has started running
Port 5432 was already bound by a zombie container from a previous
failed run, preventing docker compose from starting the DB.
Add a cleanup step at the top of the e2e job to ensure a clean state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 20:57:33 +01:00
Marcel
dcb26e201a fix(ci): replace docker-compose v1 with docker compose v2
Some checks failed
CI / Unit & Component Tests (push) Failing after 12m35s
CI / E2E Tests (push) Failing after 1m1s
The act runner does not have the standalone docker-compose binary.
Replace both occurrences with the v2 plugin syntax (space instead of hyphen).
Closes #3

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 20:25:06 +01:00
Marcel
b3de5f885d ci: add workflows 2026-03-17 13:32:12 +00:00