Skip to content

Commit

Permalink
Enable pre-release builds from dev branch:
Browse files Browse the repository at this point in the history
PyPi Deployments
================
* Add function to get a pre-release version number; only used by Travis jobs on the dev branch
* Add a separate deploy target for dev branch only
* Create & encrypt a new pypi token with a scope of pyinaturalist repo only

Dependencies
============
* Add separate `build` setuptools extra for build-specific packages
* Remove `twine` from dependencies since Travis uses this already
* Remove twine from dependencies since Travis automatically installs this during deployment
* Add `semantic-version` package, only used for Travis pre-release builds
    * Note: Also added this to dev dependencies, but only because there are unit tests for
      pre-release version numbers
* Only install the `typing` backport if we're on python < 3.5

Other Config
============
* Move `mypy.ini` config into `setup.cfg`
* Update pypi version badge to match the format/resolution of the others
* Add badges for package format and supported python version
  • Loading branch information
JWCook committed Jun 10, 2020
1 parent 3f66856 commit cd97969
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 47 deletions.
51 changes: 31 additions & 20 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,39 @@ matrix:
- python: "3.5"
- python: "3.6"
- python: "3.7"
- python: "3.8"
# Run a separate job for combined code quality checks
# Run a separate job for combined code quality checks
- python: "3.8"
env: TOXENV=coverage,mypy,style
- python: "3.8"
env:
- secure: QFRSBbtAPfFxO2GONfI2KCrq7gdSI6zj4wI5QEunjz8xVjvb60TD2Q4ULmoMPBqgFkqV6NZr6bB49MpNcpfw9aeBkUqjYmWWkLfZZsFWvJeRnkPV4EcfmMKJ9pph9QUYQ1BUcqWPZbPYk0VQdDxMVwDKETW2nzVNgRFaJm4O9kM6qV462/3dN53Q0NNTBfSju80nV8YQycP7onEQQILFityDOThKqR3FctDiwrfMo3ALWSfghkyvCgvrvpf6uAWncM1hwDwga+1Luo3vDG6reDE+M3AitFwo5XsPXy8hER8BwuUh8MRrr/HbakH66e83vvBX593DoGZr7UMqwEg+Xzpa2yUvSszW2U9ksh9BaYPbZG3nzsJJlTg61k6Sh7OU4AXglsDBPVX5aoLVz6XSAL97p+Ec85yo8dzpxzBc31ow8rI6JS9yycRnHXGATKqTIQ7Z3QiVaNKrIJVKhMdqvng1zb8RFR49MbPFT5QQuxOJLe/S1qkzOjclp2scZV17TPa6hkfTuDz01+rPXKh3US0WbR689TtNCBB/UwuoX5vnFqcvmqi0sZtl0G4eqXPvik4r7JnuX3d81LIGzF6e45FyO8sSvicZxCu8KmQQ7xI0hXjP6+vfEOnnz4xpAKmHmf2xTIStpuaCm7xqdt3M070P/A4kC0xBGcbcNCq1xU4=

# Install dependencies & run tests
install:
- pip install tox-travis coveralls
script:
- tox
# Run coveralls after 'coverage' env
after_success:
- if [[ $TOXENV == *"coverage"* ]]; then coveralls; fi
# Install dependencies & run tests, and run coveralls after 'coverage' job
install: pip install ".[build]"
script: tox
after_success: if [[ $TOXENV == *"coverage"* ]]; then coveralls; fi

# Deploy to PyPI on git tags only (and master branch only by default)
# Note: These two release types could be combined, but requires a long, ugly custom condition
# See: https://docs.travis-ci.com/user/deployment#conditional-releases-with-on
deploy:
provider: pypi
user: __token__
password:
secure: s7FY53bvG0e+xS/pVQC+SX/eGnZR7alAqpE3n6HZvGQec0kGCE3VofCpGVUyguUiUGmm027xIIdSq6Gpx+lBhWRGmf36RDUAaBOV2DVCgEdPf8nX8Gv4vinOepXWVTYal7QNXiDZCiryyA2O+/28A4abGTS37w+zUQyM70UgJwI9hO1zC4dj4maDY2WE1XHS0WHuI3+iRYc/48d5Pc58gDuGWB4adZ7lODB81/d6StxVJkFCCcVcDwpOAJPldHywULxhfQDu3+vwfchP0V7bMOd+eBwK799gfXERmuZROqxVRuNSRgd8a+TBOzOL7ckW66xyCBN+PT8sVro3P6ZJ9FE65f+opS+9Nz+nUK4Y7QhRNu8D4aUpwfJW8UrxUVl474Ni5YqdSPaARHzJsRi2H+Ft288mawzctsoV6xY/LUDh9d+p+qFR3BTVwyUnQC9NcrrBJl9CnHlsqMH2BXSP5Hr+UCP0Mnjq8UqBRIxk4WSx+4UmrtDzSAO4q1GA/Zo9SaXUyl2D/TodpkWqhgYJ9SdcyXITIhMISTCOtOAVHs1dzYkwKNf2Y+rvopfFXS037sAQm+k9MxyBpQyYaObZj+HS/k/QVwuIWOncyZOqcSb/DrLGiwEVe2aTSg/7YEFshnp0tswDhsNLv6jT9gRd4cB+cnVv3siZisvPpYIamH0=
distributions: sdist bdist_wheel
skip_cleanup: true
skip_existing: true
on:
tags: true
# Stable releases: only git tags on master branch
- provider: pypi
user: __token__
password: $PYPI_TOKEN
distributions: sdist bdist_wheel
skip_cleanup: true
skip_existing: true
# Only run in the job containing an encrypted PYPI_TOKEN
on:
tags: true
condition: $PYPI_TOKEN
# Pre-releases: dev branch only; pre-release version number is set in __init__.py
- provider: pypi
user: __token__
password: $PYPI_TOKEN
distributions: sdist
skip_cleanup: true
skip_existing: true
on:
branch: dev
condition: $PYPI_TOKEN
16 changes: 10 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@
pyinaturalist
=============================

.. image:: https://badge.fury.io/py/pyinaturalist.png
:target: http://badge.fury.io/py/pyinaturalist

.. image:: https://www.travis-ci.com/niconoe/pyinaturalist.svg?branch=master
:target: https://www.travis-ci.com/niconoe/pyinaturalist

:alt: Build Status
.. image:: https://readthedocs.org/projects/pyinaturalist/badge/?version=latest
:target: https://pyinaturalist.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status

.. image:: https://coveralls.io/repos/github/niconoe/pyinaturalist/badge.svg?branch=dev
:target: https://coveralls.io/github/niconoe/pyinaturalist?branch=dev

.. image:: https://img.shields.io/pypi/v/pyinaturalist?color=blue
:target: https://pypi.org/project/pyinaturalist
:alt: PyPI
.. image:: https://img.shields.io/pypi/pyversions/pyinaturalist
:target: https://pypi.org/project/pyinaturalist
:alt: PyPI - Python Version
.. image:: https://img.shields.io/pypi/format/pyinaturalist?color=blue
:target: https://pypi.org/project/pyinaturalist
:alt: PyPI - Format

Python client for the `iNaturalist APIs <https://www.inaturalist.org/pages/api+reference>`_.

Expand Down
10 changes: 0 additions & 10 deletions mypy.ini

This file was deleted.

35 changes: 29 additions & 6 deletions pyinaturalist/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
import logging
from logging import getLogger
from os import getenv

__author__ = "Nicolas Noé"
__email__ = "nicolas@niconoe.eu"
__version__ = "0.9.1"
__version__ = "0.10.0"

# These are imported here so they can be set with pyinaturalist.<variable>
from pyinaturalist.constants import DRY_RUN_ENABLED, DRY_RUN_WRITE_ONLY

DEFAULT_USER_AGENT = "Pyinaturalist/{version}".format(version=__version__)
user_agent = DEFAULT_USER_AGENT

# These are imported here so they can be set with pyinaturalist.<variable>
from pyinaturalist.constants import DRY_RUN_ENABLED, DRY_RUN_WRITE_ONLY

# Enable logging for urllib and other external loggers
logging.basicConfig(level="DEBUG")
def get_prerelease_version(version: str) -> str:
""" If we're running in a Travis CI job on the dev branch, get a prerelease version using the
current build number. For example: ``1.0.0 -> 1.0.0-dev.123``
This could also be done in ``.travis.yml``, but it's a bit cleaner to do in python, and
``semantic_version`` provides some extra sanity checks.
"""
if not (getenv("TRAVIS") == "true" and getenv("TRAVIS_BRANCH") == "dev"):
return version
# If we happen to be in a dev build, this will prevent the initial 'pip install' from failing
try:
from semantic_version import Version
except ImportError:
return version

new_version = Version(version)
new_version.prerelease = ("dev", getenv("TRAVIS_BUILD_NUMBER", "0"))
getLogger(__name__).info("Using pre-release version: {}".format(new_version))
return str(new_version)


# This won't modify the version outside of Travis
__version__ = get_prerelease_version(__version__)
13 changes: 13 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,18 @@ classifiers =
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7

# Tell mypy to ignore external libraries without type annotations
[mypy-pytest]
ignore_missing_imports = True

[mypy-requests_mock]
ignore_missing_imports = True

[mypy-semantic_version]
ignore_missing_imports = True

[mypy-setuptools]
ignore_missing_imports = True

[wheel]
universal = 1
13 changes: 9 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#!/usr/bin/env python
from sys import version_info
from setuptools import setup, find_packages
from pyinaturalist import __version__

# Only install the typing backport if we're on python < 3.5
backports = ["typing>=3.7.4"] if version_info < (3, 5) else []


setup(
name="pyinaturalist",
Expand All @@ -11,22 +15,23 @@
url="https://github.com/niconoe/pyinaturalist",
packages=find_packages(),
include_package_data=True,
install_requires=["python-dateutil>=2.0", "requests>=2.21.0", "typing>=3.7.4"],
install_requires=["python-dateutil>=2.0", "requests>=2.21.0"] + backports,
extras_require={
"dev": [
"black",
"coveralls",
"flake8",
"mypy",
"pytest",
"pytest-cov",
"requests-mock>=1.7",
"semantic-version",
"Sphinx",
"sphinx-autodoc-typehints",
"sphinx-rtd-theme",
"tox",
"twine",
]
],
# Additional packages used only within CI jobs
"build": ["coveralls", "semantic-version", "tox-travis"],
},
zip_safe=False,
)
3 changes: 3 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
Pytest will also automatically pick up any fixtures defined here.
"""
import json
import logging
import os
import re
from inspect import getmembers, isfunction, signature, Parameter
from unittest.mock import MagicMock

HTTP_FUNC_PATTERN = re.compile(r"(get|put|post|delete)_.+")
# Enable logging for urllib and other external loggers
logging.basicConfig(level="INFO")


def get_module_functions(module):
Expand Down
21 changes: 21 additions & 0 deletions test/test_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# A couple tests to make sure that versioning works as expected within Travis
# So, for example, the build would fail before accidentally publishing a bad version
from sys import version_info
from unittest.mock import patch
import pytest


# Mocking out getenv() instead of actually setting envars so this doesn't affect other tests
@patch("pyinaturalist.getenv", side_effect=["true", "master", "123"])
def test_version__stable_release(mock_getenv):
import pyinaturalist

assert "dev" not in pyinaturalist.__version__


@pytest.mark.skipif(version_info < (3, 6), reason="semantic-version requires python >= 3.6")
@patch("pyinaturalist.getenv", side_effect=["true", "dev", "123"])
def test_version__pre_release(mock_getenv):
import pyinaturalist

assert pyinaturalist.get_prerelease_version("1.0.0") == "1.0.0-dev.123"
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ commands =

[testenv:mypy]
commands =
mypy --config-file={toxinidir}/mypy.ini .
mypy --config-file={toxinidir}/setup.cfg .
printf '====================\n\n'

[testenv:style]
Expand Down

0 comments on commit cd97969

Please sign in to comment.