fix(ci): the settings token could NEVER have been stored -- Gitea reserves the GITEA_ prefix
The drift detector merged in #11 was inert and would have stayed inert silently. WHAT HAPPENED. infra/gitea/set-ci-token.sh minted a token and PUT it to the repo Actions secret GITEA_SETTINGS_TOKEN. Gitea RESERVES the `GITEA_` prefix for secret names -- exactly as GitHub reserves `GITHUB_` -- and rejects that PUT with: HTTP 400 {"message":"invalid secret name"} The script sent the PUT to /dev/null and printed "==> stored." unconditionally, and `curl -sS` exits 0 on an HTTP error, so it reported success for a store that never happened. Measured afterwards: the token existed in the user's token list, and the repo's secret list was EMPTY. ci/gitea-settings.sh would have skipped on every CI run forever, and with REQUIRE_GITEA_SETTINGS=true it would instead have BLOCKED EVERY PR -- including the one fixing it. Three changes: * the secret is SETTINGS_API_TOKEN; ci/gitea-settings.sh reads it, keeping GITEA_SETTINGS_TOKEN as a local-run fallback; * set-ci-token.sh checks the PUT's HTTP status AND reads the secret back, refusing to claim success otherwise. That missing verification is the actual defect -- the wrong name was just what it hid; * gate.yml maps the secret and ENABLES REQUIRE_GITEA_SETTINGS. WHY ENABLING IT HERE IS SAFE: this PR's own CI run is the proof. If the stage were still skipping, REQUIRE turns that into a failure and this PR goes RED rather than merging. Green means the token resolved and live Gitea matched infra/gitea/expected-branch-protection.json. Verified locally before pushing: REQUIRE=true, token present -> MERGE GATE: PASS REQUIRE=true, no token -> gitea-settings SKIPPED -> BLOCKED (not a silent skip) The secret is already stored and read back as present, so CI has what it needs. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
4634b44cc7
commit
50a48e6f07
3 files changed
+35
-8
No files matched your search
@@ -10,6 +10,10 @@
|
||||
# confirm the check goes green rather than assuming the scope name.
|
||||
set -euo pipefail
|
||||
HOST=gitea.home.keithjackson.dev; OWNER=Home-Network; REPO=home-network-k3s-impl
|
||||
# NOT GITEA_* — Gitea reserves that prefix for secret names and returns HTTP 400
|
||||
# "invalid secret name". The first version of this script used GITEA_SETTINGS_TOKEN, sent the
|
||||
# PUT to /dev/null, and printed "stored" regardless; the secret never existed and nobody knew.
|
||||
SECRET=SETTINGS_API_TOKEN
|
||||
NAME="ci-gitea-settings-$(date +%Y%m%d%H%M%S)"
|
||||
creds="$(printf 'protocol=https\nhost=%s\n\n' "$HOST" | git credential fill)"
|
||||
U="$(sed -n 's/^username=//p' <<<"$creds")"; P="$(sed -n 's/^password=//p' <<<"$creds")"
|
||||
@@ -22,12 +26,24 @@ TOKEN="$(basic -X POST -H 'Content-Type: application/json' \
|
||||
[ -n "$TOKEN" ] || { echo "token creation failed (check scopes for your Gitea version)" >&2; exit 1; }
|
||||
echo "==> got a ${#TOKEN}-character token (value not shown)"
|
||||
|
||||
echo "==> storing it as repo Actions secret GITEA_SETTINGS_TOKEN"
|
||||
basic -X PUT -H 'Content-Type: application/json' \
|
||||
echo "==> storing it as repo Actions secret ${SECRET}"
|
||||
code="$(basic -o /tmp/set-ci-token.out -w '%{http_code}' -X PUT -H 'Content-Type: application/json' \
|
||||
-d "$(jq -n --arg d "$TOKEN" '{data:$d}')" \
|
||||
"https://${HOST}/api/v1/repos/${OWNER}/${REPO}/actions/secrets/GITEA_SETTINGS_TOKEN" >/dev/null
|
||||
"https://${HOST}/api/v1/repos/${OWNER}/${REPO}/actions/secrets/${SECRET}")"
|
||||
unset TOKEN
|
||||
echo "==> stored."
|
||||
if [ "$code" != 201 ] && [ "$code" != 204 ]; then
|
||||
echo " PUT failed: HTTP ${code} -- $(head -c 200 /tmp/set-ci-token.out)" >&2
|
||||
rm -f /tmp/set-ci-token.out; exit 1
|
||||
fi
|
||||
rm -f /tmp/set-ci-token.out
|
||||
|
||||
# VERIFY BY READING IT BACK. curl -sS exits 0 on an HTTP error, so without this the script
|
||||
# reports success for a store that never happened -- which is exactly what it did.
|
||||
names="$(basic "https://${HOST}/api/v1/repos/${OWNER}/${REPO}/actions/secrets" \
|
||||
| jq -rc '[.. | objects | select(has("name")) | .name] | unique')"
|
||||
grep -q "$SECRET" <<<"$names" \
|
||||
|| { echo " stored HTTP ${code} but ${SECRET} is NOT in ${names} -- refusing to claim success" >&2; exit 1; }
|
||||
echo "==> stored and VERIFIED present: ${names}"
|
||||
|
||||
cat <<'NOTE'
|
||||
|
||||
|
||||
Reference in new issue
Block a user