mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-07 04:12:04 +00:00
The compose file runs Postgres 18. An install from v1.45 or earlier keeps its Postgres 16 data in `pgdata`, which 18 cannot open, so a one-shot `db-upgrade` service moves it on the first start: it starts Postgres 16 on the old volume inside its own container, streams a dump into 18 in one transaction, compares every table's row count, gathers planner statistics and marks the old volume as moved. The app waits for it to succeed. The old volume is never changed apart from the marker, so the way back is the previous image and volume lines. A move cut short leaves a "moving" marker and runs again from scratch; an emptied new volume after a finished move is refused rather than refilled with the old state. scripts/compose-db-upgrade-check.sh plays all of it against real containers from the v1.45.0 compose file, and runs in CI on every change to the compose file. Pull requests run the integration suite and e2e on Postgres 18; the nightly integration run keeps 16 covered for installs that bring their own database.
183 lines
6.8 KiB
YAML
183 lines
6.8 KiB
YAML
name: Tests (nightly, shuffled)
|
|
|
|
# Looks for what a pull request run cannot see by design.
|
|
#
|
|
# - Order dependence. Both suites run with files and tests in a random order
|
|
# (`--sequence.shuffle`), seeded from the clock and printed at the top of
|
|
# the log and in the job summary. A failure that does not reproduce on a
|
|
# pull request reproduces here with `--sequence.seed=<seed>`.
|
|
# - New property-test inputs. Pull requests run every fast-check property
|
|
# with a fixed seed; this run picks a fresh one (`FC_SEED`) and five times
|
|
# the cases, and fast-check prints the seed and the shrunk counterexample
|
|
# on a failure (see tests/property/fast-check.ts).
|
|
# - Stale shard timings. The integration reports of this run are merged into
|
|
# a regenerated `tests/durations/integration.json`, uploaded as an
|
|
# artifact for a maintainer to commit when the shards drift apart.
|
|
#
|
|
# Not a gate: nothing here blocks a merge. A red run is an issue to open.
|
|
on:
|
|
schedule:
|
|
- cron: "41 2 * * *"
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
unit:
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 45
|
|
name: unit (shuffled)
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
|
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
|
|
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
|
|
with:
|
|
node-version: 22
|
|
cache: pnpm
|
|
|
|
- run: pnpm install --frozen-lockfile
|
|
|
|
- run: pnpm db:generate
|
|
|
|
- name: Cache Playwright headless shell
|
|
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: playwright-shell-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
|
restore-keys: |
|
|
playwright-shell-${{ runner.os }}-
|
|
|
|
- run: pnpm exec playwright install --only-shell chromium
|
|
|
|
- name: Pick the seeds
|
|
run: |
|
|
echo "TEST_SEED=$(date +%s)" >> "$GITHUB_ENV"
|
|
echo "FC_SEED=$(( $(date +%s%N) % 2147483647 ))" >> "$GITHUB_ENV"
|
|
|
|
- name: Unit tests, shuffled
|
|
shell: bash
|
|
env:
|
|
# Five times each property's own case count (tests/property/fast-check.ts).
|
|
FC_RUNS_FACTOR: "5"
|
|
run: |
|
|
set -o pipefail
|
|
echo "Order seed ${TEST_SEED}, property seed ${FC_SEED}" | tee -a "$GITHUB_STEP_SUMMARY"
|
|
pnpm exec vitest run --sequence.shuffle --sequence.seed="${TEST_SEED}" \
|
|
--reporter=default --reporter=json --outputFile.json=unit-report.json
|
|
|
|
- name: Upload the timing report
|
|
if: always()
|
|
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
with:
|
|
name: nightly-unit-report
|
|
path: unit-report.json
|
|
if-no-files-found: ignore
|
|
retention-days: 14
|
|
|
|
integration:
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 45
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
shard: [1, 2, 3, 4]
|
|
name: integration shard ${{ matrix.shard }}/4 (shuffled, Postgres 16)
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
|
|
- uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
|
|
|
|
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
|
|
with:
|
|
node-version: 22
|
|
cache: pnpm
|
|
|
|
- run: pnpm install --frozen-lockfile
|
|
|
|
- run: pnpm db:generate
|
|
|
|
# One seed per run, shared by the shards through the run id, so every
|
|
# shard shuffles the same way and a failure names one seed to replay.
|
|
- name: Pick the seeds
|
|
run: |
|
|
echo "TEST_SEED=${{ github.run_id }}" >> "$GITHUB_ENV"
|
|
echo "FC_SEED=$(( ${{ github.run_id }} % 2147483647 ))" >> "$GITHUB_ENV"
|
|
|
|
- name: Integration tests, shuffled
|
|
shell: bash
|
|
env:
|
|
HEALTHLOG_INTEGRATION_WORKERS: "3"
|
|
# Pull requests run the suite on Postgres 18, the compose default.
|
|
# Installs that bring their own database may still be on 16, so the
|
|
# nightly run keeps that major covered without doubling every PR.
|
|
INTEGRATION_PG_IMAGE: "postgres:16-alpine"
|
|
# Four times each property's own case count; a property's timeout
|
|
# grows by the same factor (`propertyTimeout`).
|
|
FC_RUNS_FACTOR: "4"
|
|
# Quoted for the reason given in integration.yml.
|
|
API_TOKEN_HMAC_KEY: "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
|
|
ENCRYPTION_KEY: "0000000000000000000000000000000000000000000000000000000000000000"
|
|
SESSION_SECRET: "integration-tests"
|
|
run: |
|
|
set -o pipefail
|
|
echo "Order seed ${TEST_SEED}, property seed ${FC_SEED}" | tee -a "$GITHUB_STEP_SUMMARY"
|
|
pnpm exec vitest run --config vitest.integration.config.mts \
|
|
--shard=${{ matrix.shard }}/4 \
|
|
--sequence.shuffle --sequence.seed="${TEST_SEED}" \
|
|
--reporter=default --reporter=json \
|
|
--outputFile.json=integration-report-${{ matrix.shard }}.json
|
|
|
|
- name: Upload the timing report
|
|
if: always()
|
|
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
with:
|
|
name: nightly-integration-report-${{ matrix.shard }}
|
|
path: integration-report-${{ matrix.shard }}.json
|
|
if-no-files-found: ignore
|
|
retention-days: 14
|
|
|
|
# Merge the timings of this run into fresh timing files. Uploaded, not
|
|
# committed: the workflow has read-only access, and a maintainer decides
|
|
# whether the drift is worth a commit.
|
|
durations:
|
|
runs-on: ubuntu-24.04
|
|
needs: [unit, integration]
|
|
if: always()
|
|
timeout-minutes: 10
|
|
name: regenerate shard timings
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
|
|
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
|
|
with:
|
|
node-version: 22
|
|
|
|
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
with:
|
|
pattern: nightly-*-report*
|
|
path: reports
|
|
|
|
- name: Regenerate
|
|
shell: bash
|
|
run: |
|
|
set -o pipefail
|
|
shopt -s nullglob
|
|
integration=(reports/nightly-integration-report-*/*.json)
|
|
unit=(reports/nightly-unit-report/*.json)
|
|
if [ ${#integration[@]} -gt 0 ]; then
|
|
node scripts/test-durations.mjs integration "${integration[@]}"
|
|
fi
|
|
if [ ${#unit[@]} -gt 0 ]; then
|
|
node scripts/test-durations.mjs unit "${unit[@]}"
|
|
fi
|
|
git diff --stat -- tests/durations | tee -a "$GITHUB_STEP_SUMMARY"
|
|
|
|
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
with:
|
|
name: test-durations
|
|
path: tests/durations/*.json
|
|
retention-days: 14
|