ci(.github/workflows/deploy-docs.yaml): surface bounded error code on failure, not raw body (#26917)

## What

On failure, the `deploy-docs` jobs (`algolia-and-isr` and
`vercel-rebuild`) print the HTTP status and a **bounded error code**
extracted from the response (`(.error | objects | .code)`), never the
raw response body. Comments that wrongly described the run log as
"restricted to repo collaborators" are corrected, including a
pre-existing one.

## Why

This repository is public, so GitHub Actions run logs are
world-readable. The existing design deliberately keeps free-form
upstream strings out of the public step summary via a jq allowlist.
Printing the raw response body to the run log has the same public
visibility, so it would defeat that intent. Surfacing only the bounded
error code (for example `bad_request`) is safe and enough to diagnose
failures like the deploy hook's recent HTTP 400.

## Scope and risk

- One file, `+15/-5`, success path untouched.
- Editing this workflow does not trigger it (its `push` trigger is
scoped to `docs/**`), so merging is safe.
- `actionlint` clean. The jq extraction was verified to emit only the
bounded `code`, never `message` or free-form string errors.

<details>
<summary>Context / decision log</summary>

- This started from a `vercel-rebuild` failure (HTTP 400 on every
full-rebuild trigger since 2026-06-18) whose reason was never surfaced
in CI.
- Root cause was operational: the docs site's production branch moved
from `master` to `main`, which invalidated the old deploy hook. It was
fixed separately by repointing the hook, and the workflow is green
again.
- The first revision of this PR logged the raw response body to the run
log. `coder-agents-review` (CRF-1, P2) correctly flagged that
public-repo run logs are world-readable, so that would leak the
free-form strings the allowlist exists to suppress. Revised to surface
only the bounded error code, and to correct the false "restricted to
repo collaborators" comments (CRF-2 nit: comment blocks shortened).

</details>

---
Generated by Coder Agents on behalf of @nickvigilante.
This commit is contained in:
Nick Vigilante
2026-07-20 21:34:36 +00:00
committed by GitHub
parent d0be387194
commit 68344a0973
+23 -5
View File
@@ -429,9 +429,9 @@ jobs:
# recordsByType) that may reflect upstream error strings. This
# repository is public, so the step summary is visible to
# anyone with read access; filter those fields out before the
# summary is written. The full response remains in the curl
# output captured in the workflow logs, which are restricted
# to repo collaborators.
# summary is written. The full response stays in a temp file and
# is never printed: run logs are public for this repository, so
# the raw body must not reach them either.
#
# Keep this allowlist in sync with SyncResponseBody in
# coder/coder.com/src/pages/api/algolia-docs-sync.ts; add a
@@ -475,10 +475,19 @@ jobs:
echo
echo "### Error"
echo
echo "The request failed. See the workflow logs for the full handler response; the step summary suppresses free-form error strings because this repository is public."
echo "The request failed. The raw response body is not shown because this repository is public; only the allowlisted fields above and the bounded error code (in the run log) are surfaced."
fi
} >> "$GITHUB_STEP_SUMMARY"
if [ "$RC" -ne 0 ]; then
# This repository is public: run logs and the step summary are
# both world-readable, so surface only the bounded error code,
# never the raw response body. Sanitize the extracted code so the
# "bounded" claim holds literally: `tr -cd` drops anything outside
# [A-Za-z0-9_.-] (removing newlines and `::` so a hostile response
# body can't inject a runner workflow command) and `head -c 64`
# caps the length.
ERR_CODE=$(jq -r '(.error | objects | .code) // empty' "$RESPONSE" 2>/dev/null | tr -cd 'A-Za-z0-9_.-' | head -c 64 || true)
echo "Algolia docs sync request failed: HTTP ${HTTP_STATUS:-n/a}, error code: ${ERR_CODE:-unknown}."
exit "$RC"
fi
@@ -540,9 +549,18 @@ jobs:
echo
echo "### Error"
echo
echo "The request failed. See the workflow logs for the full hook response; the step summary suppresses free-form error strings because this repository is public."
echo "The request failed. The raw response body is not shown because this repository is public; only the allowlisted fields above and the bounded error code (in the run log) are surfaced."
fi
} >> "$GITHUB_STEP_SUMMARY"
if [ "$RC" -ne 0 ]; then
# This repository is public: run logs and the step summary are
# both world-readable, so surface only the bounded error code,
# never the raw response body. Sanitize the extracted code so the
# "bounded" claim holds literally: `tr -cd` drops anything outside
# [A-Za-z0-9_.-] (removing newlines and `::` so a hostile response
# body can't inject a runner workflow command) and `head -c 64`
# caps the length.
ERR_CODE=$(jq -r '(.error | objects | .code) // empty' "$RESPONSE" 2>/dev/null | tr -cd 'A-Za-z0-9_.-' | head -c 64 || true)
echo "Vercel deploy hook request failed: HTTP ${HTTP_STATUS:-n/a}, error code: ${ERR_CODE:-unknown}."
exit "$RC"
fi