fix(ci): make the credential scrub failure-safe, and stop the lists drifting
Round 5, and the best findings are again about the fix from round 4. The scrub only ran on success. `set -e` aborts the step when `go mod download` fails, so the cleanup line after it never executed — leaving a push-capable credential on a long-lived self-hosted runner for whatever job landed there next. It is now a `trap ... EXIT`, verified against a simulated failure. It also scrubbed the wrong file in principle: `git config --global` writes to GIT_CONFIG_GLOBAL, else $XDG_CONFIG_HOME/git/config when that exists, else ~/.gitconfig — so deleting ~/.gitconfig can scrub a path the credential was never in. The step now names GIT_CONFIG_GLOBAL itself, leaving exactly one file to remove. And the verification failed open in the case that matters most: `grep -F ""` matches every file, so a run WITHOUT the secret — a fork PR, the threat model — failed the check with a message accusing it of leaking a credential it never had. Guarded on a non-empty secret. Credentials move to an Authorization header instead of being embedded in the URL, so a password containing @ : / or # can no longer break URL parsing in a way that reads as a bad password. Two list-drift holes closed with one test that reads across languages: TestOpenAICompatProvidersAreFullyWired asserts every openAICompatProviders entry is both advertised in endpointProviderNames and has a credential arm in scripts/preflight.sh. Adding a compat provider touches three places in two languages and nothing connected them. Break-checked in both directions. Finally, a whitespace-only GADFLY_BASE_URL disagreed across the boundary: Go TrimSpaces it and takes the registry path, bash called it "set" and skipped the pre-flight, so the missing key arrived as a bare 401 with no notice. Both now agree on what unset means. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
Regular → Executable
+7
-1
@@ -27,7 +27,13 @@ gadfly_preflight_key() {
|
||||
local provider="$1" key_env="" key_hint=""
|
||||
|
||||
# Only the registry path has knowable credential rules — see above.
|
||||
if [ -n "${GADFLY_BASE_URL:-}" ]; then
|
||||
# Trim before testing: resolveModel does strings.TrimSpace on GADFLY_BASE_URL,
|
||||
# so a whitespace-only value takes the REGISTRY path there. Testing the raw
|
||||
# value here would call it "set", skip the check, and let the missing key
|
||||
# arrive as a 401 with no notice — the two must agree on what "unset" means.
|
||||
local base_url
|
||||
base_url="$(printf '%s' "${GADFLY_BASE_URL:-}" | tr -d '[:space:]')"
|
||||
if [ -n "$base_url" ]; then
|
||||
echo ""
|
||||
return 0
|
||||
fi
|
||||
|
||||
Regular → Executable
+5
@@ -79,6 +79,11 @@ done
|
||||
# GEMINI_API_KEY, so a one-name arm would skip a correctly-configured run.
|
||||
check "google w/ only GEMINI_API_KEY" "" "$(probe google GEMINI_API_KEY=k)"
|
||||
|
||||
echo "== a whitespace-only GADFLY_BASE_URL counts as unset, as it does in Go =="
|
||||
# resolveModel TrimSpaces it and takes the registry path; if this check
|
||||
# disagreed, the missing key would arrive as a bare 401 with no skip notice.
|
||||
check "qwen + blank BASE_URL" "QWEN_API_KEY" "$(probe qwen GADFLY_BASE_URL=" ")"
|
||||
|
||||
if [ "$fail" -ne 0 ]; then
|
||||
echo "RESULT: preflight table FAILED"
|
||||
exit 1
|
||||
|
||||
Reference in New Issue
Block a user