The first version died on 'curl: command not found' — the runner image carries python3 and git and nothing else on purpose. Reaching for a bigger image to send one HTTP request would have been the wrong trade, so the step uses urllib. Verified from the image itself that HTTPS to api.resend.com resolves and the certificate verifies. The step also fails LOUDLY on an empty key or a non-2xx from Resend: a silent alarm is worse than no alarm, because it reads as coverage.
This commit is contained in:
+27
-11
@@ -42,19 +42,30 @@ jobs:
|
|||||||
# THE POINT OF THE WHOLE THING. Probe P5 measured that a failed run produces NO mail, NO
|
# THE POINT OF THE WHOLE THING. Probe P5 measured that a failed run produces NO mail, NO
|
||||||
# notification row and NO log line from Gitea itself — a red tick in a web UI nobody watches
|
# notification row and NO log line from Gitea itself — a red tick in a web UI nobody watches
|
||||||
# is exactly the shape R-29 filed against. So the run sends its own alarm, on the project's
|
# is exactly the shape R-29 filed against. So the run sends its own alarm, on the project's
|
||||||
# existing transactional path (Resend, the same one the hub uses), and it prints the
|
# existing transactional path (Resend, the same one the hub uses), and prints the provider's
|
||||||
# provider's accepted id so "it was sent" is an observable rather than an assumption.
|
# accepted id so "a message left the machine" is an observable, not an assumption.
|
||||||
|
#
|
||||||
|
# Pure python3 and urllib, NOT curl: the runner image carries python3 and git and nothing
|
||||||
|
# else on purpose, and the first version of this step died on `curl: command not found`.
|
||||||
|
# Reaching for a bigger image to send one HTTP request would have been the wrong trade.
|
||||||
if: failure()
|
if: failure()
|
||||||
env:
|
env:
|
||||||
RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }}
|
RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }}
|
||||||
run: |
|
run: |
|
||||||
python3 - > payload.json <<'PY'
|
python3 - <<'PY'
|
||||||
import json, os
|
import json, os, sys, urllib.request, urllib.error
|
||||||
|
|
||||||
|
key = os.environ.get("RESEND_API_KEY", "")
|
||||||
|
if not key:
|
||||||
|
sys.exit("ALARM FAILED: RESEND_API_KEY is empty — the alarm cannot be sent, and a "
|
||||||
|
"silent alarm is worse than none. Set the user-level Actions secret.")
|
||||||
|
|
||||||
repo = os.environ.get("GITHUB_REPOSITORY", "?")
|
repo = os.environ.get("GITHUB_REPOSITORY", "?")
|
||||||
sha = os.environ.get("GITHUB_SHA", "?")
|
sha = os.environ.get("GITHUB_SHA", "?")
|
||||||
run = os.environ.get("GITHUB_RUN_NUMBER", "?")
|
run = os.environ.get("GITHUB_RUN_NUMBER", "?")
|
||||||
srv = os.environ.get("GITHUB_SERVER_URL", "https://gitea.dooplex.hu")
|
srv = os.environ.get("GITHUB_SERVER_URL", "https://gitea.dooplex.hu")
|
||||||
print(json.dumps({
|
|
||||||
|
body = json.dumps({
|
||||||
"from": "Felhom CI <monitoring@felhom.eu>",
|
"from": "Felhom CI <monitoring@felhom.eu>",
|
||||||
"to": ["admin@felhom.eu"],
|
"to": ["admin@felhom.eu"],
|
||||||
"subject": "[felhom CI] gates FAILED in %s" % repo,
|
"subject": "[felhom CI] gates FAILED in %s" % repo,
|
||||||
@@ -68,10 +79,15 @@ jobs:
|
|||||||
"disagree - that is a finding about the gates themselves, not about CI, and it\n"
|
"disagree - that is a finding about the gates themselves, not about CI, and it\n"
|
||||||
"outranks whatever the push was for.\n"
|
"outranks whatever the push was for.\n"
|
||||||
) % (repo, sha, srv, repo, run),
|
) % (repo, sha, srv, repo, run),
|
||||||
}))
|
}).encode()
|
||||||
|
|
||||||
|
req = urllib.request.Request(
|
||||||
|
"https://api.resend.com/emails", data=body, method="POST",
|
||||||
|
headers={"Authorization": "Bearer %s" % key,
|
||||||
|
"Content-Type": "application/json"})
|
||||||
|
try:
|
||||||
|
with urllib.request.urlopen(req, timeout=30) as r:
|
||||||
|
print("RESEND-ACCEPTED id=%s" % json.load(r)["id"])
|
||||||
|
except urllib.error.HTTPError as e:
|
||||||
|
sys.exit("ALARM FAILED: Resend returned HTTP %s: %s" % (e.code, e.read().decode()[:300]))
|
||||||
PY
|
PY
|
||||||
curl -sS --fail-with-body -X POST https://api.resend.com/emails \
|
|
||||||
-H "Authorization: Bearer $RESEND_API_KEY" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
--data @payload.json > resend-response.json
|
|
||||||
python3 -c "import json;print('RESEND-ACCEPTED id=%s' % json.load(open('resend-response.json'))['id'])"
|
|
||||||
|
|||||||
Reference in New Issue
Block a user