Skip to content

Add an initial release process #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Changelog
=========

.. contents::

Next
----

- Initial release
34 changes: 32 additions & 2 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -191,5 +191,35 @@ However, JPEG images up to 2MiB are accepted.
Performing a release
--------------------

There is currently no release process.
See `this issue <https://github.com/adamtheturtle/vws-python-mock/issues/12>`__ for details.
Outcomes
~~~~~~~~

* A new ``git`` tag available to install.

Prerequisites
~~~~~~~~~~~~~

* ``python3`` on your ``PATH`` set to Python 3.5+.
* ``virtualenv``.
* Push access to this repository.
* Trust that ``master`` is ready and high enough quality for release.

Perform a Release
~~~~~~~~~~~~~~~~~

#. Get a GitHub access token:

Follow the `GitHub instructions <https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/>`__ for getting an access token.

#. Set environment variables to GitHub credentials, e.g.:

.. code:: sh

export GITHUB_TOKEN=75c72ad718d9c346c13d30ce762f121647b502414
export GITHUB_OWNER=adamtheturtle

#. Perform a release:

.. code:: sh

curl https://raw.githubusercontent.com/"$GITHUB_OWNER"/vws-python-mock/master/admin/release.sh | bash
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ lint:
dodgy
flake8 .
isort --recursive --check-only
mypy src/ tests/ ci/
mypy src/ tests/ ci/ admin
pip-extra-reqs src/
pip-missing-reqs src/
pydocstyle
pylint *.py src tests ci
pylint *.py src tests ci admin
pyroma --min 10 .
vulture . --min-confidence 100
yapf \
Expand Down
Empty file added admin/__init__.py
Empty file.
115 changes: 115 additions & 0 deletions admin/release.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
"""
Release the next version of VWS Python Mock.
"""

import datetime
import os
from pathlib import Path

from dulwich.porcelain import add, commit, push, tag_list
from dulwich.repo import Repo
from github import Github, Repository, UnknownObjectException


def get_version() -> str:
"""
Returns the next version of VWS Python Mock.
This is today’s date in the format ``YYYY.MM.DD.MICRO``.
``MICRO`` refers to the number of releases created on this date,
starting from ``0``.
"""
utc_now = datetime.datetime.utcnow()
date_format = '%Y.%m.%d'
date_str = utc_now.strftime(date_format)
local_repository = Repo('.')
tag_labels = tag_list(repo=local_repository)
tag_labels = [item.decode() for item in tag_labels]
today_tag_labels = [
item for item in tag_labels if item.startswith(date_str)
]
micro = int(len(today_tag_labels))
return '{date}.{micro}'.format(date=date_str, micro=micro)


def update_changelog(version: str) -> None:
"""
Add a version title to the changelog.
"""
changelog = Path('CHANGELOG.rst')
changelog_contents = changelog.read_text()
new_changelog_contents = changelog_contents.replace(
'Next\n----',
'Next\n----\n\n{version}\n------------'.format(version=version),
)
changelog.write_text(new_changelog_contents)


def create_github_release(
repository: Repository,
version: str,
) -> None:
"""
Create a tag and release on GitHub.
"""
changelog_url = (
'https://vws-python-mock.readthedocs.io/en/latest/changelog.html'
)
repository.create_git_tag_and_release(
tag=version,
tag_message='Release ' + version,
release_name='Release ' + version,
release_message='See ' + changelog_url,
type='commit',
object=repository.get_commits()[0].sha,
)


def commit_and_push(version: str, repository: Repository) -> None:
"""
Commit and push all changes.
"""
local_repository = Repo('.')
paths = ['CHANGELOG.rst']
_, ignored = add(paths=paths)
assert not ignored
message = b'Update for release ' + version.encode('utf-8')
commit(message=message)
branch_name = 'master'
push(
repo=local_repository,
remote_location=repository.ssh_url,
refspecs=branch_name.encode('utf-8'),
)


def get_repo(github_token: str, github_owner: str) -> Repository:
"""
Get a GitHub repository.
"""
github_client = Github(github_token)
try:
github_user_or_org = github_client.get_organization(github_owner)
except UnknownObjectException:
github_user_or_org = github_client.get_user(github_owner)

return github_user_or_org.get_repo('vws-python-mock')


def main() -> None:
"""
Perform a release.
"""
github_token = os.environ['GITHUB_TOKEN']
github_owner = os.environ['GITHUB_OWNER']
repository = get_repo(github_token=github_token, github_owner=github_owner)
version_str = get_version()
update_changelog(version=version_str)
commit_and_push(version=version_str, repository=repository)
create_github_release(
repository=repository,
version=version_str,
)


if __name__ == '__main__':
main()
2 changes: 2 additions & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ autoflake==1.2
check-manifest==0.37
codecov==2.0.15 # Upload coverage data
dodgy==0.1.9 # Look for uploaded secrets
dulwich==0.19.6
flake8==3.5.0 # Lint
flake8-commas==2.0.0 # Require silicon valley commas
flake8-quotes==1.0.0 # Require single quotes
Expand All @@ -13,6 +14,7 @@ mypy==0.620 # Type checking
pip_check_reqs==2.0.3
pydocstyle==2.1.1 # Lint docstrings
pyenchant==2.0.0 # Bindings for a spellchecking sytem
pygithub==1.43
pylint==2.1.1 # Lint
pyroma==2.4 # Packaging best practices checker
pytest-cov==2.6.0 # Measure code coverage
Expand Down
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ ignore =
.remarkrc
.style.yapf
.travis.yml
admin
admin/*
CHANGELOG.rst
CODE_OF_CONDUCT.rst
CONTRIBUTING.rst
Expand Down
1 change: 1 addition & 0 deletions spelling_private_dict.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ ascii
bool
boolean
bytesio
changelog
chunked
cmyk
connectionerror
Expand Down