Skip to content

Commit feab3ba

Browse files
committed
Implement tasks to improve release automation
1 parent 00e7ee5 commit feab3ba

File tree

3 files changed

+83
-23
lines changed

3 files changed

+83
-23
lines changed

HOWTORELEASE.rst

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
How to release pytest
22
--------------------------------------------
33

4-
Note: this assumes you have already registered on PyPI and you have
5-
`invoke <https://pypi.org/project/invoke/>`_ installed.
4+
.. important::
65

7-
#. Check and finalize ``CHANGELOG.rst``.
6+
pytest releases must be prepared on **linux** because the docs and examples expect
7+
to be executed in that platform.
88

9-
#. Generate a new release announcement::
9+
#. Install development dependencies in a virtual environment with::
1010

11-
invoke generate.announce VERSION
11+
pip3 install -r tasks/requirements.txt
1212

13-
Feel free to modify the generated files before committing.
13+
#. Create a branch ``release-X.Y.Z`` with the version for the release. Make sure it is up to date
14+
with the latest ``master`` (for patch releases) and with the latest ``features`` merged with
15+
the latest ``master`` (for minor releases). Ensure your are in a clean work tree.
1416

15-
#. Regenerate the docs examples using tox::
17+
#. Check and finalize ``CHANGELOG.rst`` (will be automated soon).
1618

17-
tox -e regen
19+
#. Execute to automatically generate docs, announcements and upload a package to
20+
your ``devpi`` staging server::
1821

19-
#. At this point, open a PR named ``release-X`` so others can help find regressions or provide suggestions.
22+
invoke generate.pre_release <VERSION> <DEVPI USER> --password <DEVPI PASSWORD>
2023

21-
#. Use devpi for uploading a release tarball to a staging area::
22-
23-
devpi use https://devpi.net/USER/dev
24-
devpi upload --formats sdist,bdist_wheel
24+
If ``--password`` is not given, it is assumed the user is already logged in. If you don't have
25+
an account, please ask for one!
2526

2627
#. Run from multiple machines::
2728

tasks/generate.py

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import os
12
from pathlib import Path
2-
from subprocess import check_output
3+
from subprocess import check_output, check_call
34

45
import invoke
56

@@ -9,11 +10,7 @@
910
})
1011
def announce(ctx, version):
1112
"""Generates a new release announcement entry in the docs."""
12-
print("[generate.announce] Generating Announce")
13-
1413
# Get our list of authors
15-
print("[generate.announce] Collecting author names")
16-
1714
stdout = check_output(["git", "describe", "--abbrev=0", '--tags'])
1815
stdout = stdout.decode('utf-8')
1916
last_version = stdout.strip()
@@ -29,12 +26,12 @@ def announce(ctx, version):
2926
contributors_text = '\n'.join('* {}'.format(name) for name in sorted(contributors)) + '\n'
3027
text = template_text.format(version=version, contributors=contributors_text)
3128

32-
target = Path(__file__).joinpath('../../doc/en/announce/release-{}.rst'.format(version))
29+
target = Path(__file__).parent.joinpath('../doc/en/announce/release-{}.rst'.format(version))
3330
target.write_text(text, encoding='UTF-8')
3431
print("[generate.announce] Generated {}".format(target.name))
3532

3633
# Update index with the new release entry
37-
index_path = Path(__file__).joinpath('../../doc/en/announce/index.rst')
34+
index_path = Path(__file__).parent.joinpath('../doc/en/announce/index.rst')
3835
lines = index_path.read_text(encoding='UTF-8').splitlines()
3936
indent = ' '
4037
for index, line in enumerate(lines):
@@ -48,9 +45,68 @@ def announce(ctx, version):
4845
print("[generate.announce] Skip {} (already contains release)".format(index_path.name))
4946
break
5047

51-
print()
52-
print('Please review the generated files and commit with:')
53-
print(' git commit -a -m "Generate new release announcement for {}'.format(version))
48+
check_call(['git', 'add', str(target)])
49+
50+
51+
@invoke.task()
52+
def regen(ctx):
53+
"""Call regendoc tool to update examples and pytest output in the docs."""
54+
print("[generate.regen] Updating docs")
55+
check_call(['tox', '-e', 'regen'])
56+
57+
58+
@invoke.task()
59+
def make_tag(ctx, version):
60+
"""Create a new (local) tag for the release, only if the repository is clean."""
61+
from git import Repo
62+
63+
repo = Repo('.')
64+
if repo.is_dirty():
65+
print('Current repository is dirty. Please commit any changes and try again.')
66+
raise invoke.Exit(code=2)
67+
68+
tag_names = [x.name for x in repo.tags]
69+
if version in tag_names:
70+
print("[generate.make_tag] Delete existing tag {}".format(version))
71+
repo.delete_tag(version)
72+
73+
print("[generate.make_tag] Create tag {}".format(version))
74+
repo.create_tag(version)
5475

5576

77+
@invoke.task()
78+
def devpi_upload(ctx, version, user, password=None):
79+
"""Creates and uploads a package to devpi for testing."""
80+
if password:
81+
print("[generate.devpi_upload] devpi login {}".format(user))
82+
check_call(['devpi', 'login', user, '--password', password])
83+
84+
check_call(['devpi', 'use', 'https://devpi.net/{}/dev'.format(user)])
85+
86+
env = os.environ.copy()
87+
env['SETUPTOOLS_SCM_PRETEND_VERSION'] = version
88+
check_call(['devpi', 'upload', '--formats', 'sdist,bdist_wheel'], env=env)
89+
print("[generate.devpi_upload] package uploaded")
90+
91+
92+
@invoke.task(help={
93+
'version': 'version being released',
94+
'user': 'name of the user on devpi to stage the generated package',
95+
'password': 'user password on devpi to stage the generated package '
96+
'(if not given assumed logged in)',
97+
})
98+
def pre_release(ctx, version, user, password=None):
99+
"""Generates new docs, release announcements and uploads a new release to devpi for testing."""
100+
announce(ctx, version)
101+
regen(ctx)
102+
103+
msg = 'Preparing release version {}'.format(version)
104+
check_call(['git', 'commit', '-a', '-m', msg])
105+
106+
make_tag(ctx, version)
107+
108+
devpi_upload(ctx, version=version, user=user, password=password)
109+
110+
print()
111+
print('[generate.pre_release] Please push your branch and open a PR.')
56112

tasks/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
invoke
2+
tox
3+
gitpython

0 commit comments

Comments
 (0)