Catch IPv6 breaking after a deploy
A few lines in your pipeline. It fails when your site's IPv6 grade drops below what you set, prints why, and retries — instead of failing — when something couldn't be checked.
url="https://aaaa.bot/check/example.com?min=C"
for i in 1 2 3 4; do
rm -f aaaa.txt
code=$(curl -sS -o aaaa.txt -w '%{http_code}' "$url") || code=000
cat aaaa.txt 2>/dev/null || true; echo
case "$code" in
200) exit 0 ;; # meets the minimum
422) exit 1 ;; # confirmed below the minimum
*) sleep 30 ;; # 503 couldn't check, 429 busy, network error: try again
esac
done
echo "IPv6 check inconclusive after 4 tries — not failing the build."
Quick version, if you don't mind a rare false alarm when a check can't complete: curl -sS --fail-with-body --retry 3 --retry-delay 30 "https://aaaa.bot/check/example.com?min=C"
What it answers
| 200 | PASS example.com: grade A (minimum C) — … |
|---|---|
| 422 | FAIL example.com: grade D (minimum C) — … plus the first fix |
| 503 | UNKNOWN … — we couldn't complete the check. The script above retries, then lets the build pass rather than blame you for our gap. |
min is the lowest grade you accept: C (the default) means "the website answers over IPv6", B allows one gap, A means website, mail and DNS all on IPv6. How grades work. Every answer links to a saved evidence record.
GitHub Actions
Save as .github/workflows/ipv6.yml and change the domain:
name: IPv6
on:
deployment_status: # after each deploy (Vercel, Netlify and others report these)
schedule:
- cron: "17 6 * * 1" # and every Monday
workflow_dispatch:
jobs:
ipv6:
if: github.event_name != 'deployment_status' || github.event.deployment_status.state == 'success'
runs-on: ubuntu-latest
steps:
- name: Check IPv6
run: |
url="https://aaaa.bot/check/example.com?min=C"
for i in 1 2 3 4; do
rm -f aaaa.txt
code=$(curl -sS -o aaaa.txt -w '%{http_code}' "$url") || code=000
cat aaaa.txt 2>/dev/null || true; echo
case "$code" in
200) exit 0 ;; # meets the minimum
422) exit 1 ;; # confirmed below the minimum
*) sleep 30 ;; # 503 couldn't check, 429 busy, network error: try again
esac
done
echo "IPv6 check inconclusive after 4 tries — not failing the build."
Checks run from aaaa.bot's server, not from your runner, so they work on any CI — GitLab, CircleCI, a cron job. The limit is 30 domain checks a minute per IP; the script retries the rare 429.
JSON
curl -s -H "accept: application/json" "https://aaaa.bot/check/example.com?min=B"
{"pass":true,"grade":"A","min":"B","status":200,"receiptId":"…","text":"PASS …"}