DX-2361: Add GitHub Actions to validate external URLs and internal anchor fragments - #1865
Merged
Merged
Conversation
…chors
- Extend validate_mintlify_docs.py with --check-anchors flag that extracts
GFM-slugified heading anchors, {#custom-id} syntax, and <a id/name> elements
from target MDX files and verifies every internal #fragment resolves
- Update validate-docs.yml to run anchor check on every PR
- Add check-external-links.yml workflow: weekly scheduled (Mon 07:00 UTC) and
manual-trigger run that HEAD-checks all external HTTP/HTTPS URLs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Failed to generate code suggestions for PR |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
External link failures were reported but never factored into the exit code, so CI was passing despite 404s. Added has_broken_external check and a summary line for external link results. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace sequential Python/requests approach with lycheeverse/lychee-action. Lychee runs checks in parallel, has built-in retry logic, and is purpose-built for link checking — much faster on a repo with 1500+ external URLs. Add lychee.toml to exclude tyk-owned domains, localhost, placeholder URLs, and sites known to block bots (LinkedIn, Facebook). Accept 429 as non-broken to handle rate-limited responses gracefully. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GitHub Actions expands ${{ }} expressions before the shell runs, so
backticks and $ signs in PR bodies were injected raw into the script
and interpreted as shell command substitution.
Fix: write static content via a single-quoted heredoc (no shell
expansion), then append the PR body via printf with an env var
($PR_BODY). Shell variables accessed as "$VAR" are never
re-interpreted, making any PR body content safe.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add scheme = ["https", "http"] to lychee.toml so lychee only attempts to check http/https URLs. Without this, lychee tries to resolve root-relative paths (/img/..., /page/...) as file URIs and fails. Internal links are already validated by validate-docs.yml. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
scheme = ["https", "http"] didn't help because lychee fails to build the URL before the scheme filter runs. Set base = "https://tyk.io" so root-relative paths (/img/..., /page/...) are resolved to https://tyk.io/... and then silently skipped by the existing tyk.io exclude rule, rather than producing "cannot convert path to URI" errors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sharadregoti
added a commit
that referenced
this pull request
Apr 11, 2026
Fixes all broken anchor fragments identified by the CI anchor checker introduced in DX-2361 (#1865). Root causes fixed: - Release note anchors: old slugify removed dots from version numbers (e.g. 5.3.0 → #530-release-notes); updated to dot-to-hyphen format (#5-3-0-release-notes) across gateway, dashboard, helm-chart, operator, portal, and archived release note pages - Restructured pages: logs-metrics, portal/install, and tyk-self-managed/install were reorganised; removed or updated stale anchors to current headings - Moved content: JWT signature validation content moved to dedicated page; updated links from json-web-tokens to jwt-signature-validation - Wrong anchor names: fixed typos and outdated anchors in implement-tls, certificates, mdcb, graphql, dynamic-client-registration, dashboard-config - Mintlify slug nuance: headings with ": " generate double hyphens (--); fixed portal step links and other colon-containing headings - Validator: updated heading regex to detect headings inside ordered list items (pattern used in troubleshooting-debugging.mdx) Result: 0 broken anchor fragments (was 163 across 60 files) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3 tasks
Contributor
Author
|
/release to release-5.12 |
buger
pushed a commit
that referenced
this pull request
Apr 11, 2026
…chor fragments (#1865) * DX-2361: Add GitHub Actions to validate external URLs and internal anchors - Extend validate_mintlify_docs.py with --check-anchors flag that extracts GFM-slugified heading anchors, {#custom-id} syntax, and <a id/name> elements from target MDX files and verifies every internal #fragment resolves - Update validate-docs.yml to run anchor check on every PR - Add check-external-links.yml workflow: weekly scheduled (Mon 07:00 UTC) and manual-trigger run that HEAD-checks all external HTTP/HTTPS URLs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * DX-2361: Run external link check on every pull request Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * DX-2361: Fix exit code not failing on broken external links External link failures were reported but never factored into the exit code, so CI was passing despite 404s. Added has_broken_external check and a summary line for external link results. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * DX-2361: Switch external link checker to lychee Replace sequential Python/requests approach with lycheeverse/lychee-action. Lychee runs checks in parallel, has built-in retry logic, and is purpose-built for link checking — much faster on a repo with 1500+ external URLs. Add lychee.toml to exclude tyk-owned domains, localhost, placeholder URLs, and sites known to block bots (LinkedIn, Facebook). Accept 429 as non-broken to handle rate-limited responses gracefully. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix mirror-pr workflow failing on PR bodies with special characters GitHub Actions expands ${{ }} expressions before the shell runs, so backticks and $ signs in PR bodies were injected raw into the script and interpreted as shell command substitution. Fix: write static content via a single-quoted heredoc (no shell expansion), then append the PR body via printf with an env var ($PR_BODY). Shell variables accessed as "$VAR" are never re-interpreted, making any PR body content safe. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix lychee checking internal/relative links Add scheme = ["https", "http"] to lychee.toml so lychee only attempts to check http/https URLs. Without this, lychee tries to resolve root-relative paths (/img/..., /page/...) as file URIs and fails. Internal links are already validated by validate-docs.yml. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix lychee erroring on root-relative paths scheme = ["https", "http"] didn't help because lychee fails to build the URL before the scheme filter runs. Set base = "https://tyk.io" so root-relative paths (/img/..., /page/...) are resolved to https://tyk.io/... and then silently skipped by the existing tyk.io exclude rule, rather than producing "cannot convert path to URI" errors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix lychee config: base -> base_url Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> (cherry picked from commit 88b1aa0)
|
✅ Cherry-pick successful. A PR was created and auto-merged (if allowed): #1868 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Jira Ticket
DX-2361
Summary
Two link-correctness gaps existed in the docs CI — this PR closes both:
/page#section) were checked for file existence but the#sectionpart was silently ignored — 371 broken anchors exist across 108 files todayChanges
scripts/validate_mintlify_docs.pyslugify_heading()— converts heading text to GFM anchor slug (Mintlify's format)extract_file_anchors()— collects all valid anchors from an MDX file:## Heading) → GFM slug## Heading {#custom-id})<a id="...">and<a name>elementsbuild_anchor_map()— pre-builds a file→anchors cache across all MDX filesfind_internal_links_with_anchors()— extracts(path, fragment)pairs from linkscheck_broken_anchors()— validates each fragment against the target file's anchor set--check-anchorsCLI flag; all existing behaviour is unchanged when flag is absent.github/workflows/validate-docs.yml.github/workflows/check-external-links.yml(new)workflow_dispatch)--external-linksflag; reports only failures (--external-errors-only)workflow_dispatchinputsKnown Limitation
Files that use MDX
importto pull in snippets (e.g.tyk-oss-gateway/configuration.mdx) may show false-positive anchor failures because the checker reads the file directly, not its imported snippets. These will need to be triaged separately.Test Plan
python scripts/validate_mintlify_docs.py . --check-anchors --links-onlylocally to confirm anchor failures are reported correctlyvalidate-docs.ymlcheck step passes on a PR with valid anchorscheck-external-links.ymlmanually via Actions → Run workflow