-
Notifications
You must be signed in to change notification settings - Fork 7
Add redirect checker to block PRs with deleted pages missing redirects #666
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Adds a GitHub Action and local script that compares the branch to main, detects deleted markdown files, and ensures each has a corresponding redirect entry in next.config.ts. Prevents broken bookmarks and SEO issues. Co-Authored-By: Claude Opus 4.5 <[email protected]>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cursor Bugbot has reviewed your changes and found 4 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
scripts/check-redirects.sh
Outdated
| fi | ||
|
|
||
| # Get list of deleted markdown files (comparing to base branch) | ||
| DELETED_FILES=$(git diff --name-status "$BASE_BRANCH"...HEAD 2>/dev/null | grep "^D" | grep -E '\.(md|mdx)$' | awk '{print $2}' || true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Script silently succeeds when base branch unavailable
High Severity
When the base branch cannot be fetched (network failure, invalid remote, wrong branch name), the script silently reports success with "No deleted markdown files found" instead of failing. The || true on the fetch command allows continuation, and the subsequent git diff against the non-existent branch fails silently due to 2>/dev/null || true. This allows PRs with deleted files to pass the check without any actual verification being performed.
…t checker Content moves: - Move guides/agent-frameworks/* to get-started/agent-frameworks/* - Move guides/tool-calling/mcp-clients/* to get-started/mcp-clients/* - Add wildcard redirects for moved content - Fix stale _meta.tsx references Redirect checker enhancements: - Interactive mode prompts for redirect destinations - Validates existing redirects for placeholder text (REPLACE_WITH, TODO, FIXME) - Catches circular redirects (source == destination) - Verifies destination pages exist - Detects both deletes and renames Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Fail with error when base branch is unavailable instead of silent success - Fix root page URL path handling (app/en/page.mdx -> /:locale) - Only check page.md/mdx files (skip non-routable markdown like README.md) - Use cut with tab delimiter instead of awk to handle filenames with spaces Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| # Return the destination | ||
| echo "$destination" | ||
| return 0 | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interactive prompts captured as destination value
Medium Severity
The prompt_for_destination function echoes informational prompts and messages to stdout (lines 223-230, 234, 240, 246), and the final destination path is also echoed to stdout (line 254). When called via command substitution at line 284 with destination=$(prompt_for_destination "$url_path"), all stdout output gets captured into destination, not just the intended path. This results in malformed redirect entries containing prompt text mixed with the actual destination, breaking the suggested redirect output in interactive mode.
Additional Locations (1)
| # Only match page.md or page.mdx files (actual routable pages in Next.js App Router) | ||
| # Use cut with tab delimiter instead of awk for proper field separation | ||
| COMMITTED_DELETES=$(git diff --name-status "$BASE_BRANCH"...HEAD 2>/dev/null | grep -E "^D|^R" | grep -E 'page\.(md|mdx)$' | cut -f2 || true) | ||
| UNCOMMITTED_DELETES=$(git diff --name-status HEAD 2>/dev/null | grep -E "^D|^R" | grep -E 'page\.(md|mdx)$' | cut -f2 || true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed page files to non-page files not detected
Medium Severity
The grep filter grep -E 'page\.(md|mdx)$' checks if the line ends with page.md(x), but for git renames the line format is R100<TAB>old-path<TAB>new-path, so it checks the new path, not the old one. If someone renames page.mdx to a non-page file (like component.tsx), the old page URL would break but the script won't detect it needs a redirect. The filter should check the old path (field 2), not the entire line.
Summary
scripts/check-redirects.sh) that works via git comparison to main.md/.mdxfiles and verifies they have redirect entries innext.config.tsTest plan
./scripts/check-redirects.shon a branch with deleted files🤖 Generated with Claude Code
Note
Adds automated protection against broken doc links and updates URLs for moved content.
check-redirects.ymlrunsscripts/check-redirects.shto detect deletedapp/**/*.md(x)without entries innext.config.ts, posting PR comments and failing the check.next.config.tsforguides/agent-frameworks→get-started/agent-frameworksandguides/tool-calling/mcp-clients→get-started/mcp-clients(including wildcards).public/llms.txtlinks, and adjusts_meta.tsxto reflect the newget-startedlocations.Written by Cursor Bugbot for commit 4142993. This will update automatically on new commits. Configure here.