Skip to content

Commit 9df8fd9

Browse files
ihabadhamclaudegithub-actions[bot]alexeyr-ci2
authored
Migrate from markdown-link-check to lychee (#2219)
## Summary Replaces the broken `markdown-link-check` setup with `lychee` for link checking. ## Problem The previous setup using `Wandalen/wretry.action` wrapper with `tcort/markdown-link-check` was **silently failing** due to a Node.js 21 ESM compatibility bug (see #2217). The tool crashed on every file, but the crash message didn't match the error detection pattern, so CI falsely reported "All links are good!" - while actually checking zero links. ## Solution Migrate to [lychee](https://github.com/lycheeverse/lychee), a Rust-based link checker that: - ✅ **Built-in retry for ALL transient errors** (502, 503, 504) - what PR #1899 wanted but couldn't achieve - ✅ **Proper exit codes** (2 = link failures, not relying on string matching) - ✅ **Faster execution** (~12 seconds vs 4+ minutes for 550 links) - ✅ **Result caching** for faster repeated runs - ✅ **No Docker/Node.js compatibility issues** ## Changes - Replace `.github/markdown-link-check-config.json` with `.lychee.toml` - Update workflow to use `lycheeverse/lychee-action@v2` - Add `.lycheecache` to `.gitignore` ## Test Plan - [x] CI link checker workflow runs successfully - [x] lychee correctly identifies broken links (will show ~26 errors from known broken URLs that need separate fixes) ## Note This PR will **fail CI** because it correctly detects ~26 broken links that the previous setup missed. Those links need to be fixed in a separate PR (like #2216). Fixes #2217 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Migrated CI markdown-link checking to Lychee with caching and updated workflow steps. * Removed the previous markdown-link-check configuration and added a new Lychee configuration. * Updated ignore rules to stop tracking Lychee cache artifacts. * **Documentation** * Rewrote and refreshed release notes and migration docs; updated tutorial links and formatting. * Clarified contributing guidance, changelog entry, and project listing content. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Alexey Romanov <alexeyr-ci2@users.noreply.github.com>
1 parent 93ab7df commit 9df8fd9

File tree

9 files changed

+237
-209
lines changed

9 files changed

+237
-209
lines changed

.github/markdown-link-check-config.json

Lines changed: 0 additions & 53 deletions
This file was deleted.

.github/workflows/check-markdown-links.yml

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ on:
66
paths:
77
- '**.md'
88
- '.github/workflows/check-markdown-links.yml'
9-
- '.github/markdown-link-check-config.json'
9+
- '.lychee.toml'
1010
pull_request:
1111
paths:
1212
- '**.md'
1313
- '.github/workflows/check-markdown-links.yml'
14-
- '.github/markdown-link-check-config.json'
14+
- '.lychee.toml'
1515
schedule:
1616
# Run weekly on Monday at 8am UTC
1717
- cron: '0 8 * * 1'
@@ -23,18 +23,15 @@ jobs:
2323
steps:
2424
- uses: actions/checkout@v4
2525

26-
- name: Check markdown links (with retry on transient errors)
27-
uses: Wandalen/wretry.action@v3.5.0
26+
- name: Restore lychee cache
27+
uses: actions/cache@v4
2828
with:
29-
action: tcort/github-action-markdown-link-check@a800ad5f1c35bf61987946fd31c15726a1c9f2ba
30-
with: |
31-
use-quiet-mode: yes
32-
use-verbose-mode: no
33-
config-file: .github/markdown-link-check-config.json
34-
folder-path: docs/
35-
file-extension: .md
36-
max-depth: -1
37-
check-modified-files-only: no
38-
base-branch: master
39-
attempt_limit: 3
40-
attempt_delay: 10000
29+
path: .lycheecache
30+
key: cache-lychee-${{ github.sha }}
31+
restore-keys: cache-lychee-
32+
33+
- name: Check markdown links
34+
uses: lycheeverse/lychee-action@v2
35+
with:
36+
args: --config .lychee.toml docs/ *.md react_on_rails_pro/docs/ react_on_rails_pro/*.md
37+
fail: true

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,4 @@ packages/**/node_modules/
9191

9292
# Jest test reports
9393
junit.xml
94+
.lycheecache

.lychee.toml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Lychee link checker configuration
2+
# https://lychee.cli.rs
3+
4+
# Accept successful responses and permanent redirects
5+
# 200 = OK, 308 = Permanent Redirect
6+
accept = ["200", "308"]
7+
8+
# Retry failed requests (handles transient 502/503/504/429 errors)
9+
max_retries = 4
10+
retry_wait_time = 15
11+
12+
# Timeout for each request
13+
timeout = 20
14+
15+
# Exclude patterns (migrated from markdown-link-check-config.json)
16+
exclude = [
17+
# Localhost/development URLs
18+
'^http://localhost',
19+
'^https://localhost',
20+
'^mailto:',
21+
22+
# Sites that block bots or require auth
23+
'^https://www\.npmjs\.(org|com)',
24+
'^https://medium\.com', # Returns 403 for automated requests
25+
'^https://www\.linkedin\.com',
26+
'^https://reactrails\.slack\.com',
27+
'^https://docs\.google\.com', # Private docs require auth
28+
'^https://claude\.ai', # Returns 403 for automated requests
29+
30+
# Known dead/problematic URLs (verified)
31+
'^https://your-shared-addr\.c9users\.io',
32+
'^https://hichee\.com',
33+
'^https?://rubyonrails\.org/doctrine', # DNS issues
34+
35+
# Sites from PROJECTS.md that block bots or are unreliable
36+
'^https://blog\.shakacode\.com', # May block automated requests
37+
'^https?://(www\.)?foxford\.ru', # Russian site, often blocks bots
38+
'^https://(www\.)?airgoat\.com', # Returns 403
39+
'^https://(www\.)?first\.io', # Returns 403
40+
'^https://(www\.)?estately\.com', # Returns 403
41+
'^https://hiring\.careerbuilder\.com', # Returns 403
42+
]
43+
44+
# Exclude paths (regex patterns)
45+
exclude_path = [
46+
'docs/planning/', # Contains placeholder links
47+
'.*/node_modules/.*', # Dependencies
48+
'.*/spec/.*', # Test fixtures
49+
'SUMMARY.md', # GitBook TOC with old doc structure links (kept for redirects)
50+
]
51+
52+
# Don't check fragments/anchors (can be flaky)
53+
include_fragments = false
54+
55+
# Cache results to speed up repeated runs
56+
cache = true
57+
max_cache_age = "1d"

PROJECTS.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,10 @@ _Please support the project by [emailing Justin Gordon](mailto:justin@shakacode.
4141

4242
- [github.com/empirical-org/Empirical-Core](https://github.com/empirical-org/Empirical-Core): [Quill.org](https://quill.org/) Provides free tools to make your students better writers.
4343
- **[Coderwall](https://coderwall.com/)**: The latest development and design tips, tools, and projects from our developer community. Source at [github.com/coderwall/coderwall-next](https://github.com/coderwall/coderwall-next)
44-
- [department-of-veterans-affairs/caseflow](https://github.com/department-of-veterans-affairs/caseflow): Caseflow is a web application that enables the tracking and processing of appealed claims at the Board of Veterans' Appeals.
4544

4645
## Demos and Tutorials
4746

48-
- [reactrails.com](http://www.reactrails.com), source code [github.com/shakacode/react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial/)
47+
- [reactrails.com](https://reactrails.com), source code [github.com/shakacode/react-webpack-rails-tutorial](https://github.com/shakacode/react-webpack-rails-tutorial/)
4948
- [Relay Rails Blog](https://github.com/gauravtiwari/relay-rails-blog): Tutorial to learn Relay with Rails.
5049
- [Hot Module Replacement with react_on_rails](https://medium.com/@hrishio/lesson-5-hot-module-replacement-for-react-in-rails-using-the-react-on-rails-gem-643c5b01f3d7#.ehevxok16) : Step-by-step tutorial for a quick basic set up of hot asset reloading with HMR in a Rails 5 app. [Code on Github](https://github.com/learnetto/calreact-hmr).....
5150

react_on_rails_pro/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ Changes since the last non-beta release.
102102
- Seamlessly use React Server Components in your Rails apps
103103
- Reduce client bundle sizes
104104
- Enable powerful new patterns for data fetching
105-
- [See the full tutorial](https://www.shakacode.com/react-on-rails-pro/docs/react-server-components-tutorial)
105+
- [See the full tutorial](https://www.shakacode.com/react-on-rails-pro/docs/react-server-components/tutorial)
106106

107107
[PR 422](https://github.com/shakacode/react_on_rails_pro/pull/422) by [AbanoubGhadban](https://github.com/AbanoubGhadban).
108108

0 commit comments

Comments
 (0)