ci: add linkspector link checking for blog content, fixes #470 - #695
Merged
Conversation
Adds a GitHub Actions job (mirroring ddev/ddevs docs-check.yml) that runs linkspector against src/content/blog on push and PRs, checking added lines only for PRs and everything on push to main. Also fixes the ~20 broken/stale links this surfaced across 26 blog posts (dead docs pages, renamed repos, expired campaign/session links replaced with Wayback Machine snapshots, a defunct xip.io reference, and a couple of markdown escaping bugs that turned example URLs into real links) so the checker starts green instead of red on merge. Developed with assistance from Claude Code (https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…ners The PR check for #695 failed on the Unsplash referral link added in eight-more-ways-to-get-the-most-out-of-ddev-local.md: Unsplash returned its anti-bot challenge (401) to the GitHub Actions runner even though the same URL format works fine elsewhere on the site and loads fine in a normal browser. Same class of issue as the existing LinkedIn/Medium/ npmjs/packtpub ignores. Developed with assistance from Claude Code (https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Deploying ddev-com-front-end with
|
| Latest commit: |
8929115
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://bc64cdb8.ddev-com-front-end.pages.dev |
| Branch Preview URL: | https://20260726-link-check.ddev-com-front-end.pages.dev |
stasadev
approved these changes
Jul 27, 2026
Member
There was a problem hiding this comment.
Thank you!
I tested it locally with:
~/.ddev-dev-tools/node/bin/linkspector checkThere's one more 404 page:
https://staatzstreich.de/blog/wie-ein-kaputter-installer-reload-zu-zwei-open-source-patche-2 (I fixed it).
The check itself is pretty heavy - it checks more than 2,000 links on main. If it becomes too annoying, we could remove it from the main push workflow and run it manually from time to time.
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.
Summary
Adds automated link checking for blog content, mirroring the approach ddev/ddev already uses for its docs (
.github/workflows/docs-check.yml+umbrelladocs/action-linkspector)..linkspector.ymlscopes the check tosrc/content/blogand ignores a short list of known-noisy patterns (see below)..github/workflows/link-check.ymlruns linkspector on push to main (full check) and on pull requests (added lines only), same split ddev/ddev uses.Fixing the internal-link-checker-for-Astro half of #470 (item 1 in the issue, replacing MkDocs strict-build checking) is left for later; root-relative internal links (
/contact,/img/...) are intentionally excluded here since Astro has no build-time equivalent yet.Why the ignore patterns
Running the checker against all 141 existing posts turned up two different kinds of noise that are not actually broken links:
*.ddev.siteexample URLs in tutorials always resolve to127.0.0.1and never have a real server behind them in CI.mailpit.axllent.organd similar in its own config.Content fixes (26 posts)
Running the checker also surfaced real, pre-existing broken links across the blog archive. Fixed here so the checker starts green on merge instead of red:
/blog/contributor-training/to/blog/category/training/, but the markdown-filename links (contributor-training.md) in these posts still pointed at the deleted file. Repointed to/blog/category/training.docker-providers.mdhad a malformed relative link to the ARM64 post;ddev-add-on-maintenance-guide.mdlinked to a mistyped anchor (#mutagen-problemreportinstead of#mutagen-problem-report).github.com/ddev/community->github.com/ddev/.github(the actual community-health repo); twodocs.ddev.compages that were restructured (install/ddev/->install/ddev-installation/,alternate-uses/#casual-...->topics/hosting/); a malformedgithub.com/.../READMEURL.web.archive.orgsnapshots so the content stays reachable.xip.iohas shut down, replaced with its direct successorsslip.io;frankenphp.orgwas a wrong TLD, corrected tofrankenphp.dev(used correctly elsewhere on the site).127.0.0.1, an autolinked<http://...>) to be parsed as real hyperlinks instead of inline code. Fixed the markdown so they render as code again.xdebugctlwas linked to agithub.com/xdebug/xdebugctlrepo that does not exist (it is a script bundled inside DDEV itself, not a separate project); removed that link and kept the workingxdebug.orgdocumentation link in the same sentence.How to test
Since this branch was pushed directly to
ddev/ddev.com(not a fork), the newpull_requesttrigger inlink-check.ymlshould run for this PR itself, not just after merging to main. A separate test repo likeddev-test/ddev.comis not needed: GitHub Actions resolves workflow files forpull_requestevents from the PR head branch as long as the PR is same-repo, so a brand-new workflow file added in a PR still executes for that PR. Check the "Checks" tab on this PR for a "Link check" run.To reproduce locally instead:
That should report 0 failed links (the local run before this PR was opened found 1: a
gnu.orgnavigation timeout that reproduced only in my sandbox and loads fine in an actual browser — worth watching in case it is flaky on CI too, but not treated as broken here).Fixes #470
🤖 Generated with Claude Code