-
Notifications
You must be signed in to change notification settings - Fork 0
108 lines (103 loc) · 4.89 KB
/
Copy pathcheck.yml
File metadata and controls
108 lines (103 loc) · 4.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
name: Test and container smoke check
on: [push, pull_request]
permissions:
contents: read
jobs:
verify:
runs-on: ubuntu-latest
# GUESS: UNCALIBRATED GUESS — CI timeout, not application performance.
timeout-minutes: 20
steps:
# SOURCE: actions/checkout v4 commit resolved from the official repository.
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
- name: Build app and run unit tests inside Docker
run: docker build -t pattern-forge:test .
- name: Check the running container and error contract
shell: bash
run: |
set -euo pipefail
# SOURCE: use the app's default port only on the CI runner loopback.
docker run -d --name pattern-forge-test -p 127.0.0.1:3000:3000 pattern-forge:test
trap 'docker logs pattern-forge-test; docker rm -f pattern-forge-test' EXIT
# GUESS: UNCALIBRATED GUESS — bounded startup retry budget for the CI runner.
# SOURCE: Docker can accept a connection before Node is listening, causing curl exit 56.
curl --retry 10 --retry-all-errors --retry-delay 1 --fail http://127.0.0.1:3000/api/health
curl --fail --output /tmp/pattern-forge-page.html http://127.0.0.1:3000/
grep -q 'Pattern Forge' /tmp/pattern-forge-page.html
test "$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3000/api/markets/INVALID)" = 400
test "$(docker exec pattern-forge-test id -u)" != 0
# Without a database the stored reader must say so, not appear healthy.
test "$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3000/api/stored/BTC)" = 503
persistence:
runs-on: ubuntu-latest
# GUESS: UNCALIBRATED GUESS — CI timeout, not application performance.
timeout-minutes: 20
services:
postgres:
image: postgres:18-alpine
env:
POSTGRES_DB: patternforge
POSTGRES_USER: patternforge
# CI-only credential for an ephemeral service container.
POSTGRES_PASSWORD: patternforge
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U patternforge -d patternforge"
--health-interval 5s
--health-timeout 5s
--health-retries 12
env:
DATABASE_URL: postgresql://patternforge:patternforge@127.0.0.1:5432/patternforge
# SOURCE: the fixed instant the recorded payload is validated against.
# See ingest/fixtures/build_fixture.py.
FIXTURE_NOW_MS: "1788220800000"
# SOURCE: 48 of the 50 recorded BTC hourly rows are closed and unique.
EXPECTED_HOURLY: "48"
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
# SOURCE: actions/setup-python v5 and actions/setup-node v4 pinned by commit.
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: "3.13"
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
with:
node-version: "24"
- name: Install dependencies
run: |
python -m pip install --disable-pip-version-check -r ingest/requirements.txt
npm ci
- name: The recorded fixture is the committed one
run: |
python -m ingest.fixtures.build_fixture
git diff --exit-code -- ingest/fixtures/public-candles.json
- name: Python validation and ingestion failure tests
run: python -m unittest ingest.tests.test_candles ingest.tests.test_ingest -v
- name: Ingest, repeat and confirm the stored rows
run: python -m unittest ingest.tests.test_persistence -v
- name: Load the fixture in one process, then read it back in another
shell: bash
run: |
set -euo pipefail
python -m ingest.ingest \
--fixture ingest/fixtures/public-candles.json \
--now "$FIXTURE_NOW_MS" --symbols BTC --intervals 1h --show-stored
# A second pass must not grow the table: the primary key is the guard.
python -m ingest.ingest \
--fixture ingest/fixtures/public-candles.json \
--now "$FIXTURE_NOW_MS" --symbols BTC --intervals 1h
# This process never saw the ingester, so the rows can only come from PostgreSQL.
node scripts/check_persistence.mjs "$EXPECTED_HOURLY"
- name: Restart the database and replay what survived
shell: bash
run: |
set -euo pipefail
container="$(docker ps --filter ancestor=postgres:18-alpine --format '{{.ID}}' | head -n 1)"
test -n "$container"
docker restart "$container"
# GUESS: UNCALIBRATED GUESS — bounded wait for the restarted server.
for attempt in $(seq 1 30); do
if docker exec "$container" pg_isready -U patternforge -d patternforge; then break; fi
sleep 2
done
node scripts/check_persistence.mjs "$EXPECTED_HOURLY"