From 243828ef0bdf63eefe9eaa512dd325517dec6cad Mon Sep 17 00:00:00 2001 From: matham Date: Wed, 4 Nov 2020 20:45:58 -0500 Subject: [PATCH] Switch to GitHub actions with automatic deployment (#71) * Use a single setup.py. * Dosn't use a seperate setup for sdist. * Test on all branches. * Drop 3.5 and add 3.9. * Make, upload, and test sdist. * Update deploy.yml * Add pyproject.toml to sdist. * Delete .travis.yml * Add all root folders to sdist * Include md files. * Fix env variables to correct names. --- .github/workflows/deploy.yml | 57 ++++++++++++++++++ .github/workflows/python-package.yml | 8 +-- .travis.yml | 78 ------------------------ MANIFEST.in | 5 +- setup.py | 88 ++++++++++++++++++++++------ setup_sdist.py | 71 ---------------------- 6 files changed, 132 insertions(+), 175 deletions(-) create mode 100644 .github/workflows/deploy.yml delete mode 100644 .travis.yml delete mode 100644 setup_sdist.py diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..4f3aedb --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,57 @@ +name: Deploy sdist + +on: [push, pull_request] + +jobs: + deploy: + runs-on: macOs-latest + steps: + - uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v1 + with: + python-version: '3.x' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip setuptools + pip install cython twine + + - name: Build Package + run: | + python setup.py sdist --formats=gztar + + - name: Create artifacts + uses: actions/upload-artifact@v1 + with: + name: sdist + path: dist + + - name: Upload to GitHub Releases + if: startsWith(github.ref, 'refs/tags/') + uses: softprops/action-gh-release@v0.1.5 + env: + GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB }} + with: + files: dist/* + draft: false + + - name: Publish to PyPI + if: startsWith(github.ref, 'refs/tags/') + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + run: | + twine upload dist/* + + - name: Test sdist + run: | + pip uninstall cython -y + + root="$(pwd)" + cd ~ + pyobjus_fname=$(ls $root/dist/pyobjus-*.tar.gz) + pip install "$pyobjus_fname" + + python -c "from pyobjus import autoclass, objc_str" diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 204d104..0b613b7 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -3,11 +3,7 @@ name: Python package -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] +on: [push, pull_request] jobs: build: @@ -15,7 +11,7 @@ jobs: runs-on: macOs-latest strategy: matrix: - python-version: [3.5, 3.6, 3.7, 3.8] + python-version: [3.6, 3.7, 3.8, 3.9] steps: - uses: actions/checkout@v2 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index fd1a6fe..0000000 --- a/.travis.yml +++ /dev/null @@ -1,78 +0,0 @@ -sudo: required - -matrix: - fast_finish: true - include: - - language: generic - env: RUN=unit PY=2 HOMEBREW_NO_AUTO_UPDATE=1 - os: osx - - - language: generic - env: RUN=unit PY=3 HOMEBREW_NO_AUTO_UPDATE=1 - os: osx - - - language: generic - env: RUN=sdist PY=3 HOMEBREW_NO_AUTO_UPDATE=1 - os: osx - -before_install: - - echo PATH=$PATH; - - # uninstall old GNUpg, install new one and add Brew - # 'Cellar' folder to the path (contains binaries) - - brew uninstall gnupg - - brew install gnupg2 - - sudo ln -sv /usr/local/Cellar/gnupg /usr/local/Cellar/gpg || true - - sudo ln -sv /usr/local/Cellar/gnupg /usr/local/Cellar/gpg2 || true - - export PATH=$PATH:/usr/local/Cellar - - - echo "disable-ipv6" >> $HOME/.gnupg/dirmngr.conf - - gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB - - rvm get head - - # use real branch name instead of detached HEAD unless PR - - if [ "$TRAVIS_PULL_REQUEST_BRANCH" == "" ]; then - git checkout $TRAVIS_BRANCH; - fi; - -install: - # get Py3 because it's not present in any OSX image on Travis - - if [ "${PY}" == "3" ]; then - py3pkg=python-3.5.4rc1-macosx10.6.pkg; - curl -O -L https://www.python.org/ftp/python/3.5.4/$py3pkg; - sudo installer -package $py3pkg -target /; - fi; - - # manual get-pip.py on OSX because TLS1.2+ required - # pyfound.blogspot.com/2017/01/time-to-upgrade-your-python-tls-v12.html - # and install to virtualenv - - curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py - - if [ "${PY}" == "3" ]; then - sudo python3 get-pip.py; - else - sudo python get-pip.py; - fi; - - - if [ "${PY}" == "3" ]; then - pip3 install --user virtualenv; - python3 -m virtualenv env; - else - pip install --user virtualenv; - python -m virtualenv env; - fi; - - - source env/bin/activate; - - pip install --upgrade cython pytest - -script: - - make test_lib - - make - - make tests - - if [ "$RUN" == "sdist" ]; then - if [ "$PYOBJUS_DEPLOY" == "1" ]; then - git clean -dxf --exclude=env; - pip install requests[security] twine; - python setup_sdist.py sdist; - python -m twine upload dist/*; - fi; - fi; diff --git a/MANIFEST.in b/MANIFEST.in index d82d620..fe1a7af 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,5 @@ -include *LICENSE +include *LICENSE *pyproject.toml *Makefile *README.md recursive-include pyobjus *.pyx *.pxi *.h +recursive-include docs * +recursive-include tests * +recursive-include tools * diff --git a/setup.py b/setup.py index 52719c7..ffab693 100644 --- a/setup.py +++ b/setup.py @@ -1,10 +1,15 @@ from distutils.core import setup, Extension -from os import environ +from os import environ, walk from os.path import dirname, join, exists import sys import subprocess import platform -from setup_sdist import SETUP_KWARGS + +with open(join('pyobjus', '__init__.py')) as fd: + VERSION = [ + x for x in fd.readlines() + if x.startswith('__version__') + ][0].split("'")[-2] dev_platform = sys.platform kivy_ios_root = environ.get('KIVYIOSROOT', None) @@ -26,20 +31,24 @@ elif dev_platform == 'ios': from distutils.command.build_ext import build_ext files = ['pyobjus.c'] -# create a configuration file for pyobjus (export the platform) -config_pxi_fn = join(dirname(__file__), 'pyobjus', 'config.pxi') -config_pxi_need_update = True -config_pxi = 'DEF PLATFORM = "{}"\n'.format(dev_platform) -config_pxi += 'DEF ARCH = "{}"'.format(arch) -if exists(config_pxi_fn): - with open(config_pxi_fn) as fd: - config_pxi_need_update = fd.read() != config_pxi -if config_pxi_need_update: - with open(config_pxi_fn, 'w') as fd: - fd.write(config_pxi) -# if dev_platform` == 'ios': -# subprocess.`call(['find', '.', '-name', '*.pyx', '-exec', 'cython', '{}', ';']) +class PyObjusBuildExt(build_ext, object): + + def build_extensions(self): + # create a configuration file for pyobjus (export the platform) + config_pxi_fn = join(dirname(__file__), 'pyobjus', 'config.pxi') + config_pxi_need_update = True + config_pxi = 'DEF PLATFORM = "{}"\n'.format(dev_platform) + config_pxi += 'DEF ARCH = "{}"'.format(arch) + if exists(config_pxi_fn): + with open(config_pxi_fn) as fd: + config_pxi_need_update = fd.read() != config_pxi + if config_pxi_need_update: + with open(config_pxi_fn, 'w') as fd: + fd.write(config_pxi) + + super().build_extensions() + libraries = ['ffi'] library_dirs = [] @@ -55,12 +64,42 @@ depends = [join('pyobjus', x) for x in ( 'type_enc.pxi', 'pyobjus.pyx')] -# pop setup.py from included files in the installed package -SETUP_KWARGS['py_modules'].remove('setup') +data_allowed_ext = ( + 'readme', 'py', 'wav', 'png', 'jpg', 'svg', 'json', 'avi', 'gif', 'txt', + 'ttf', 'obj', 'mtl', 'kv', 'mpg', 'glsl', 'zip', 'h', 'm', 'md', +) + +def tree(source, allowed_ext=data_allowed_ext, tree_name='share/pyobjus-'): + found = {} + + for root, subfolders, files in walk(source): + for fn in files: + ext = fn.split('.')[-1].lower() + if ext not in allowed_ext: + continue + filename = join(root, fn) + directory = '%s%s' % (tree_name, dirname(filename)) + if directory not in found: + found[directory] = [] + found[directory].append(filename) + return found + # create the extension setup( - cmdclass={'build_ext': build_ext}, + name='pyobjus', + version=VERSION, + packages=['pyobjus', 'pyobjus.consts'], + ext_package='pyobjus', + data_files=[ + item + for data in [ + list(tree('examples').items()), + list(tree('objc_classes', tree_name='objc_classes/').items()) + ] + for item in data + ], + cmdclass={'build_ext': PyObjusBuildExt}, ext_modules=[ Extension( 'pyobjus', [join('pyobjus', x) for x in files], @@ -71,5 +110,16 @@ setup( extra_link_args=extra_link_args ) ], - **SETUP_KWARGS + classifiers=[ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Natural Language :: English', + 'Operating System :: MacOS', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Topic :: Software Development :: Libraries :: Application Frameworks' + ], ) diff --git a/setup_sdist.py b/setup_sdist.py deleted file mode 100644 index e92c58e..0000000 --- a/setup_sdist.py +++ /dev/null @@ -1,71 +0,0 @@ -''' -Setup.py only for creating a source distributions. - -This file holds all the common setup.py keyword arguments between the source -distribution and the ordinary setup.py for binary distribution. Running this -instead of the default setup.py will create a GitHub-like archive with setup.py -meant for installing via pip. -''' - -# pylint: disable=import-error,no-name-in-module -from distutils.core import setup -from os import walk -from os.path import join, dirname - - -with open(join('pyobjus', '__init__.py')) as fd: - VERSION = [ - x for x in fd.readlines() - if x.startswith('__version__') - ][0].split("'")[-2] - -data_allowed_ext = ( - 'readme', 'py', 'wav', 'png', 'jpg', 'svg', 'json', 'avi', 'gif', 'txt', - 'ttf', 'obj', 'mtl', 'kv', 'mpg', 'glsl', 'zip', 'h', 'm' -) - -def tree(source, allowed_ext=data_allowed_ext, tree_name='share/pyobjus-'): - found = {} - - for root, subfolders, files in walk(source): - for fn in files: - ext = fn.split('.')[-1].lower() - if ext not in allowed_ext: - continue - filename = join(root, fn) - directory = '%s%s' % (tree_name, dirname(filename)) - if directory not in found: - found[directory] = [] - found[directory].append(filename) - return found - -SETUP_KWARGS = { - 'name': 'pyobjus', - 'version': VERSION, - 'packages': ['pyobjus', 'pyobjus.consts'], - 'py_modules': ['setup'], - 'ext_package': 'pyobjus', - 'data_files': [ - item - for data in [ - list(tree('examples').items()), - list(tree('objc_classes', tree_name='objc_classes/').items()) - ] - for item in data - ], - 'classifiers': [ - 'Development Status :: 4 - Beta', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', - 'Natural Language :: English', - 'Operating System :: MacOS', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Topic :: Software Development :: Libraries :: Application Frameworks' - ] -} - -if __name__ == '__main__': - setup(**SETUP_KWARGS)