Add Bump.sh proxy to preview API docs links in cloud-docs PRs#638
Add Bump.sh proxy to preview API docs links in cloud-docs PRs#638kbatuigas wants to merge 1 commit into
Conversation
The API reference is served at /api/doc/... by a Netlify edge function that proxies to Bump.sh. That proxy exists in the docs and docs-site repos but not in cloud-docs, so link:/api/doc/... links 404 in rp-cloud deploy previews (they resolve fine on production, which is built by docs-site). Mirror redpanda-data/docs#1552: add netlify.toml registering the /api/* edge function and the proxy-api-docs.js function (copied verbatim from docs main, includes the docs-site#182 cache-poisoning fix). Requires BUMP_PROXY_SECRET to be set on the rp-cloud Netlify site. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
✅ Deploy Preview for rp-cloud ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughAdds Netlify configuration for Node.js 22, local documentation publishing, and Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant NetlifyEdgeFunction
participant Bump.sh
participant WidgetEndpoints
Client->>NetlifyEdgeFunction: Request API documentation
NetlifyEdgeFunction->>Bump.sh: Fetch rewritten documentation URL
Bump.sh-->>NetlifyEdgeFunction: Return documentation response
NetlifyEdgeFunction->>WidgetEndpoints: Fetch HTML widget fragments
WidgetEndpoints-->>NetlifyEdgeFunction: Return widget HTML
NetlifyEdgeFunction-->>Client: Return transformed or non-HTML response
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@netlify.toml`:
- Around line 9-11: Update the [[edge_functions]] configuration for the
proxy-api-docs function to include cache = "manual", enabling its response
caching behavior and allowing the configured Cache-Control and Netlify-Vary
headers to take effect.
In `@netlify/edge-functions/proxy-api-docs.js`:
- Around line 84-88: Update fetchWithRetry to retry HTTP 429 and 5xx responses,
applying the existing retry limits and delay behavior while continuing to retry
network exceptions. In the caller’s non-successful response handling, preserve
non-retryable upstream statuses such as 404 instead of throwing an error path
that maps them to 503; return or propagate the original response status and body
as appropriate.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5597b832-9de0-4742-88f3-ee1929729fb8
📒 Files selected for processing (2)
netlify.tomlnetlify/edge-functions/proxy-api-docs.js
| [[edge_functions]] | ||
| path = "/api/*" | ||
| function = "proxy-api-docs" |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Does Netlify Edge Function response caching require cache = "manual" when Cache-Control and Netlify-Vary headers are returned?
💡 Result:
Yes, configuring an Edge Function for caching requires explicitly opting in by setting the cache property to manual [1][2]. Netlify Edge Function responses are not cached by default because they are dynamic [3][4]. Simply returning Cache-Control or Netlify-Vary headers in your function response is insufficient on its own; if the cache property is not set to manual (either inline in the function code or via netlify.toml), the function will continue to execute on every request, and the cache headers will not be honored for edge caching [1][2]. To enable caching for your Edge Function, you must complete both of these steps [2]: 1. Opt in to caching by setting cache = "manual" in your function declaration [1][5]. 2. Customize the caching behavior by including appropriate HTTP headers (such as Cache-Control or Netlify-Vary) in your response [1][3]. If you perform only one of these actions, the responses will not be cached by the edge [2]. Once cache = "manual" is configured, Netlify will respect the Cache-Control and Netlify-Vary headers you return to manage how the response is cached and how cache keys are generated [1][3].
Citations:
- 1: https://docs.netlify.com/build/edge-functions/optional-configuration/
- 2: https://answers.netlify.com/t/cache-in-edge-functions-not-working/95121
- 3: https://docs.netlify.com/build/caching/caching-overview/
- 4: https://docs.netlify.com/build/caching/caching-overview
- 5: https://docs.netlify.com/build/edge-functions/declarations/
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Repo root: '; pwd
echo '--- netlify.toml ---'
nl -ba netlify.toml | sed -n '1,80p'
echo '--- edge function files ---'
fd -a 'proxy-api-docs' .
echo '--- search for caching headers/config ---'
rg -n --hidden --glob '!**/.git/**' 'cache\s*=\s*"manual"|Cache-Control|Netlify-Vary|edge_functions|proxy-api-docs' .Repository: redpanda-data/cloud-docs
Length of output: 253
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- locate netlify.toml ---'
fd -a '^netlify\.toml$' .
echo '--- netlify.toml with line numbers ---'
sed -n '1,80p' netlify.toml | cat -n
echo '--- locate proxy-api-docs implementation ---'
fd -a 'proxy-api-docs' .
echo '--- search for caching-related headers and edge function config ---'
rg -n --hidden --glob '!**/.git/**' 'cache\s*=\s*"manual"|Cache-Control|Netlify-Vary|edge_functions|proxy-api-docs' .Repository: redpanda-data/cloud-docs
Length of output: 914
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- proxy-api-docs.js outline ---'
ast-grep outline netlify/edge-functions/proxy-api-docs.js --view expanded
echo '--- proxy-api-docs.js relevant lines ---'
sed -n '1,220p' netlify/edge-functions/proxy-api-docs.js | cat -nRepository: redpanda-data/cloud-docs
Length of output: 10050
Opt this Edge Function into response caching. Add cache = "manual" to netlify.toml:9-11; otherwise the proxy still runs on every request and the Cache-Control / Netlify-Vary headers won’t take effect.
Proposed fix
[[edge_functions]]
path = "/api/*"
function = "proxy-api-docs"
+cache = "manual"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| [[edge_functions]] | |
| path = "/api/*" | |
| function = "proxy-api-docs" | |
| [[edge_functions]] | |
| path = "/api/*" | |
| function = "proxy-api-docs" | |
| cache = "manual" |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@netlify.toml` around lines 9 - 11, Update the [[edge_functions]]
configuration for the proxy-api-docs function to include cache = "manual",
enabling its response caching behavior and allowing the configured Cache-Control
and Netlify-Vary headers to take effect.
| // Handle non-successful responses | ||
| if (!bumpRes.ok) { | ||
| console.error(`❌ Bump.sh returned ${bumpRes.status}: ${bumpRes.statusText}`); | ||
| throw new Error(`Bump.sh API error: ${bumpRes.status}`); | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Retry transient HTTP failures without converting every upstream error to 503.
fetchWithRetry retries only network exceptions, so HTTP 429/5xx responses return immediately. The caller then throws for every non-2xx response, causing permanent statuses such as 404 to be reported as 503. Retry 429/5xx inside the helper and preserve non-retryable upstream statuses.
Proposed approach
- if (!bumpRes.ok) {
+ if (!bumpRes.ok && bumpRes.status >= 400 && bumpRes.status < 500) {
console.error(`❌ Bump.sh returned ${bumpRes.status}: ${bumpRes.statusText}`);
- throw new Error(`Bump.sh API error: ${bumpRes.status}`);
+ return bumpRes;
} const response = await fetch(url, {
...options,
signal: AbortSignal.timeout(10000),
});
- return response;
+
+ const retryable = response.status === 429 || response.status >= 500;
+ if (!retryable || attempt === maxRetries) {
+ return response;
+ }
+
+ await response.body?.cancel();Also applies to: 275-294
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@netlify/edge-functions/proxy-api-docs.js` around lines 84 - 88, Update
fetchWithRetry to retry HTTP 429 and 5xx responses, applying the existing retry
limits and delay behavior while continuing to retry network exceptions. In the
caller’s non-successful response handling, preserve non-retryable upstream
statuses such as 404 instead of throwing an error path that maps them to 503;
return or propagate the original response status and body as appropriate.
Description
link:/api/doc/...API reference links 404 inrp-clouddeploy previews. The/api/doc/...reference is the Bump.sh-hosted API docs, served by a Netlify edge function that proxies/api/*→ Bump.sh. That proxy lives in thedocsanddocs-siterepos but not in cloud-docs (which had nonetlify.toml), so the links only resolve on production (built bydocs-site), not in cloud-docs previews. The link syntax itself is already correct.This mirrors
redpanda-data/docs#1552("Add the Bump proxy for previewing API docs in PRs"):netlify.toml— registers the/api/*edge function (identical todocsmain).netlify/edge-functions/proxy-api-docs.js— copied verbatim fromdocsmain (includes thedocs-site#182cache-poisoning fix).Validated on
docsPR #1786's preview (branch that includes the same proxy):/api/doc/cloud-controlplane/authenticationand/api/doc/admin/operation/operation-get_cluster_health_overviewboth return 200.BUMP_PROXY_SECRETmust be set on therp-cloudNetlify site (same value as thedocs/docs-sitesites). Without it the edge function returns 503. This is a Netlify dashboard step, not a repo change.How to verify
Once the deploy preview builds and the secret is set, these should return 200 (not 404/503):
https://deploy-preview-<PR>--rp-cloud.netlify.app/api/doc/cloud-controlplane/authenticationhttps://deploy-preview-<PR>--rp-cloud.netlify.app/api/doc/cloud-controlplane/operation/operation-clusterservice_createclusterNo production impact:
docs.redpanda.comis built bydocs-site, which has its own proxy; thisnetlify.tomlonly affects therp-cloudsite.Checks
🤖 Generated with Claude Code