diff --git a/.github/workflows/link-check.yml b/.github/workflows/link-check.yml new file mode 100644 index 000000000..ccebe7675 --- /dev/null +++ b/.github/workflows/link-check.yml @@ -0,0 +1,62 @@ +name: Link Check + +on: + # Run on PRs that touch the list + pull_request: + paths: + - "README.md" + + # Run on pushes to master + push: + branches: + - master + paths: + - "README.md" + + # Weekly scan (Sunday 06:00 UTC) + schedule: + - cron: "0 6 * * 0" + + # Manual trigger + workflow_dispatch: + +jobs: + link-check: + name: Check Links + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Restore link cache + id: restore-cache + uses: actions/cache/restore@v4 + with: + path: .lycheecache + key: lychee-cache-${{ github.sha }} + restore-keys: lychee-cache- + + - name: Check links in README.md + id: lychee + uses: lycheeverse/lychee-action@v2 + with: + args: >- + --verbose + --no-progress + --cache + --max-cache-age 3d + --max-retries 3 + --retry-wait-time 5 + --max-concurrency 10 + --timeout 30 + --user-agent "Mozilla/5.0 (compatible; awesome-python-link-checker)" + './README.md' + token: ${{ secrets.GITHUB_TOKEN }} + fail: true + + - name: Save link cache + uses: actions/cache/save@v4 + if: always() + with: + path: .lycheecache + key: ${{ steps.restore-cache.outputs.cache-primary-key }} diff --git a/.lycheeignore b/.lycheeignore new file mode 100644 index 000000000..f4c43e345 --- /dev/null +++ b/.lycheeignore @@ -0,0 +1,12 @@ +# LinkedIn blocks automated requests (always returns 999) +^https?://(www\.)?linkedin\.com + +# Social media sites with aggressive bot detection +^https?://(www\.)?twitter\.com +^https?://x\.com +^https?://(www\.)?facebook\.com +^https?://(www\.)?instagram\.com + +# Localhost / local development URLs +^https?://localhost +^https?://127\.0\.0\.1 diff --git a/README.md b/README.md index 00b4d2ef7..0d8761012 100644 --- a/README.md +++ b/README.md @@ -1034,7 +1034,7 @@ _Libraries for testing codebases and generating test data._ - Testing Frameworks - [hypothesis](https://github.com/HypothesisWorks/hypothesis) - Hypothesis is an advanced Quickcheck style property based testing library. - - [nose2](https://github.com/nose-devs/nose2) - The successor to `nose`, based on `unittest2. + - [nose2](https://github.com/nose-devs/nose2) - The successor to `nose`, based on `unittest2`. - [pytest](https://docs.pytest.org/en/latest/) - A mature full-featured Python testing tool. - [Robot Framework](https://github.com/robotframework/robotframework) - A generic test automation framework. - [ScanAPI](https://pypi.org/project/scanapi/) - Automated Testing and Documentation for your REST API. diff --git a/lychee.toml b/lychee.toml new file mode 100644 index 000000000..17c99e578 --- /dev/null +++ b/lychee.toml @@ -0,0 +1,23 @@ +# Lychee link checker configuration +# https://lychee.cli.rs/usage/config/ + +# Treat 429 (rate-limited) responses as acceptable +accept = ["100..=103", "200..=299", "429"] + +# Don't fail the check when a request times out +timeout = 30 +accept_timeouts = true + +# Retry settings +max_retries = 3 +retry_wait_time = 5 + +# Be polite -- limit concurrent requests per host +max_concurrency = 10 + +# GitHub has the most links (528/708) -- throttle to avoid rate limits +[host."github.com"] + +[host."pypi.org"] + +[host."docs.python.org"]