# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license

# Continuous Integration (CI) GitHub Actions tests broken link checker using https://github.com/lycheeverse/lychee
# Ignores the following status codes to reduce false positives:
#   - 401(Vimeo, 'unauthorized')
#   - 403(OpenVINO, 'forbidden')
#   - 429(Instagram, 'too many requests')
#   - 500(Zenodo, 'cached')
#   - 502(Zenodo, 'bad gateway')
#   - 999(LinkedIn, 'unknown status code')

name: Check Broken links

permissions:
  contents: read

on:
  workflow_dispatch:
  schedule:
    - cron: "0 0 * * *" # runs at 00:00 UTC every day

jobs:
  Links:
    if: github.repository == 'ultralytics/ultralytics'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7

      - name: Install lychee
        run: |
          curl -sSfL "https://github.com/lycheeverse/lychee/releases/latest/download/lychee-x86_64-unknown-linux-gnu.tar.gz" |
            sudo tar xz --strip-components=1 -C /usr/local/bin lychee-x86_64-unknown-linux-gnu/lychee

      - name: Test Markdown and HTML links with retry
        uses: ultralytics/actions/retry@main
        with:
          timeout_minutes: 60
          retry_delay_seconds: 1800
          retries: 2
          backoff: fixed
          run: |
            lychee \
            --scheme https \
            --timeout 60 \
            --insecure \
            --accept 100..=103,200..=299,401,403,429,500,502,999 \
            --exclude-all-private \
            --exclude 'https?://(www\.)?(linkedin\.com|twitter\.com|instagram\.com|kaggle\.com|fonts\.gstatic\.com|url\.com|neptune\.ai|gnu\.org/software/make|survey\.stackoverflow\.co|clear\.ml|gitee\.com)' \
            --exclude-path docs/zh \
            --exclude-path docs/es \
            --exclude-path docs/ru \
            --exclude-path docs/pt \
            --exclude-path docs/fr \
            --exclude-path docs/de \
            --exclude-path docs/ja \
            --exclude-path docs/ko \
            --exclude-path docs/hi \
            --exclude-path docs/ar \
            --github-token ${{ secrets.GITHUB_TOKEN }} \
            --header "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36" \
            './**/*.md' \
            './**/*.html' | tee -a $GITHUB_STEP_SUMMARY

            # Raise error if broken links found
            if ! grep -q "0 Errors" $GITHUB_STEP_SUMMARY; then
              exit 1
            fi

      - name: Test Markdown, HTML, YAML, Python and Notebook links with retry
        if: github.event_name == 'workflow_dispatch'
        uses: ultralytics/actions/retry@main
        with:
          timeout_minutes: 60
          retry_delay_seconds: 1800
          retries: 2
          backoff: fixed
          run: |
            lychee \
            --scheme https \
            --timeout 60 \
            --insecure \
            --accept 100..=103,200..=299,401,403,429,500,502,999 \
            --exclude-all-private \
            --exclude 'https?://(www\.)?(linkedin\.com|twitter\.com|instagram\.com|kaggle\.com|fonts\.gstatic\.com|url\.com|neptune\.ai|gnu\.org/software/make|survey\.stackoverflow\.co|clear\.ml|gitee\.com)' \
            --exclude 'https?://[^[:space:]]*(%7B|%7D|\{|\}|sentry\.io|google-analytics\.com/mp/collect|storage\.googleapis\.com|packages\.cloud\.google\.com/apt)(/.*)?' \
            --exclude 'https://github\.com/ultralytics/assets/releases/download/v0\.0\.0' \
            --exclude 'https://raw\.githubusercontent\.com/ultralytics/assets/main/yolov8/banner-yolov8\.png/?' \
            --exclude 'https://static\.pepy\.tech/badge/ultralytics/?' \
            --exclude 'https://docs\.ultralytics\.com/(modes/(predict|val|train|export)|integrations/openvino)//?n' \
            --exclude 'https://ultralytics\.com/assets(/example\.zip)?' \
            --exclude-path './**/ci.yml' \
            --exclude-path docs/zh \
            --exclude-path docs/es \
            --exclude-path docs/ru \
            --exclude-path docs/pt \
            --exclude-path docs/fr \
            --exclude-path docs/de \
            --exclude-path docs/ja \
            --exclude-path docs/ko \
            --exclude-path docs/hi \
            --exclude-path docs/ar \
            --github-token ${{ secrets.GITHUB_TOKEN }} \
            --header "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36" \
            './**/*.md' \
            './**/*.html' \
            './**/*.yml' \
            './**/*.yaml' \
            './**/*.py' \
            './**/*.ipynb' | tee -a $GITHUB_STEP_SUMMARY

            # Raise error if broken links found
            if ! grep -q "0 Errors" $GITHUB_STEP_SUMMARY; then
              exit 1
            fi
