name: Documentation CI

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

permissions:
  contents: read

env:
  CARGO_TERM_COLOR: always

jobs:
  check_docs:
    name: Check Documentation
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          # Required for tj-actions/changed-files to diff against the correct base.
          fetch-depth: 0

      - name: Get changed files
        id: changed_files
        uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46
        with:
          files_yaml: |
            docs_relevant:
              - src/**/*.rs
              - Cargo.toml
              - README.md
              - ./**/*.md
              - .github/workflows/docs.yml

      - name: Install Rust toolchain
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: stable
          cache: 'cargo'

      - name: Setup sccache
        if: steps.changed_files.outputs.docs_relevant_any_changed == 'true'
        uses: mozilla-actions/sccache-action@v0.0.9

      - name: Configure Rust to use sccache
        if: steps.changed_files.outputs.docs_relevant_any_changed == 'true'
        run: |
          echo "SCCACHE_GHA_ENABLED=true" >> $GITHUB_ENV
          echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV

      - name: Check Intra-Doc Links
        if: steps.changed_files.outputs.docs_relevant_any_changed == 'true'
        env:
          # Treat all documentation warnings (like broken links) as errors.
          RUSTDOCFLAGS: -D warnings
        run: cargo doc --no-deps --all-features

      - name: Restore lychee cache
        if: steps.changed_files.outputs.docs_relevant_any_changed == 'true'
        uses: actions/cache@v4
        with:
          path: .lycheecache
          key: lychee-cache-${{ runner.os }}-${{ github.sha }}
          restore-keys: |
            lychee-cache-${{ runner.os }}-

      - name: Check External Links
        if: steps.changed_files.outputs.docs_relevant_any_changed == 'true'
        # Pin action to a specific commit SHA for security and reproducibility.
        uses: lycheeverse/lychee-action@7da8ec1fc4e01b5a12062ac6c589c10a4ce70d67 # v2.0.0
        with:
          jobSummary: true
          args: >
            --verbose
            --no-progress
            --cache
            --max-cache-age 1d
            --exclude 'docs.rs'
            --exclude 'adobe.com'
            './target/doc/mpatch/**/*.html'
            './**/*.md'
        env:
          # Use GitHub token to avoid API rate-limiting when checking github.com links.
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Show sccache stats
        if: always() && steps.changed_files.outputs.docs_relevant_any_changed == 'true'
        shell: bash
        run: ${SCCACHE_PATH} --show-stats

      - name: Indicate checks skipped
        if: steps.changed_files.outputs.docs_relevant_any_changed == 'false'
        run: echo "Documentation checks skipped as no relevant files were changed."