Skip to content

Commit 2f0aeea

Browse files
Merge pull request #31 from adamtheturtle/pypi-test
Add an initial release process
2 parents 5354f67 + 4074fcd commit 2f0aeea

File tree

8 files changed

+163
-4
lines changed

8 files changed

+163
-4
lines changed

CHANGELOG.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Changelog
2+
=========
3+
4+
.. contents::
5+
6+
Next
7+
----
8+
9+
- Initial release

CONTRIBUTING.rst

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,5 +191,35 @@ However, JPEG images up to 2MiB are accepted.
191191
Performing a release
192192
--------------------
193193

194-
There is currently no release process.
195-
See `this issue <https://github.com/adamtheturtle/vws-python-mock/issues/12>`__ for details.
194+
Outcomes
195+
~~~~~~~~
196+
197+
* A new ``git`` tag available to install.
198+
199+
Prerequisites
200+
~~~~~~~~~~~~~
201+
202+
* ``python3`` on your ``PATH`` set to Python 3.5+.
203+
* ``virtualenv``.
204+
* Push access to this repository.
205+
* Trust that ``master`` is ready and high enough quality for release.
206+
207+
Perform a Release
208+
~~~~~~~~~~~~~~~~~
209+
210+
#. Get a GitHub access token:
211+
212+
Follow the `GitHub instructions <https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/>`__ for getting an access token.
213+
214+
#. Set environment variables to GitHub credentials, e.g.:
215+
216+
.. code:: sh
217+
218+
export GITHUB_TOKEN=75c72ad718d9c346c13d30ce762f121647b502414
219+
export GITHUB_OWNER=adamtheturtle
220+
221+
#. Perform a release:
222+
223+
.. code:: sh
224+
225+
curl https://raw.githubusercontent.com/"$GITHUB_OWNER"/vws-python-mock/master/admin/release.sh | bash

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ lint:
2727
dodgy
2828
flake8 .
2929
isort --recursive --check-only
30-
mypy src/ tests/ ci/
30+
mypy src/ tests/ ci/ admin
3131
pip-extra-reqs src/
3232
pip-missing-reqs src/
3333
pydocstyle
34-
pylint *.py src tests ci
34+
pylint *.py src tests ci admin
3535
pyroma --min 10 .
3636
vulture . --min-confidence 100
3737
yapf \

admin/__init__.py

Whitespace-only changes.

admin/release.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
"""
2+
Release the next version of VWS Python Mock.
3+
"""
4+
5+
import datetime
6+
import os
7+
from pathlib import Path
8+
9+
from dulwich.porcelain import add, commit, push, tag_list
10+
from dulwich.repo import Repo
11+
from github import Github, Repository, UnknownObjectException
12+
13+
14+
def get_version() -> str:
15+
"""
16+
Returns the next version of VWS Python Mock.
17+
This is today’s date in the format ``YYYY.MM.DD.MICRO``.
18+
``MICRO`` refers to the number of releases created on this date,
19+
starting from ``0``.
20+
"""
21+
utc_now = datetime.datetime.utcnow()
22+
date_format = '%Y.%m.%d'
23+
date_str = utc_now.strftime(date_format)
24+
local_repository = Repo('.')
25+
tag_labels = tag_list(repo=local_repository)
26+
tag_labels = [item.decode() for item in tag_labels]
27+
today_tag_labels = [
28+
item for item in tag_labels if item.startswith(date_str)
29+
]
30+
micro = int(len(today_tag_labels))
31+
return '{date}.{micro}'.format(date=date_str, micro=micro)
32+
33+
34+
def update_changelog(version: str) -> None:
35+
"""
36+
Add a version title to the changelog.
37+
"""
38+
changelog = Path('CHANGELOG.rst')
39+
changelog_contents = changelog.read_text()
40+
new_changelog_contents = changelog_contents.replace(
41+
'Next\n----',
42+
'Next\n----\n\n{version}\n------------'.format(version=version),
43+
)
44+
changelog.write_text(new_changelog_contents)
45+
46+
47+
def create_github_release(
48+
repository: Repository,
49+
version: str,
50+
) -> None:
51+
"""
52+
Create a tag and release on GitHub.
53+
"""
54+
changelog_url = (
55+
'https://vws-python-mock.readthedocs.io/en/latest/changelog.html'
56+
)
57+
repository.create_git_tag_and_release(
58+
tag=version,
59+
tag_message='Release ' + version,
60+
release_name='Release ' + version,
61+
release_message='See ' + changelog_url,
62+
type='commit',
63+
object=repository.get_commits()[0].sha,
64+
)
65+
66+
67+
def commit_and_push(version: str, repository: Repository) -> None:
68+
"""
69+
Commit and push all changes.
70+
"""
71+
local_repository = Repo('.')
72+
paths = ['CHANGELOG.rst']
73+
_, ignored = add(paths=paths)
74+
assert not ignored
75+
message = b'Update for release ' + version.encode('utf-8')
76+
commit(message=message)
77+
branch_name = 'master'
78+
push(
79+
repo=local_repository,
80+
remote_location=repository.ssh_url,
81+
refspecs=branch_name.encode('utf-8'),
82+
)
83+
84+
85+
def get_repo(github_token: str, github_owner: str) -> Repository:
86+
"""
87+
Get a GitHub repository.
88+
"""
89+
github_client = Github(github_token)
90+
try:
91+
github_user_or_org = github_client.get_organization(github_owner)
92+
except UnknownObjectException:
93+
github_user_or_org = github_client.get_user(github_owner)
94+
95+
return github_user_or_org.get_repo('vws-python-mock')
96+
97+
98+
def main() -> None:
99+
"""
100+
Perform a release.
101+
"""
102+
github_token = os.environ['GITHUB_TOKEN']
103+
github_owner = os.environ['GITHUB_OWNER']
104+
repository = get_repo(github_token=github_token, github_owner=github_owner)
105+
version_str = get_version()
106+
update_changelog(version=version_str)
107+
commit_and_push(version=version_str, repository=repository)
108+
create_github_release(
109+
repository=repository,
110+
version=version_str,
111+
)
112+
113+
114+
if __name__ == '__main__':
115+
main()

dev-requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ autoflake==1.2
33
check-manifest==0.37
44
codecov==2.0.15 # Upload coverage data
55
dodgy==0.1.9 # Look for uploaded secrets
6+
dulwich==0.19.6
67
flake8==3.5.0 # Lint
78
flake8-commas==2.0.0 # Require silicon valley commas
89
flake8-quotes==1.0.0 # Require single quotes
@@ -13,6 +14,7 @@ mypy==0.620 # Type checking
1314
pip_check_reqs==2.0.3
1415
pydocstyle==2.1.1 # Lint docstrings
1516
pyenchant==2.0.0 # Bindings for a spellchecking sytem
17+
pygithub==1.43
1618
pylint==2.1.1 # Lint
1719
pyroma==2.4 # Packaging best practices checker
1820
pytest-cov==2.6.0 # Measure code coverage

setup.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ ignore =
88
.remarkrc
99
.style.yapf
1010
.travis.yml
11+
admin
12+
admin/*
1113
CHANGELOG.rst
1214
CODE_OF_CONDUCT.rst
1315
CONTRIBUTING.rst

spelling_private_dict.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ ascii
44
bool
55
boolean
66
bytesio
7+
changelog
78
chunked
89
cmyk
910
connectionerror

0 commit comments

Comments
 (0)