name: Build Documentation

# zizmor ignore note: All caching for pushes to main should be disabled with the `USE_CACHE` env var
on: # zizmor: ignore[cache-poisoning]
  pull_request: # Uses cache
  workflow_dispatch: # Able to not use cache by user demand
    inputs:
      cache:
        description: "Use build cache"
        required: false
        default: "true"
  # No cache enabled for `schedule` and `push`
  schedule:
    - cron: "0 0 1 * *" # once a month on main
  push:
    tags:
      - "*"
    branches:
      - main

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  USE_CACHE: ${{
    (
    (github.event_name == 'workflow_dispatch' && github.event.inputs.cache == 'true') ||
    (github.event_name == 'pull_request') ||
    (github.event_name == 'push')
    ) &&
    !startsWith(github.ref, 'refs/tags/v') &&
    !startsWith(github.ref, 'refs/heads/release/') &&
    !startsWith(github.ref, 'refs/heads/main')
    }}
  PYDEVD_DISABLE_FILE_VALIDATION: "1"
  PYTEST_ADDOPTS: "--color=yes"
  FORCE_COLOR: "True"
  VTK_DEFAULT_OPENGL_WINDOW: "vtkOSOpenGLRenderWindow"

permissions:
  id-token: none

jobs:
  doc:
    name: Build Documentation
    runs-on: ubuntu-22.04
    env:
      PYVISTA_OFF_SCREEN: "True"
      ALLOW_PLOTTING: true
      SHELLOPTS: "errexit:pipefail"
    steps:
      - uses: actions/checkout@v4
        with:
          persist-credentials: false

      - uses: actions/setup-python@v5
        with:
          python-version: "3.13"
          cache: "pip"

      - uses: awalsh128/cache-apt-pkgs-action@4c82c3ccdc1344ee11e9775dbdbdf43aa8a5614e
        with:
          packages: libosmesa6-dev libgl1-mesa-dev python3-tk pandoc git-restore-mtime
          version: 3.0

      - name: Install PyVista and dependencies
        run: |
          pip install --upgrade pip
          pip install . --group docs

      - name: PyVista Report
        run: |
          python -c "import pyvista;print(pyvista.Report())"
          echo PYVISTA_EXAMPLE_DATA_PATH=$(python -c "from pyvista import examples; print(examples.USER_DATA_PATH)") >> $GITHUB_ENV
          pip list

      - name: Cache Sphinx-Gallery Examples
        uses: actions/cache@v4
        if: env.USE_CACHE == 'true' && (! github.event_name == 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'no-gallery-cache'))
        with:
          path: doc/source/examples/
          key: doc-examples-${{ hashFiles('pyvista/_version.py') }}

      - name: Cache example data
        uses: actions/cache@v4
        if: env.USE_CACHE == 'true' && (! github.event_name == 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'no-example-data-cache'))
        with:
          path: ${{ env.PYVISTA_EXAMPLE_DATA_PATH }}
          key: example-data-1-${{ hashFiles('pyvista/_version.py') }}

      - name: Cache Sphinx build directory
        uses: actions/cache@v4
        if: env.USE_CACHE == 'true' && (! github.event_name == 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'no-sphinx-build-cache'))
        with:
          path: doc/_build/
          key: doc-examples-${{ hashFiles('pyvista/_version.py') }}

      - name: Build Documentation
        run: make -C doc html

      - name: Dump Sphinx Warnings and Errors
        if: always()
        run: if [ -e doc/sphinx_warnings.txt ]; then cat doc/sphinx_warnings.txt; fi

      - name: Dump VTK Warnings and Errors
        if: always()
        run: if [ -e doc/errors.txt ]; then cat doc/errors.txt; fi

      - name: Test Documentation
        if: always()
        run: pytest tests/doc/tst_doc_build.py

      - name: Upload Images for Failed Tests
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: doc-debug-images-failed
          path: _doc_debug_images_failed

      - name: Upload Test Debug Images
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: doc-debug-images
          path: _doc_debug_images

      - uses: actions/checkout@v4
        if: startsWith(github.ref, 'refs/heads/main') || startsWith(github.ref, 'refs/tags/v')
        with:
          repository: pyvista/pyvista-doc-translations
          path: pyvista-doc-translations
          fetch-depth: 0
          persist-credentials: false

      - name: Build I18N Documentation
        if: startsWith(github.ref, 'refs/heads/main') || startsWith(github.ref, 'refs/tags/v')
        run: |
          make -C doc mini18n-html
          find doc/_build/mini18n-html -mindepth 1 -maxdepth 1 -type d -exec cp -rf {} doc/_build/html/ \;
          rm -rf doc/_build/mini18n-html

      - name: Upload HTML documentation
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: docs-build
          path:
            | # Only vtksz files in 'doc/_build/html/_images/' are used. Exclude all others since these files may be large.
            doc/_build/html/
            !doc/_build/html/index-*.vtksz
            !doc/_build/html/api/**/*.vtksz
            !doc/_build/html/extras/**/*.vtksz
            !doc/_build/html/getting-started/**/*.vtksz
            !doc/_build/html/user-guide/**/*.vtksz

      - name: Upload non-interactive HTML documentation
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: docs-build-light
          path: |
            doc/_build/html/
            !doc/_build/html/**/*.vtksz

      - uses: actions/upload-artifact@v4
        with:
          name: examples
          path: doc/source/examples/

      - name: Get Notebooks
        run: |
          mkdir _notebooks
          find doc/source/examples -type f -name '*.ipynb' | cpio -p -d -v _notebooks/

      - uses: actions/upload-artifact@v4
        with:
          name: pyvista-notebooks
          path: _notebooks

  preview:
    name: Preview Development Documentation
    runs-on: ubuntu-22.04
    needs: doc
    if: github.ref == 'refs/heads/main' || github.event_name == 'pull_request'
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: docs-build
          path: .

      - name: Preview HTML documentation
        uses: nwtgck/actions-netlify@4cbaf4c08f1a7bfa537d6113472ef4424e4eb654
        with:
          publish-dir: .
          production-deploy: ${{ github.ref == 'refs/heads/main' }}
          github-token: ${{ secrets.PYVISTA_BOT_TOKEN }}
          deploy-message: "Deploy from GitHub Actions"
          enable-pull-request-comment: true
          enable-commit-comment: false
          overwrites-pull-request-comment: true
        env:
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEV_SITE_ID }} # DEV site
        timeout-minutes: 10

  deploy:
    name: Publish Release Documentation
    runs-on: ubuntu-22.04
    needs: doc
    if: startsWith(github.ref, 'refs/tags/v')
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: docs-build
          path: .

      - name: Deploy Release Documentation
        uses: nwtgck/actions-netlify@4cbaf4c08f1a7bfa537d6113472ef4424e4eb654
        with:
          publish-dir: .
          production-deploy: true
          github-token: ${{ secrets.GITHUB_TOKEN }}
          deploy-message: "Deploy from GitHub Actions"
          enable-pull-request-comment: false
          enable-commit-comment: false
          overwrites-pull-request-comment: false
        env:
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_STABLE_SITE_ID }} # STABLE site
        timeout-minutes: 10

  publish-notebooks:
    name: Publish Notebooks for MyBinder
    runs-on: ubuntu-22.04
    needs: doc
    if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')
    steps:
      - uses: actions/checkout@v4
        with:
          persist-credentials: false
      - uses: actions/setup-python@v5
        with:
          python-version: "3.13"
      - name: Install Dependencies
        run: |
          pip install cookiecutter
      - uses: actions/download-artifact@v4
        with:
          name: pyvista-notebooks
          path: .

      - name: Make Cookiecutter
        run: |
          cookiecutter -f --no-input --config-file ./doc/source/pyvista-binder-config.yml https://github.com/pyvista/cookiecutter-pyvista-binder.git;
          rm -rf ./pyvista-examples/notebooks/
          cp -r doc/source/examples/ ./pyvista-examples/
          ls -l ./pyvista-examples/

      - name: Publish notebooks on release
        if: startsWith(github.ref, 'refs/tags/v')
        uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e
        with:
          external_repository: pyvista/pyvista-examples
          personal_token: ${{ secrets.PYVISTA_BOT_TOKEN }}
          publish_dir: pyvista-examples
          publish_branch: master
          exclude_assets: ""
