From 6e42f39c015f1443a095923fd81a9acefb32da35 Mon Sep 17 00:00:00 2001 From: Bill Little Date: Wed, 4 Aug 2021 12:55:02 +0100 Subject: [PATCH] Fix GHA pypi-publish and UDUNITS2 XML read (#196) * Fix GHA pypi-publish and UDUNITS2 XML read * add publish to pypi job * turn codecov patch off --- .github/workflows/actions/entrypoint.sh | 27 ++++- .../actions/manylinux2010_x86_64/action.yml | 7 -- .../actions/manylinux2014_x86_64/action.yml | 7 ++ .github/workflows/build_linux.yml | 40 ------- .github/workflows/pypi_publish.yml | 102 ++++++++++++++++++ cf_units/__init__.py | 11 +- cf_units/config.py | 12 +++ cf_units/tests/unit/test__udunits2.py | 23 +++- codecov.yml | 5 +- setup.cfg | 1 + 10 files changed, 168 insertions(+), 67 deletions(-) delete mode 100644 .github/workflows/actions/manylinux2010_x86_64/action.yml create mode 100644 .github/workflows/actions/manylinux2014_x86_64/action.yml delete mode 100644 .github/workflows/build_linux.yml create mode 100644 .github/workflows/pypi_publish.yml diff --git a/.github/workflows/actions/entrypoint.sh b/.github/workflows/actions/entrypoint.sh index 71c6fed6..90bf95be 100755 --- a/.github/workflows/actions/entrypoint.sh +++ b/.github/workflows/actions/entrypoint.sh @@ -1,18 +1,37 @@ -#!/bin/sh +#!/usr/bin/env bash + +trap 'echo "Aborted!"; exit 1' ERR +set -e + yum install -y udunits2-devel + PYTHONS=("cp37-cp37m" "cp38-cp38" "cp39-cp39") -WHEELHOUSE="/github/workspace/wheelhouse/" +WHEELHOUSE="/github/workspace/wheelhouse" +MANYLINUX="manylinux2014_x86_64" +DISTRIBUTION="dist" export UDUNITS2_INCDIR="/usr/include/udunits2" export UDUNITS2_LIBDIR="/usr/lib64" export UDUNITS2_XML_PATH="/usr/share/udunits/udunits2.xml" +# Create the distribution directory. +mkdir ${DISTRIBUTION} + +# Build the wheels in the wheelhouse. for PYTHON in ${PYTHONS[@]}; do - /opt/python/${PYTHON}/bin/pip install --upgrade pip wheel setuptools setuptools_scm build twine auditwheel - /opt/python/${PYTHON}/bin/python -m build --sdist --wheel . --outdir ${WHEELHOUSE} + PYBIN="/opt/python/${PYTHON}/bin/python" + ${PYBIN} -m pip install --upgrade pip wheel setuptools setuptools_scm build twine auditwheel + ${PYBIN} -m build --wheel . --outdir ${WHEELHOUSE} done +# Build the sdist in the distribution. +${PYBIN} -m build --sdist . --outdir ${DISTRIBUTION} + +# Convert to manylinux wheels in the wheelhouse. for BDIST_WHEEL in ${WHEELHOUSE}/cf_units*.whl; do auditwheel repair ${BDIST_WHEEL} done + +# Populate distribution with the manylinux wheels. +cp ${WHEELHOUSE}/cf_units*${MANYLINUX}.whl ${DISTRIBUTION} diff --git a/.github/workflows/actions/manylinux2010_x86_64/action.yml b/.github/workflows/actions/manylinux2010_x86_64/action.yml deleted file mode 100644 index 4ddbd103..00000000 --- a/.github/workflows/actions/manylinux2010_x86_64/action.yml +++ /dev/null @@ -1,7 +0,0 @@ -name: 'build wheels with manylinux2010_x86_64' -description: 'build wheels with manylinux2010_x86_64' -runs: - using: 'docker' - image: docker://quay.io/pypa/manylinux2010_x86_64 - args: - - .github/workflows/actions/entrypoint.sh diff --git a/.github/workflows/actions/manylinux2014_x86_64/action.yml b/.github/workflows/actions/manylinux2014_x86_64/action.yml new file mode 100644 index 00000000..e0d5ba07 --- /dev/null +++ b/.github/workflows/actions/manylinux2014_x86_64/action.yml @@ -0,0 +1,7 @@ +name: 'build wheels with manylinux2014_x86_64' +description: 'build wheels with manylinux2014_x86_64' +runs: + using: 'docker' + image: docker://quay.io/pypa/manylinux2014_x86_64 + args: + - .github/workflows/actions/entrypoint.sh diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml deleted file mode 100644 index cbee7058..00000000 --- a/.github/workflows/build_linux.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: linux-wheels - -on: - release: - types: - - published - -jobs: - packages: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Get tags - shell: bash - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* - - - uses: ./.github/workflows/actions/manylinux2010_x86_64 - - name: copy manylinux wheels - run: | - mkdir dist - cp wheelhouse/cf_units*-manylinux2010_x86_64.whl dist/ - - - name: CheckFiles - shell: bash - run: | - ls dist - - - name: Test wheels - shell: bash - run: | - python -m pip install wheel twine pytest - cd dist && python -m pip install cf_units*.whl && python -m pytest --pyargs cf_units - python -m twine check * - - - name: Publish a Python distribution to PyPI - uses: pypa/gh-action-pypi-publish@v1.4.2 - with: - user: __token__ - password: ${{ secrets.PYPI_PASSWORD }} diff --git a/.github/workflows/pypi_publish.yml b/.github/workflows/pypi_publish.yml new file mode 100644 index 00000000..43485315 --- /dev/null +++ b/.github/workflows/pypi_publish.yml @@ -0,0 +1,102 @@ +name: pypi-publish + +on: + release: + types: + - published + +jobs: + build-artifacts: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Get tags + shell: bash + run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* + + - name: Build linux wheels + uses: ./.github/workflows/actions/manylinux2014_x86_64 + + - name: List built artifacts + shell: bash + working-directory: dist + run: ls + + - name: Check built artifacts + shell: bash + working-directory: dist + run: | + python -m pip install wheel twine + python -m twine check * + + - name: Inspect built wheels + shell: bash + working-directory: dist + run: | + for WHEEL in *.whl; do + echo -e "\n${WHEEL}" + python -m zipfile --list ${WHEEL} + done + + - name: Upload built artifacts + uses: actions/upload-artifact@v2 + with: + name: pypi-artifacts + path: dist + + test-artifacts: + needs: build-artifacts + name: Test ${{ matrix.tag }} for Python ${{ matrix.python }} + runs-on: ubuntu-latest + strategy: + matrix: + python: [3.7, 3.8, 3.9] + include: + - python: 3.7 + tag: cp37-cp37m + - python: 3.8 + tag: cp38-cp38 + - python: 3.9 + tag: cp39-cp39 + steps: + - name: Download built artifacts + uses: actions/download-artifact@v2 + with: + name: pypi-artifacts + path: dist + + - name: Setup Python ${{ matrix.python }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python }} + + - name: Install ${{ matrix.tag }} + env: + TAG: ${{ matrix.tag }} + shell: bash + working-directory: dist + run: python -m pip install cf_units-*-${TAG}-*.whl + + - name: Test ${{ matrix.tag }} + shell: bash + run: | + python -m pip install pytest + python -m pytest --pyargs cf_units + + publish-artifacts: + needs: [build-artifacts, test-artifacts] + name: Publish built artifacts to PyPI + runs-on: ubuntu-latest + steps: + - name: Download built artifacts + uses: actions/download-artifact@v2 + with: + name: pypi-artifacts + path: dist + + - name: Publish artifacts + uses: pypa/gh-action-pypi-publish@v1.4.2 + with: + user: __token__ + password: ${{ secrets.PYPI_PASSWORD }} diff --git a/cf_units/__init__.py b/cf_units/__init__.py index e1c94f8c..d45bd671 100644 --- a/cf_units/__init__.py +++ b/cf_units/__init__.py @@ -15,8 +15,6 @@ """ import copy -import os.path -import sys from contextlib import contextmanager import cftime @@ -187,15 +185,8 @@ def suppress_errors(): try: _ud_system = _ud.read_xml() except _ud.UdunitsError: - _alt_xml_path = config.get_option( - "System", - "udunits2_xml_path", - default=os.path.join( - sys.prefix, "share", "udunits", "udunits2.xml" - ), - ) try: - _ud_system = _ud.read_xml(_alt_xml_path.encode()) + _ud_system = _ud.read_xml(config.get_xml_path()) except _ud.UdunitsError as e: error_msg = ': "%s"' % e.error_msg() if e.errnum else "" raise OSError( diff --git a/cf_units/config.py b/cf_units/config.py index 4538cb40..8e0dec30 100644 --- a/cf_units/config.py +++ b/cf_units/config.py @@ -6,6 +6,7 @@ import configparser +import sys from pathlib import Path from tempfile import NamedTemporaryFile @@ -23,6 +24,17 @@ def get_option(section, option, default=None): return value +def get_xml_path(): + """Return the alternative path to the UDUNITS2 XMl file""" + default = Path(sys.prefix) / "share" / "udunits" / "udunits2.xml" + path = get_option( + "System", + "udunits2_xml_path", + default=str(default), + ) + return path.encode() + + # Figure out the full path to the "cf_units" package. ROOT_PATH = Path(__file__).resolve().parent diff --git a/cf_units/tests/unit/test__udunits2.py b/cf_units/tests/unit/test__udunits2.py index 069e8708..a92896ed 100644 --- a/cf_units/tests/unit/test__udunits2.py +++ b/cf_units/tests/unit/test__udunits2.py @@ -15,6 +15,7 @@ import numpy as np from cf_units import _udunits2 as _ud +from cf_units.config import get_xml_path _ud.set_error_message_handler(_ud.ignore) @@ -26,7 +27,10 @@ class Test_get_system(unittest.TestCase): """ def test_read_xml(self): - system = _ud.read_xml() + try: + system = _ud.read_xml() + except _ud.UdunitsError: + system = _ud.read_xml(get_xml_path()) self.assertIsNotNone(system) @@ -46,7 +50,10 @@ class Test_system(unittest.TestCase): """ def setUp(self): - self.system = _ud.read_xml() + try: + self.system = _ud.read_xml() + except _ud.UdunitsError: + self.system = _ud.read_xml(get_xml_path()) def test_get_unit_by_name(self): unit = _ud.get_unit_by_name(self.system, b"metre") @@ -91,7 +98,11 @@ class Test_unit(unittest.TestCase): """ def setUp(self): - self.system = _ud.read_xml() + try: + self.system = _ud.read_xml() + except _ud.UdunitsError: + self.system = _ud.read_xml(get_xml_path()) + self.metre = _ud.get_unit_by_name(self.system, b"metre") self.yard = _ud.get_unit_by_name(self.system, b"yard") self.second = _ud.get_unit_by_name(self.system, b"second") @@ -267,7 +278,11 @@ class Test_convert(unittest.TestCase): """ def setUp(self): - system = _ud.read_xml() + try: + system = _ud.read_xml() + except _ud.UdunitsError: + system = _ud.read_xml(get_xml_path()) + metre = _ud.get_unit_by_name(system, b"metre") yard = _ud.get_unit_by_name(system, b"yard") self.converter = _ud.get_converter(metre, yard) diff --git a/codecov.yml b/codecov.yml index e52d2034..99cf0038 100644 --- a/codecov.yml +++ b/codecov.yml @@ -5,5 +5,6 @@ coverage: status: project: default: - target: auto # auto compares coverage to the previous base commit - threshold: 0.5% # coverage can drop by up to 0.5% while still posting success + target: auto + threshold: 0.5% # coverage can drop by up to % while still posting success + patch: off diff --git a/setup.cfg b/setup.cfg index ac557f95..0811aabb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,6 +40,7 @@ include_package_data = True install_requires = antlr4-python3-runtime ==4.7.2 cftime >=1.2 + jinja2 numpy # udunits2 cannot be installed with pip, and it is expected to be # installed separately.