Skip to content

Conversation

@JakeSCahill
Copy link
Contributor

Description

Allows us to preview API docs in preview builds by adding the proxy for Bump.sh.

Page previews

Checks

  • New feature
  • Content gap
  • Support Follow-up
  • Small fix (typos, links, copyedits, etc)

@JakeSCahill JakeSCahill requested a review from a team as a code owner January 20, 2026 09:12
@netlify
Copy link

netlify bot commented Jan 20, 2026

Deploy Preview for redpanda-docs-preview ready!

Name Link
🔨 Latest commit 7ba6716
🔍 Latest deploy log https://app.netlify.com/projects/redpanda-docs-preview/deploys/696f6887b3f6c30008305191
😎 Deploy Preview https://deploy-preview-1552--redpanda-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 20, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This pull request introduces Netlify infrastructure for API documentation proxying. It adds a Netlify configuration file that specifies Node 24 runtime, sets the documentation directory as the publishing path, and defines an edge function mapping. A new edge function is added that proxies API documentation requests through bump.sh, applies path-based theming, injects custom widgets (head script, header, footer), handles request redirects, includes resilient fetching with exponential backoff, and provides graceful error handling with fallback responses.

Sequence Diagram

sequenceDiagram
    participant Client
    participant EdgeFunc as Edge Function<br/>(proxy-api-docs)
    participant BumpSh as bump.sh
    participant WidgetSrc as Widget Sources
    
    Client->>EdgeFunc: Request /api/v1/docs
    
    EdgeFunc->>EdgeFunc: Normalize path & check<br/>for legacy redirects
    alt Legacy Route Detected
        EdgeFunc-->>Client: 301 Redirect to<br/>new path
    else Current Route
        EdgeFunc->>EdgeFunc: Map path to<br/>header color
        EdgeFunc->>BumpSh: Fetch documentation<br/>with retry logic
        
        alt Non-HTML Response
            BumpSh-->>EdgeFunc: Return raw content
            EdgeFunc-->>Client: Raw response
        else HTML Response
            BumpSh-->>EdgeFunc: HTML content
            EdgeFunc->>WidgetSrc: Fetch head widget<br/>with retry
            EdgeFunc->>WidgetSrc: Fetch header widget<br/>with retry
            EdgeFunc->>WidgetSrc: Fetch footer widget<br/>with retry
            
            EdgeFunc->>EdgeFunc: Parse HTML &<br/>inject widgets
            EdgeFunc-->>Client: Modified HTML<br/>with caching headers
        end
    end
    
    alt Fetch/Processing Error
        EdgeFunc-->>Client: 503 Error Page<br/>(graceful fallback)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • Feediver1
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive The description covers the main purpose but is missing critical template sections: no JIRA ticket link, no review deadline, and no page preview links or checks selected. Add the JIRA ticket resolution link, review deadline, actual page preview URLs, and select at least one checkbox to classify the change type.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding a Bump proxy for API docs preview functionality in PRs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@netlify/edge-functions/proxy-api-docs.js`:
- Around line 7-24: The redirect logic currently drops query parameters; update
the redirect branch that checks redirects[normalizedPath] to append the original
request's url.search (e.g., url.search) to the target path when calling
Response.redirect so query string and anchors are preserved; modify the redirect
call that uses Response.redirect(`${url.origin}${redirects[normalizedPath]}`,
301) to include url.search (and ensure you don't duplicate "?" if search is
empty) while keeping the existing normalizedPath and redirects lookup.
🧹 Nitpick comments (1)
netlify/edge-functions/proxy-api-docs.js (1)

151-172: Retry on 429/5xx responses to improve resilience.

fetchWithRetry currently retries only on network errors and timeouts. Transient 429 (rate limit) and 5xx responses from Bump.sh will fail immediately. Consider treating them as retryable and respecting the Retry-After header to improve robustness.

♻️ Suggested update
 async function fetchWithRetry(url, options, maxRetries = 3) {
   for (let attempt = 1; attempt <= maxRetries; attempt++) {
     try {
       const response = await fetch(url, {
         ...options,
         signal: AbortSignal.timeout(10000), // 10 second timeout
       });
-      return response;
+      if (response.ok) return response;
+
+      const retryable = response.status === 429 || response.status >= 500;
+      if (!retryable || attempt === maxRetries) return response;
+
+      response.body?.cancel();
+      const retryAfter = response.headers.get("retry-after");
+      const delay =
+        retryAfter && Number.isFinite(Number(retryAfter))
+          ? Number(retryAfter) * 1000
+          : Math.pow(2, attempt) * 1000;
+      await new Promise(resolve => setTimeout(resolve, delay));
+      continue;
     } catch (error) {
       console.warn(`Attempt ${attempt} failed for ${url}:`, error.message);
 
       if (attempt === maxRetries) {
         throw error;
       }
 
       const delay = Math.pow(2, attempt) * 1000;
       await new Promise(resolve => setTimeout(resolve, delay));
     }
   }
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants