summaryrefslogtreecommitdiff
path: root/release.py
blob: 143853de95eb344bdce02d1363a3b1a349b10d98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
"""
This script will walk a developer through the process of cutting a release.

Based on https://bitbucket.org/cherrypy/cherrypy/wiki/ReleaseProcess

To cut a release, simply invoke this script at the changeset to be released.
"""

from __future__ import print_function

import subprocess
import sys
import os
import platform
import shutil
import importlib

from six.moves import input

VERSION='3.2.6'


def get_next_version():
    print("The last release on this branch was {version}".format(
        version=VERSION))
    return input("What version are you releasing? ")

NEXT_VERSION = get_next_version()

files_with_versions = (
    'release.py', 'setup.py', 'cherrypy/__init__.py',
                       'cherrypy/wsgiserver/wsgiserver2.py',
                       'cherrypy/wsgiserver/wsgiserver3.py',
                       )


def check_wheel():
    """
    Ensure 'wheel' is installed (required for bdist_wheel).
    """
    try:
        importlib.import_module('wheel')
    except ImportError:
        print("CherryPy requires 'wheel' be installed to produce wheels.",
              file=sys.stderr)
        raise SystemExit(5)


def check_status():
    """
    Make sure there aren't outstanding changesets that are unpushed, maybe
    run the tests or ask the user if the tests are passing.
    """
    print("You're about to release CherryPy {NEXT_VERSION}".format(
        **globals()))
    res = input('Have you run the tests with `nosetests -s ./` on '
                'Windows, Linux, and Mac on at least Python '
                '2.4, 2.5, 2.7, and 3.2? '
                .format(**globals()))
    if not res.lower().startswith('y'):
        print("Please do that")
        raise SystemExit(1)


def bump_versions():
    """
    Bump the versions in each of the places where it appears and commit.
    """
    list(map(bump_version, files_with_versions))

    subprocess.check_call(['hg', 'ci', '-m',
                           'Bumped to {NEXT_VERSION} in preparation for next '
                           'release.'.format(**globals())])


def bump_version(filename):
    with open(filename, 'rb') as f:
        b_version = VERSION.encode('ascii')
        b_next_version = NEXT_VERSION.encode('ascii')
        lines = [line.replace(b_version, b_next_version) for line in f]
    with open(filename, 'wb') as f:
        f.writelines(lines)


def tag_release():
    """
    Tag the release.
    """
    subprocess.check_call(['hg', 'tag', NEXT_VERSION])

dist_commands = ['sdist', 'bdist_wininst', 'bdist_wheel']


def build():
    if os.path.isfile('MANIFEST'):
        os.remove('MANIFEST')
    if os.path.isdir('dist'):
        shutil.rmtree('dist')
    subprocess.check_call([sys.executable, 'setup.py'] + dist_commands)


def push():
    "The build went well, so let's push the SCM changesets"
    subprocess.check_call(['hg', 'push', '-r', '.'])


def publish():
    """
    Publish the dists on PyPI
    """
    try:
        upload_dist_command = [sys.executable, 'setup.py'] + dist_commands + ['register', 'upload']
        subprocess.check_call(upload_dist_command)
    except:
        print("Unable to upload the dist files. Ask in IRC for help access 57"
              "or assistance.")
        raise SystemExit(4)
    print('Distributions have been uploaded.')
    print('Please ask in IRC for others to help you test '
          'CherryPy {NEXT_VERSION}.'
          .format(**globals()))
    print("Please confirm that the distro installs properly "
          "with `easy_install CherryPy=={NEXT_VERSION}`.".format(**globals()))


def announce():
    print("Please change the Wiki: Home page (news), CherryPyDownload")
    print("Please announce the release on newsgroups, mailing lists, "
          "and IRC /topic.")


def main():
    assert sys.version_info >= (2, 6), ("Release script requires Python 2.6 "
                                        "or later.")
    assert platform.system() == 'Windows', ('You must release on Windows '
                                            '(to create Windows installers)')
    check_wheel()
    check_status()
    bump_versions()
    tag_release()
    build()
    push()
    publish()
    announce()

if __name__ == '__main__':
    main()