From 166b41b2e2c0e2ac8ec9235532deaa0015c49d4e Mon Sep 17 00:00:00 2001 From: Drew Camron Date: Fri, 1 Nov 2024 14:16:09 -0600 Subject: [PATCH] Drop in MetPy docs workflows --- .github/workflows/docs-conda.yml | 89 +++++--------------- .github/workflows/docs.yml | 136 ++++++++++--------------------- ci/filter_links.py | 45 ++++++++++ 3 files changed, 111 insertions(+), 159 deletions(-) create mode 100755 ci/filter_links.py diff --git a/.github/workflows/docs-conda.yml b/.github/workflows/docs-conda.yml index 391ec3013..50605326a 100644 --- a/.github/workflows/docs-conda.yml +++ b/.github/workflows/docs-conda.yml @@ -3,12 +3,15 @@ name: Build Docs (Conda) # We don't want pushes (or PRs) to gh-pages to kick anything off on: pull_request: - branches: [ main ] + branches: + - main + - '[0-9]+.[0-9]+.x' + +concurrency: + group: ${{ github.workflow}}-${{ github.head_ref }} + cancel-in-progress: true jobs: - # - # Build our docs on macOS and Windows on Python 3.6 and 3.8, respectively. - # Docs: name: ${{ matrix.os }} ${{ matrix.python-version }} runs-on: ${{ matrix.os }}-latest @@ -19,78 +22,28 @@ jobs: fail-fast: false matrix: include: - - python-version: 3.8 - os: macOS - - python-version: 3.7 + - python-version: '3.10' os: Windows + - python-version: 3.11 + os: macOS + - python-version: 3.12 + os: macOS steps: - # We check out only a limited depth and then pull tags to save time - name: Checkout source - uses: actions/checkout@v3 - with: - fetch-depth: 100 - - - name: Get tags - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* - - - name: Setup conda caching - uses: actions/cache@v3 + uses: actions/checkout@v4 with: - path: ~/conda_pkgs_dir - key: conda-docs-${{ runner.os }}-${{ matrix.python-version}}-${{ hashFiles('ci/*') }} - restore-keys: | - conda-docs-${{ runner.os }}-${{ matrix.python-version}} - conda-docs-${{ runner.os }} - conda-docs- + fetch-depth: 150 + fetch-tags: true - - name: Set up Python ${{ matrix.python-version }} - uses: conda-incubator/setup-miniconda@v2 + - name: Install from Conda + uses: Unidata/MetPy/.github/actions/install-conda@main with: - miniconda-version: "latest" + type: 'doc' python-version: ${{ matrix.python-version }} - channel-priority: strict - channels: conda-forge - show-channel-urls: true - # Needed for caching - use-only-tar-bz2: true - - - name: Install dependencies - run: conda install --quiet --yes --file ci/doc_requirements.txt --file ci/extra_requirements.txt --file ci/requirements.txt - - # This imports CartoPy to find its map data cache directory - - name: Get CartoPy maps dir - id: cartopy-cache - run: echo "::set-output name=dir::$(python -c 'import cartopy;print(cartopy.config["data_dir"])')" - - - name: Setup mapdata caching - uses: actions/cache@v3 - env: - # Increase to reset cache of map data - CACHE_NUMBER: 0 - with: - path: ${{ steps.cartopy-cache.outputs.dir }} - key: docs-cartopy-${{ env.CACHE_NUMBER }} - restore-keys: docs-cartopy- - - - name: Install - # For some reason on Windows 3.7 building the wheel fails to properly include our extra - # stuff. Executing the egg_info beforehand for some reason fixes it. No idea why. We're - # deep in territory where googling for answers helps not at all. - run: | - python setup.py egg_info - python -m pip install --no-deps . + need-cartopy: false - name: Build docs - run: | - pushd docs - make html O=-W - popd - - - name: Upload docs as artifact - uses: actions/upload-artifact@v3 + uses: ./.github/actions/build-docs with: - name: ${{ matrix.os }}-${{ matrix.python-version }}-docs - path: | - docs/build/html - !docs/_static/*.pdf + key: ${{ matrix.os }}-${{ matrix.python-version }} diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index bc8dfa7d6..275c946f4 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -10,128 +10,82 @@ on: - v[0-9]+.[0-9]+.[0-9]+ pull_request: +permissions: + contents: write + +concurrency: + group: ${{ github.workflow}}-${{ github.head_ref }} + cancel-in-progress: true + jobs: # - # Build our docs on Linux against multiple Pythons, including pre-releases + # Build our docs on Linux against multiple Pythons # Docs: - name: ${{ matrix.python-version }} ${{ matrix.dep-versions }} - runs-on: ubuntu-20.04 - continue-on-error: ${{ matrix.experimental }} - env: - DOC_VERSION: dev + name: "Linux ${{ matrix.python-version }}" + runs-on: ubuntu-latest strategy: fail-fast: false matrix: + python-version: ['3.10', 3.11] + check-links: [false] include: - - python-version: 3.8 - check-links: false - dep-versions: requirements.txt - experimental: false - - python-version: 3.9 + - python-version: 3.12 check-links: true - dep-versions: requirements.txt - experimental: false - - python-version: 3.9 - check-links: false - dep-versions: Prerelease - experimental: true + outputs: + doc-version: ${{ steps.build-docs.outputs.doc-version }} steps: - # We check out only a limited depth and then pull tags to save time - name: Checkout source - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: - fetch-depth: 100 + fetch-depth: 150 - name: Get tags run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + - name: Install using PyPI + uses: Unidata/MetPy/.github/actions/install-pypi@main with: + type: 'doc' python-version: ${{ matrix.python-version }} - - # This uses pip to find the right cache dir and then sets up caching for it - - name: Get pip cache dir - id: pip-cache - run: echo "::set-output name=dir::$(pip cache dir)" - - - name: Setup pip cache - uses: actions/cache@v3 - with: - path: ${{ steps.pip-cache.outputs.dir }} - key: pip-docs-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('ci/*') }} - restore-keys: | - pip-docs-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('ci/*') }} - pip-docs-${{ runner.os }}-${{ matrix.python-version }}- - pip-docs-${{ runner.os }}- - pip-docs- - - # This installs the stuff needed to build and install Shapely and CartoPy from source. - # Need to install numpy first to make CartoPy happy. - - name: Install dependencies (PyPI) - if: ${{ runner.os == 'Linux' }} - run: | - sudo apt-get install libgeos-dev libproj-dev proj-bin - python -m pip install --upgrade pip setuptools - python -m pip install -c ci/${{ matrix.dep-versions }} numpy - python -m pip install -r ci/doc_requirements.txt -r ci/extra_requirements.txt -c ci/${{ matrix.dep-versions }} - - # This imports CartoPy to find its map data cache directory - - name: Get CartoPy maps dir - id: cartopy-cache - run: echo "::set-output name=dir::$(python -c 'import cartopy;print(cartopy.config["data_dir"])')" - - - name: Setup mapdata caching - uses: actions/cache@v3 - env: - # Increase to reset cache of map data - CACHE_NUMBER: 0 - with: - path: ${{ steps.cartopy-cache.outputs.dir }} - key: docs-cartopy-${{ env.CACHE_NUMBER }} - restore-keys: docs-cartopy- - - - name: Install self - run: python -m pip install -c ci/${{ matrix.dep-versions }} . + need-extras: true + need-cartopy: false - name: Build docs - run: | - pushd docs - make html O=-W - popd - - - name: Enable linkchecker for PRs - # Doing the linkchecker separately so that we avoid problems with vendored LICENSE - # files in the build directory - if: ${{ github.event_name == 'pull_request' && matrix.check-links == true }} - run: | - pushd docs - find build/html/_static -name LICENSE.md -delete - make linkcheck - popd + id: build-docs + uses: Unidata/MetPy/.github/actions/build-docs@main + with: + run-linkchecker: ${{ github.event_name == 'pull_request' && matrix.check-links == true }} + key: ${{ runner.os }}-${{ matrix.python-version }} + make-targets: '' + + Deploy: + if: ${{ github.event_name != 'pull_request' }} + needs: Docs + environment: + name: github-pages + runs-on: ubuntu-latest + env: + DOC_VERSION: dev - - name: Upload docs as artifact - if: ${{ github.event_name == 'pull_request' }} - uses: actions/upload-artifact@v3 + steps: + - name: Download doc build + uses: actions/download-artifact@v4 with: - name: ${{ matrix.python-version }}-${{ matrix.dep-versions }}-docs - path: | - docs/build/html - !docs/_static/*.pdf + name: Linux-3.11-docs + path: ./docs/build/html # This overrides the version "dev" with the proper version if we're building off a # branch that's not main (which is confined to n.nn.x above) or on a tag. - name: Set doc version if: ${{ github.event_name != 'push' || !contains(github.ref, 'main') }} - run: echo "DOC_VERSION=v$(python -c 'import siphon; print(siphon.__version__.rsplit(".", maxsplit=2)[0])')" >> $GITHUB_ENV + run: echo "DOC_VERSION=v${{ needs.Docs.outputs.doc-version }}" >> $GITHUB_ENV - name: Upload to GitHub Pages - if: ${{ github.event_name != 'pull_request' && matrix.experimental == false }} - uses: peaceiris/actions-gh-pages@v3.9.3 + uses: peaceiris/actions-gh-pages@v4 with: - github_token: ${{ secrets.GITHUB_TOKEN }} + deploy_key: ${{ secrets.GHPAGES_DEPLOY_KEY }} publish_dir: ./docs/build/html exclude_assets: '.buildinfo,_static/jquery-*.js,_static/underscore-*.js' destination_dir: ./${{ env.DOC_VERSION }} diff --git a/ci/filter_links.py b/ci/filter_links.py new file mode 100755 index 000000000..c03e791bc --- /dev/null +++ b/ci/filter_links.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# Copyright (c) 2021 MetPy Developers. +"""Filter links from Sphinx's linkcheck.""" +import json +import subprocess +import sys + + +def get_failing_links(fname): + """Yield links with problematic statuses.""" + with open(fname) as linkfile: + links = json.loads('[' + ','.join(linkfile) + ']') + for link in links: + if link['status'] not in {'working', 'ignored', 'unchecked'}: + yield link + + +def get_added(): + """Get all lines added in the most recent merge.""" + revs = subprocess.check_output(['git', 'rev-list', '--parents', '-n', '1', 'HEAD']) + merge_commit, target, _ = revs.decode('utf-8').split() + diff = subprocess.check_output(['git', 'diff', f'{target}...{merge_commit}']) + return '\n'.join(line for line in diff.decode('utf-8').split('\n') + if line.startswith('+') and not line.startswith('+++')) + + +if __name__ == '__main__': + # If the second argument is true, then we only want links in the most recent merge, + # otherwise we print all failing links. + if sys.argv[2] in ('true', 'True'): + print('Checking only links in the diff') + added = get_added() + check_link = lambda link: link['uri'] in added + else: + print('Checking all links') + check_link = lambda link: True + + ret = 0 + for link in get_failing_links(sys.argv[1]): + if check_link(link): + ret = 1 + print(f'{link["filename"]}:{link["lineno"]}: {link["uri"]} -> ' + f'{link["status"]} {link["info"]}') + + sys.exit(ret)