Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3840432

Browse files
EdwardAngertClaude
and
Claude
committed
refactor: replace linkspector with lychee for link checking
- Replace umbrelladocs/action-linkspector with lycheeverse/lychee-action - Create .lycheeignore file with the same patterns from linkspector - Update all workflows to use lychee with the new config - Update action outputs to support lychee's format - Remove .linkspector.yml as it's no longer needed - Enhanced documentation to reflect the tool change Reasons for the change: - Lychee is faster (written in Rust) - Better maintained and more widely used - More flexible configuration options - Improved error handling and reporting 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 0a464f3 commit 3840432

File tree

7 files changed

+124
-58
lines changed

7 files changed

+124
-58
lines changed

.github/actions/docs-shared/action.yaml

+14-7
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ outputs:
7676
value: ${{ steps.format-docs.outputs.result || '' }}
7777
link_check_results:
7878
description: 'Results from link checking'
79-
value: ${{ steps.check-links.outputs.result || '' }}
79+
value: ${{ steps.lychee.outputs.exit_code != '0' && 'Link check found issues' || '' }}
8080

8181
runs:
8282
using: 'composite'
@@ -262,13 +262,20 @@ runs:
262262
263263
- name: Check Markdown links
264264
if: inputs.check-links == 'true' && steps.docs-analysis.outputs.has_changes == 'true'
265-
id: check-links
266-
uses: umbrelladocs/action-linkspector@49cf4f8da82db70e691bb8284053add5028fa244 # v1.3.2
265+
id: lychee
266+
uses: lycheeverse/lychee-action@v1
267267
with:
268-
reporter: github-pr-review
269-
config_file: ".github/.linkspector.yml"
270-
fail_on_error: ${{ inputs.fail-on-error }}
271-
filter_mode: "nofilter"
268+
args: >-
269+
--verbose
270+
--no-progress
271+
--exclude-mail
272+
--exclude-loopback
273+
--exclude-private
274+
--ignore-file=.github/docs/.lycheeignore
275+
'${{ steps.changed-files.outputs.all_changed_files }}'
276+
format: json
277+
output: ./lychee-result.json
278+
fail: ${{ inputs.fail-on-error }}
272279

273280
- name: Generate Preview URL
274281
if: inputs.generate-preview == 'true' && steps.docs-analysis.outputs.has_changes == 'true'

.github/docs/.linkspector.yml

-22
This file was deleted.

.github/docs/.lycheeignore

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Ignore patterns for lychee link checker
2+
# These patterns match those previously configured in .linkspector.yml
3+
4+
# Common non-http links
5+
^#.* # Anchor links
6+
^mailto:.* # Email links
7+
^file:///.* # Local file links
8+
^\${.*} # Template variables
9+
10+
# Local development links
11+
^https?://localhost.*
12+
^https?://127\.0\.0\.1.*
13+
^https?://0\.0\.0\.0.*
14+
15+
# Domains that may have connectivity issues in CI but are known to be valid
16+
github.com
17+
coder.com
18+
example.com
19+
kubernetes.io
20+
k8s.io
21+
docker.com
22+
terraform.io
23+
hashicorp.com

.github/docs/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This directory contains GitHub Actions, configurations, and workflows for Coder'
77
- `actions/docs-setup`: Common setup action for documentation workflows
88
- `actions/docs-shared`: Phase-based composite action providing core documentation functionality
99
- `vale`: Configuration and style rules for Vale documentation linting
10-
- `.linkspector.yml`: Configuration for link checking
10+
- `.lycheeignore`: Configuration patterns for lychee link checking
1111

1212
## Available Workflows
1313

.github/docs/actions/docs-shared/action.yaml

+49-7
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ outputs:
8484
value: ${{ steps.format-docs.outputs.result || '' }}
8585
link_check_results:
8686
description: 'Results from link checking'
87-
value: ${{ steps.check-links.outputs.result || '' }}
87+
value: ${{ steps.process-lychee.outputs.result || '' }}
8888
vale_results:
8989
description: 'Results from Vale style checks'
9090
value: ${{ steps.lint-vale.outputs.result || '' }}
@@ -243,13 +243,55 @@ runs:
243243
244244
- name: Check Markdown links
245245
if: inputs.check-links == 'true' && steps.process-files.outputs.has_changes == 'true'
246-
id: check-links
247-
uses: umbrelladocs/action-linkspector@49cf4f8da82db70e691bb8284053add5028fa244 # v1.3.2
246+
id: lychee
247+
uses: lycheeverse/lychee-action@v1
248248
with:
249-
reporter: github-pr-review
250-
config_file: ".github/docs/.linkspector.yml"
251-
fail_on_error: ${{ inputs.fail-on-error }}
252-
filter_mode: "nofilter"
249+
args: >-
250+
--verbose
251+
--no-progress
252+
--exclude-mail
253+
--exclude-loopback
254+
--exclude-private
255+
--ignore-file=.github/docs/.lycheeignore
256+
'${{ steps.process-files.outputs.md_files_line }}'
257+
format: json
258+
output: ./lychee-result.json
259+
fail: false # We'll handle failure in the next step
260+
261+
- name: Process lychee results
262+
if: inputs.check-links == 'true' && steps.process-files.outputs.has_changes == 'true'
263+
id: process-lychee
264+
shell: bash
265+
run: |
266+
if [ -f "./lychee-result.json" ]; then
267+
# Count broken links - lychee format is different from linkspector
268+
BROKEN_LINKS=$(jq '.data.failed | length' "./lychee-result.json")
269+
270+
if [ "$BROKEN_LINKS" -gt 0 ]; then
271+
# Format results for output
272+
LINK_RESULTS="# Broken Links ($BROKEN_LINKS found)\n\n"
273+
LINK_RESULTS+="| File | Link | Status |\n"
274+
LINK_RESULTS+="|------|------|--------|\n"
275+
276+
# Process lychee's output format
277+
LINK_TABLE=$(jq -r '.data.failed[] | "| \(.input_file // "Unknown") | \(.url) | \(.status_code // "Error") |"' "./lychee-result.json")
278+
LINK_RESULTS+="$LINK_TABLE"
279+
280+
echo "result<<EOF" >> $GITHUB_OUTPUT
281+
echo -e "$LINK_RESULTS" >> $GITHUB_OUTPUT
282+
echo "EOF" >> $GITHUB_OUTPUT
283+
284+
if [ "${{ inputs.fail-on-error }}" == "true" ]; then
285+
echo "::error::Broken links found:"
286+
echo -e "$LINK_RESULTS"
287+
exit 1
288+
fi
289+
else
290+
echo "No broken links found"
291+
fi
292+
else
293+
echo "No lychee results file found"
294+
fi
253295
254296
- name: Run Vale style checks
255297
if: inputs.lint-vale == 'true' && steps.process-files.outputs.has_changes == 'true'

.github/workflows/docs-link-check.yaml

+24-15
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,22 @@ jobs:
3939
with:
4040
setup-vale: false # Don't need Vale for post-merge checks
4141

42-
# Check links with linkspector
42+
# Check links with lychee (faster and more robust than linkspector)
4343
- name: Check Markdown links
44-
uses: umbrelladocs/action-linkspector@v1
45-
id: link-check
44+
id: lychee
45+
uses: lycheeverse/lychee-action@v1
4646
with:
47-
reporter: github-check
48-
config_file: ".github/docs/.linkspector.yml"
49-
fail_on_error: "false" # Don't fail the workflow so we can create an issue
50-
filter_mode: "nofilter"
51-
format: "json" # Output in JSON format to parse results
47+
args: >-
48+
--verbose
49+
--no-progress
50+
--exclude-mail
51+
--exclude-loopback
52+
--exclude-private
53+
--ignore-file=.github/docs/.lycheeignore
54+
'./docs/**/*.md'
55+
format: json
56+
output: ./lychee-result.json
57+
fail: false
5258

5359
# Check cross-references specifically using our shared action
5460
- name: Check Cross-References
@@ -77,23 +83,26 @@ jobs:
7783
ISSUE_CONTENT=""
7884
ISSUE_TITLE=""
7985
80-
# Process link check results
81-
if [ -f "${{ steps.link-check.outputs.output_file }}" ]; then
82-
echo "Reading link check results from ${{ steps.link-check.outputs.output_file }}"
86+
# Process link check results from lychee
87+
if [ -f "./lychee-result.json" ]; then
88+
echo "Reading link check results from lychee-result.json"
8389
84-
# Count broken links
85-
BROKEN_LINKS=$(jq -r '.[] | select(.status != "alive") | .link' "${{ steps.link-check.outputs.output_file }}" | wc -l)
90+
# Count broken links - lychee format is different from linkspector
91+
BROKEN_LINKS=$(jq '.data.failed | length' "./lychee-result.json")
8692
echo "broken_links=$BROKEN_LINKS" >> $GITHUB_OUTPUT
8793
8894
if [ "$BROKEN_LINKS" -gt 0 ]; then
8995
HAS_ISSUES="true"
9096
ISSUE_TITLE="📚 Documentation Health Check: Broken Links and References"
9197
92-
# Format link results
98+
# Format link results with lychee's output structure
9399
LINK_RESULTS="## Broken Links ($BROKEN_LINKS found)\n\n"
94100
LINK_RESULTS+="| File | Link | Status |\n"
95101
LINK_RESULTS+="|------|------|--------|\n"
96-
LINK_RESULTS+=$(jq -r '.[] | select(.status != "alive") | "| \(.file) | \(.link) | \(.status) |"' "${{ steps.link-check.outputs.output_file }}")
102+
103+
# Process lychee's output format which is different from linkspector
104+
LINK_TABLE=$(jq -r '.data.failed[] | "| \(.input_file // "Unknown") | \(.url) | \(.status_code // "Error") |"' "./lychee-result.json")
105+
LINK_RESULTS+="$LINK_TABLE"
97106
98107
ISSUE_CONTENT+="$LINK_RESULTS\n\n"
99108
fi

.github/workflows/weekly-docs.yaml

+13-6
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,21 @@ jobs:
2929
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
3030

3131
- name: Check Markdown links
32-
uses: umbrelladocs/action-linkspector@49cf4f8da82db70e691bb8284053add5028fa244 # v1.3.2
33-
id: markdown-link-check
32+
uses: lycheeverse/lychee-action@v1
33+
id: lychee
3434
# checks all markdown files from /docs including all subfolders
3535
with:
36-
reporter: github-pr-review
37-
config_file: ".github/.linkspector.yml"
38-
fail_on_error: "true"
39-
filter_mode: "nofilter"
36+
args: >-
37+
--verbose
38+
--no-progress
39+
--exclude-mail
40+
--exclude-loopback
41+
--exclude-private
42+
--ignore-file=.github/docs/.lycheeignore
43+
'./docs/**/*.md'
44+
format: json
45+
output: ./lychee-result.json
46+
fail: true
4047

4148
- name: Send Slack notification
4249
if: failure() && github.event_name == 'schedule'

0 commit comments

Comments
 (0)