Skip to content

Commit 67b9173

Browse files
committed
add reusable smoke-e2e script and ignore local smoke artifacts
1 parent 8d97e5b commit 67b9173

3 files changed

Lines changed: 138 additions & 34 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -31,38 +31,6 @@ jobs:
3131
- name: Build Docs
3232
run: npm run build:docs
3333

34-
- name: Seed Sample Data
35-
run: npm run db:seed
36-
37-
- name: Smoke Start Server And Webhook Route
34+
- name: Smoke E2E
3835
shell: bash
39-
run: |
40-
set -euo pipefail
41-
npm start > server.log 2>&1 &
42-
SERVER_PID=$!
43-
44-
cleanup() {
45-
if kill -0 "$SERVER_PID" 2>/dev/null; then
46-
kill "$SERVER_PID" 2>/dev/null || true
47-
wait "$SERVER_PID" 2>/dev/null || true
48-
fi
49-
cat server.log
50-
}
51-
trap cleanup EXIT
52-
53-
for _ in {1..30}; do
54-
if curl -sf "http://localhost:3000/api" >/dev/null; then
55-
break
56-
fi
57-
sleep 1
58-
done
59-
60-
curl -sf "http://localhost:3000/api" >/dev/null
61-
62-
webhook_response="$(curl -s -o /tmp/webhook.out -w "%{http_code}" \
63-
-X POST "http://localhost:3000/webhook/sample/01J0Z8X3GWBD9117Q9H4M2KCFP" \
64-
-H "Content-Type: application/json" \
65-
--data-raw '{"name":"CI Alert","timestamp":"2026-03-28T10:00:00Z","host":"ci-host","description":"smoke"}')"
66-
67-
test "$webhook_response" = "200"
68-
grep -q "Picked up by Herald at the Gate" /tmp/webhook.out
36+
run: bash scripts/smoke-e2e.sh

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ node_modules
66
.vscode
77
.site
88

9+
# Local smoke-test artifacts
10+
server.out.log
11+
server.err.log
12+
webhook.out
13+

scripts/smoke-e2e.sh

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
BASE_URL="${BASE_URL:-http://localhost:3000}"
5+
SAMPLE_ROUTE_PATH="${SAMPLE_ROUTE_PATH:-/webhook/sample/01J0Z8X3GWBD9117Q9H4M2KCFP}"
6+
UNKNOWN_ROUTE_PATH="${UNKNOWN_ROUTE_PATH:-/webhook/sample/not-configured}"
7+
START_SERVER="${START_SERVER:-1}"
8+
SEED_SAMPLE_DATA="${SEED_SAMPLE_DATA:-1}"
9+
STARTUP_TIMEOUT_SEC="${STARTUP_TIMEOUT_SEC:-30}"
10+
11+
PASS_COUNT=0
12+
FAIL_COUNT=0
13+
SERVER_PID=""
14+
SERVER_LOG_FILE="/tmp/gateherald-smoke-server.log"
15+
16+
pass() {
17+
echo "PASS: $1"
18+
PASS_COUNT=$((PASS_COUNT + 1))
19+
}
20+
21+
fail() {
22+
echo "FAIL: $1"
23+
FAIL_COUNT=$((FAIL_COUNT + 1))
24+
}
25+
26+
cleanup() {
27+
if [ -n "$SERVER_PID" ] && kill -0 "$SERVER_PID" 2>/dev/null; then
28+
kill "$SERVER_PID" 2>/dev/null || true
29+
wait "$SERVER_PID" 2>/dev/null || true
30+
fi
31+
}
32+
33+
trap cleanup EXIT
34+
35+
echo "Running Gateherald smoke E2E against $BASE_URL"
36+
37+
if [ "$SEED_SAMPLE_DATA" = "1" ]; then
38+
echo "Seeding sample data..."
39+
npm run db:seed >/tmp/gateherald-smoke-seed.log 2>&1
40+
fi
41+
42+
if [ "$START_SERVER" = "1" ]; then
43+
echo "Starting server..."
44+
npm start >"$SERVER_LOG_FILE" 2>&1 &
45+
SERVER_PID=$!
46+
47+
started=0
48+
for _ in $(seq 1 "$STARTUP_TIMEOUT_SEC"); do
49+
if curl -sf "$BASE_URL/api" >/dev/null; then
50+
started=1
51+
break
52+
fi
53+
sleep 1
54+
done
55+
56+
if [ "$started" -ne 1 ]; then
57+
echo "Server failed to become ready in ${STARTUP_TIMEOUT_SEC}s"
58+
if [ -f "$SERVER_LOG_FILE" ]; then
59+
echo "--- server log ---"
60+
cat "$SERVER_LOG_FILE"
61+
echo "--- end server log ---"
62+
fi
63+
exit 1
64+
fi
65+
fi
66+
67+
check_http() {
68+
local label="$1"
69+
local expected_code="$2"
70+
local method="$3"
71+
local url="$4"
72+
local body="${5:-}"
73+
74+
local output_file
75+
output_file="$(mktemp)"
76+
local code
77+
78+
if [ -n "$body" ]; then
79+
code="$(curl -s -o "$output_file" -w "%{http_code}" -X "$method" "$url" -H "Content-Type: application/json" --data-raw "$body")"
80+
else
81+
code="$(curl -s -o "$output_file" -w "%{http_code}" -X "$method" "$url")"
82+
fi
83+
84+
if [ "$code" = "$expected_code" ]; then
85+
pass "$label (HTTP $code)"
86+
else
87+
echo " URL: $url"
88+
echo " Expected: $expected_code"
89+
echo " Actual: $code"
90+
echo " Body:"
91+
sed 's/^/ /' "$output_file"
92+
fail "$label"
93+
fi
94+
95+
LAST_OUTPUT_FILE="$output_file"
96+
}
97+
98+
check_http "Health endpoint" "200" "GET" "$BASE_URL/api"
99+
rm -f "$LAST_OUTPUT_FILE"
100+
101+
sample_payload='{"name":"CI Alert","timestamp":"2026-03-28T10:00:00Z","host":"ci-host","description":"smoke"}'
102+
check_http "Webhook configured route" "200" "POST" "$BASE_URL$SAMPLE_ROUTE_PATH" "$sample_payload"
103+
if grep -q "Picked up by Herald at the Gate" "$LAST_OUTPUT_FILE"; then
104+
pass "Configured route response body"
105+
else
106+
echo " Expected response to include: Picked up by Herald at the Gate"
107+
echo " Actual body:"
108+
sed 's/^/ /' "$LAST_OUTPUT_FILE"
109+
fail "Configured route response body"
110+
fi
111+
rm -f "$LAST_OUTPUT_FILE"
112+
113+
check_http "Webhook unknown route" "404" "POST" "$BASE_URL$UNKNOWN_ROUTE_PATH" '{"x":1}'
114+
if grep -Eq "Route not configured|Cannot POST" "$LAST_OUTPUT_FILE"; then
115+
pass "Unknown route response body"
116+
else
117+
echo " Expected 404 body to include route error text"
118+
echo " Actual body:"
119+
sed 's/^/ /' "$LAST_OUTPUT_FILE"
120+
fail "Unknown route response body"
121+
fi
122+
rm -f "$LAST_OUTPUT_FILE"
123+
124+
echo
125+
echo "Summary: $PASS_COUNT passed, $FAIL_COUNT failed"
126+
127+
if [ "$FAIL_COUNT" -gt 0 ]; then
128+
exit 1
129+
fi
130+
131+
exit 0

0 commit comments

Comments
 (0)