Skip to content

Commit af5499f

Browse files
committed
Stop the metrics check failing on its own pipe, and retry flaky pulls
Two ways CI went red on amd64 without the commit being at fault. The metrics assertions piped a Prometheus scrape into `grep -q`, which exits the instant it matches and never drains the rest. Once the scrape outgrows the pipe buffer that leaves `echo` writing into a closed pipe, and pipefail reports the EPIPE as the pipeline's status — so the check failed with the series sitting right there in the payload. Measured on Linux: clean at 82 KB, fails every time at 123 KB, and a scrape grows with every route and bucket, so it only bites once a suite is busy enough to cross the line. Both checks now use herestrings, which take the pipe out of it at any size. Only these two moved. The same `echo … | grep -q` shape appears throughout both suites, but every other payload measures well under a kilobyte — /api/sites is 316 bytes, the apex homepage 989 — so none are near the threshold, and a mechanical sweep is a good way to break a working suite for no gain. The other failure was Docker Hub answering 502 mid-`make up-auth`. Nothing to fix in the tree, but the stack pulls six images from Docker Hub anonymously, from a runner IP shared with every other public repo, so 429s and 502s will keep arriving now that this one is public. Both bring-ups retry three times with backoff, tearing down volumes in between. The retry wraps only the pull and start, never the suite, so a stack that is genuinely broken still fails three times and reports it. Worth knowing if this recurs: authenticating to Docker Hub raises the pull limit far more than retrying works around it, but that needs credentials in repo secrets, so it is left as a deliberate choice rather than assumed.
1 parent 931d516 commit af5499f

2 files changed

Lines changed: 35 additions & 4 deletions

File tree

.github/workflows/ci.yml

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,19 @@ jobs:
8383
- uses: actions/setup-go@v7
8484
with:
8585
go-version-file: go.mod
86-
- run: make up
86+
# Bringing the stack up pulls six images from Docker Hub, anonymously,
87+
# from a runner IP shared with every other public repo — so it draws
88+
# rate-limit 429s and the occasional 502 that have nothing to do with the
89+
# commit. Retry the bring-up rather than making someone re-run the job.
90+
- name: Start the stack
91+
run: |
92+
for attempt in 1 2 3; do
93+
make up && exit 0
94+
echo "::warning::stack bring-up failed (attempt $attempt/3), retrying"
95+
docker compose down -v || true
96+
sleep $((attempt * 15))
97+
done
98+
exit 1
8799
- run: make smoke
88100
- name: stack logs
89101
if: failure()
@@ -112,7 +124,17 @@ jobs:
112124
|| echo '127.0.0.1 dex.click.localhost' | sudo tee -a /etc/hosts >/dev/null
113125
fi
114126
getent hosts dex.click.localhost
115-
- run: make up-auth
127+
# Same transient-registry retry as smoke-open above; the auth overlay adds
128+
# three more images (dex, oauth2-proxy, libsql-server) to the pull.
129+
- name: Start the auth stack
130+
run: |
131+
for attempt in 1 2 3; do
132+
make up-auth && exit 0
133+
echo "::warning::auth stack bring-up failed (attempt $attempt/3), retrying"
134+
docker compose -f docker-compose.yml -f docker-compose.auth.yml down -v || true
135+
sleep $((attempt * 15))
136+
done
137+
exit 1
116138
- run: make smoke-auth
117139
- name: stack logs
118140
if: failure()

scripts/smoke.sh

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,17 @@ ok "apex requests can't spoof a site scope (header stripped by nginx)"
175175
# templates (not concrete paths), so cardinality stays in check. Runs after
176176
# the database section so /api/db/{collection} traffic exists on a fresh stack.
177177
METRICS=$(curl -fsS -H "Host: click.localhost" "$BASE/metrics")
178-
echo "$METRICS" | grep -q '^click_http_requests_total{' || fail "metrics endpoint missing HTTP RED series"
179-
echo "$METRICS" | grep -q 'route="/api/db/{collection}"' || fail "metrics route label is not a bounded template"
178+
# Herestrings, not `echo "$METRICS" | grep -q`: `grep -q` exits the instant it
179+
# matches and never drains the rest, so once a scrape outgrows the pipe buffer
180+
# `echo` is left writing into a closed pipe. pipefail reports that EPIPE as the
181+
# pipeline's status, so the check fails with the series sitting right there —
182+
# and both patterns here match near the top, which is the worst case. Measured
183+
# on Linux: clean at 82 KB, fails every time at 123 KB, and a scrape grows with
184+
# every route and bucket, so this only bites once a suite is busy enough. The
185+
# herestring takes the pipe out of it entirely, at any size. Same hazard the
186+
# header capture above sidesteps by not piping curl straight into grep.
187+
grep -q '^click_http_requests_total{' <<<"$METRICS" || fail "metrics endpoint missing HTTP RED series"
188+
grep -q 'route="/api/db/{collection}"' <<<"$METRICS" || fail "metrics route label is not a bounded template"
180189
ok "GET /metrics exposes RED metrics with bounded route templates"
181190

182191
echo "== 404 handling =="

0 commit comments

Comments
 (0)