From 42f14dfefb5c04f23f134328d50d76ffbf6de3ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Dudfield?= Date: Wed, 7 Mar 2018 15:43:50 +0100 Subject: [PATCH] Adding ability to deploy through travisci. And docs. --- .travis.yml | 49 +++++--- README.rst | 31 +++++ pygameweb/__init__.py | 2 +- pygameweb/builds/update_version_from_git.py | 118 ++++++++++++++++++++ requirements.dev.txt | 2 + setup.cfg | 2 + setup.py | 4 +- 7 files changed, 190 insertions(+), 18 deletions(-) create mode 100644 pygameweb/builds/update_version_from_git.py diff --git a/.travis.yml b/.travis.yml index 74f9670..4ae9af4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,33 +1,52 @@ - -# sudo required currently for postgresql 9.6 dist: trusty sudo: required services: - - postgresql +- postgresql before_install: - - sudo apt-get -qq update - - sudo apt-get install -y yui-compressor node optipng +- sudo apt-get -qq update +- sudo apt-get install -y yui-compressor node optipng before_script: - - cp example.env .env - - psql -c 'create database pygame_test;' -U postgres - - psql pygame_test -c "CREATE USER pygame_test WITH PASSWORD 'password';" -U postgres - - psql pygame_test -c "GRANT ALL PRIVILEGES ON DATABASE pygame_test to pygame_test;" -U postgres +- cp example.env .env +- psql -c 'create database pygame_test;' -U postgres +- psql pygame_test -c "CREATE USER pygame_test WITH PASSWORD 'password';" -U postgres +- psql pygame_test -c "GRANT ALL PRIVILEGES ON DATABASE pygame_test to pygame_test;" + -U postgres addons: - postgresql: "9.6" + postgresql: '9.6' test: adapter: postgresql database: pygame_test - language: python cache: pip python: - - "3.6" +- '3.6' install: - pip install -r requirements.dev.txt - pip install coveralls - pip install -e . - script: APP_SECRET_KEY=a pytest - after_success: - - coveralls +- coveralls +before_deploy: +- pwd +- ls -la +- pygameweb_release_version_correct +deploy: + - provider: pypi + user: illume + distributions: sdist bdist_wheel + on: + branch: + - master + - mastertest + password: + secure: gzDc/dK0FJnLtcYBDXRu4PiIc+DvTBLKRbClBlSVayCiH0k+TzjatjwRJm9EPK0ctR3QX4esBrlxlLHVVIhjt1fWe/UcN+JEmR0ICPaPmcqR+17j+tPBX3PyrV8aULWe/PG9MgTKEZw9S8ysGPThlcXlcO0h65ma5/a58NZIBEKyamjXgrZmuipfYlMRjyk54c53gZGI+jKn3R3mgk+pDcjI3vL5pkA6QU69ucBhg/iLLoicpiTkUTfewV6nNcUKj88j162wgXshQ2Rnl7prvekDOaYeNplZzLto8gYO+HxO95povzG8nTxgqs1Soip1vW8hyPj4hmWkYfsxQt88UJZhnNaE+Dy2Uv+YyhxT7x9xonLB/HewOf2QROKElJG8qJ9CM+/F4QbkyRHXl9eP0hDbMDzc4cxAiuDJ0y3XysZBkRcBQoj+moDlyCv4LTc/bXhvoUXjCsmAI3xRmrV0j4Ml8wgoqFxT/bLH3CLW2sRmYg6mE+OCGfjubyxQPrwHLDOOJykj2kB1GCDhl1Jn0iGyRXdKzykSJPO3LJVelMmiwZwbdED0Nih70buG6EsEOquZhZB+oGltjO2W9rbphaxnoUDTQVq+JFrXD1eACY/42HJ4RZ9gBo0SqRCuGGaaYgw2BCvqinRoH+5qfoXontlkGX/XFbKQP3+3agJ0K+M= + skip_cleanup: true + - provider: pypi + user: illume + distributions: sdist bdist_wheel + on: + tags: true + password: + secure: gzDc/dK0FJnLtcYBDXRu4PiIc+DvTBLKRbClBlSVayCiH0k+TzjatjwRJm9EPK0ctR3QX4esBrlxlLHVVIhjt1fWe/UcN+JEmR0ICPaPmcqR+17j+tPBX3PyrV8aULWe/PG9MgTKEZw9S8ysGPThlcXlcO0h65ma5/a58NZIBEKyamjXgrZmuipfYlMRjyk54c53gZGI+jKn3R3mgk+pDcjI3vL5pkA6QU69ucBhg/iLLoicpiTkUTfewV6nNcUKj88j162wgXshQ2Rnl7prvekDOaYeNplZzLto8gYO+HxO95povzG8nTxgqs1Soip1vW8hyPj4hmWkYfsxQt88UJZhnNaE+Dy2Uv+YyhxT7x9xonLB/HewOf2QROKElJG8qJ9CM+/F4QbkyRHXl9eP0hDbMDzc4cxAiuDJ0y3XysZBkRcBQoj+moDlyCv4LTc/bXhvoUXjCsmAI3xRmrV0j4Ml8wgoqFxT/bLH3CLW2sRmYg6mE+OCGfjubyxQPrwHLDOOJykj2kB1GCDhl1Jn0iGyRXdKzykSJPO3LJVelMmiwZwbdED0Nih70buG6EsEOquZhZB+oGltjO2W9rbphaxnoUDTQVq+JFrXD1eACY/42HJ4RZ9gBo0SqRCuGGaaYgw2BCvqinRoH+5qfoXontlkGX/XFbKQP3+3agJ0K+M= + skip_cleanup: true diff --git a/README.rst b/README.rst index ea08d78..1352644 100644 --- a/README.rst +++ b/README.rst @@ -226,3 +226,34 @@ With with a @cache decorator, and/or markup in a template. .. |coverage-status| image:: https://coveralls.io/repos/github/pygame/pygameweb/badge.svg?branch=master :target: https://coveralls.io/github/pygame/pygameweb?branch=master :alt: Test coverage percentage + + + + +Releases +======== + +Releases are done from travisci. Fairly closely following this: +https://docs.travis-ci.com/user/deployment/pypi/ + +- Commits to `master` branch do a dev deploy to pypi. +- Commits to `mastertest` branch do a dev deploy to pypi. +- Commits to a tag do a real deploy to pypi. + + +https://packaging.python.org/tutorials/distributing-packages/#pre-release-versioning + +Pre releases should be named like this: +``` +# pygameweb/__init__.py +__version__ = '0.0.2' +``` +Which is one version ahead of of the last tagged release. + +Release tags should be like '0.0.2', and match the `pygameweb/__init__.py __version__`. + +When everything is ready, tags should be done through github. + +Note: do not tag pre releases (these are made on commits to `master`/`mastertest`). +https://help.github.com/articles/creating-releases/ + diff --git a/pygameweb/__init__.py b/pygameweb/__init__.py index ec3388b..d76a13c 100644 --- a/pygameweb/__init__.py +++ b/pygameweb/__init__.py @@ -1,4 +1,4 @@ -__version__ = '0.0.1' +__version__ = '0.0.2' # So we can use environment variables to configure things. diff --git a/pygameweb/builds/update_version_from_git.py b/pygameweb/builds/update_version_from_git.py new file mode 100644 index 0000000..db7ec9e --- /dev/null +++ b/pygameweb/builds/update_version_from_git.py @@ -0,0 +1,118 @@ +"""For updating the version from git. + +__init__.py contains a __version__ field. +Update that. + + +If we are on master, we want to update the version as a pre-release. +git describe --tags + + + +With these: + __init__.py + __version__= '0.0.2' + git describe --tags + 0.0.1-22-g729a5ae + +We want this: + __init__.py + __version__= '0.0.2.dev22.g729a5ae' + +Get the branch/tag name with this. + git symbolic-ref -q --short HEAD || git describe --tags --exact-match + + + +""" + +import io +import os +import pathlib +import re +import subprocess + +def migrate_source_attribute(attr, to_this, target_file, regex): + """Updates __magic__ attributes in the source file""" + change_this = re.compile(regex, re.S) + new_file = [] + found = False + + with open(target_file, 'r') as fp: + lines = fp.readlines() + + for line in lines: + if line.startswith(attr): + found = True + line = re.sub(change_this, to_this, line) + new_file.append(line) + + if found: + with open(target_file, 'w') as fp: + fp.writelines(new_file) + +def migrate_version(target_file, new_version): + """Updates __version__ in the source file""" + regex = r"(?:(\d+\.(?:\d+\.)*\d+))" + migrate_source_attribute('__version__', new_version, target_file, regex) + + +def is_master_or_mastertest(): + cmd = ('git rev-parse --abbrev-ref HEAD') + tag_branch = subprocess.check_output(cmd, shell=True) + return tag_branch in [b'master\n', b'mastertest\n'] + +def git_tag_name(): + cmd = ('git describe --tags') + tag_branch = subprocess.check_output(cmd, shell=True) + tag_branch = tag_branch.decode().strip() + return tag_branch + +def prerelease_version(): + """ return what the prerelease version should be. + 0.0.2.dev22+22.g729a5ae + """ + cmd = 'git describe --tags' + ver_str = subprocess.check_output(cmd, shell=True) + ver, commits_since, githash = ver_str.decode().strip().split('-') + initpy_ver = get_version() + assert len(initpy_ver.split('.')) == 3, 'pygameweb/__init__.py version should be like 0.0.2' + assert initpy_ver > ver, 'the pygameweb/__init__.py version should be newer than the last tagged release.' + return f'{initpy_ver}.dev{commits_since}+{commits_since}.{githash}' + +def read(*parts): + """ Reads in file from *parts. + """ + try: + return io.open(os.path.join(*parts), 'r', encoding='utf-8').read() + except IOError: + return '' + +def get_version(): + """ Returns version from pygameweb/__init__.py + """ + version_file = read('pygameweb', '__init__.py') + version_match = re.search(r'^__version__ = [\'"]([^\'"]*)[\'"]', + version_file, re.MULTILINE) + if version_match: + return version_match.group(1) + raise RuntimeError('Unable to find version string.') + + +def release_version_correct(): + """Makes sure the: + - prerelease verion for master is correct. + - release version is correct for tags. + """ + if is_master_or_mastertest(): + # update for a pre release version. + initpy = pathlib.Path('pygameweb') / '__init__.py' + + if initpy.exists(): + target_version = str(initpy.absolute()) + new_version = prerelease_version() + print(f'updating version in {initpy} from {target_version} to {new_version}') + migrate_version(target_version, new_version) + else: + # check that we are a tag with the same version as in __init__.py + assert get_version() == git_tag_name(), 'git tag/branch name not the same as pygame/__init__.py __verion__' diff --git a/requirements.dev.txt b/requirements.dev.txt index e4ad76c..794d521 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -14,4 +14,6 @@ pytest-pylint pytest-timeout pytest-watch pytest-xdist +twine +wheel -r requirements.txt diff --git a/setup.cfg b/setup.cfg index 703f2af..8cd1a8c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -9,3 +9,5 @@ addopts=-v --cov pygameweb pygameweb/ tests/ +[bdist_wheel] +universal=1 diff --git a/setup.py b/setup.py index 075e981..aee6124 100644 --- a/setup.py +++ b/setup.py @@ -41,8 +41,6 @@ def get_requirements(): name='pygameweb', classifiers=[ 'Development Status :: 1 - Planning', - 'Classifier: Framework :: Flask', - 'Classifier: License :: OSI Approved', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.6', @@ -80,6 +78,8 @@ def get_requirements(): 'pygameweb.comment.classifier_train:classify_comments', 'pygameweb_worker=' 'pygameweb.tasks.worker:work', + 'pygameweb_release_version_correct=' + 'pygameweb.builds.update_version_from_git:release_version_correct', ], }, )