##// END OF EJS Templates
Merge pull request #10241 from takluyver/release-integrate-twine...
Matthias Bussonnier -
r23304:a1a338f2 merge
parent child Browse files
Show More
@@ -1,259 +1,246 b''
1 1 .. _release_process:
2 2
3 3 =======================
4 4 IPython release process
5 5 =======================
6 6
7 7 This document contains the process that is used to create an IPython release.
8 8
9 9 Conveniently, the ``release`` script in the ``tools`` directory of the ``IPython``
10 10 repository automates most of the release process. This document serves as a
11 11 handy reminder and checklist for the release manager.
12 12
13 13 During the release process, you might need the extra following dependencies:
14 14
15 15 - ``keyring`` to access your GitHub authentication tokens
16 16 - ``graphviz`` to generate some graphs in the documentation
17 17
18 18 Make sure you have all the required dependencies to run the tests as well.
19 19
20 20
21 21 1. Set Environment variables
22 22 ----------------------------
23 23
24 24 Set environment variables to document previous release tag, current
25 25 release milestone, current release version, and git tag.
26 26
27 27 These variables may be used later to copy/paste as answers to the script
28 28 questions instead of typing the appropriate command when the time comes. These
29 29 variables are not used by the scripts directly; therefore, there is no need to
30 30 ``export`` them. The format for bash is as follows, but note that these values
31 31 are just an example valid only for the 5.0 release; you'll need to update them
32 32 for the release you are actually making::
33 33
34 34 PREV_RELEASE=4.2.1
35 35 MILESTONE=5.0
36 36 VERSION=5.0.0
37 37 BRANCH=master
38 38
39 39
40 40 2. Create GitHub stats and finish release note
41 41 ----------------------------------------------
42 42
43 43 .. note::
44 44
45 45 This step is optional if making a Beta or RC release.
46 46
47 47 .. note::
48 48
49 49 Before generating the GitHub stats, verify that all closed issues and pull
50 50 requests have `appropriate milestones
51 51 <https://github.com/ipython/ipython/wiki/Dev:-GitHub-workflow#milestones>`_.
52 52 `This search
53 53 <https://github.com/ipython/ipython/issues?q=is%3Aclosed+no%3Amilestone+is%3Aissue>`_
54 54 should return no results before creating the GitHub stats.
55 55
56 56 If a major release:
57 57
58 58 - merge any pull request notes into what's new::
59 59
60 60 python tools/update_whatsnew.py
61 61
62 62 - update ``docs/source/whatsnew/development.rst``, to ensure it covers
63 63 the major release features
64 64
65 65 - move the contents of ``development.rst`` to ``versionX.rst`` where ``X`` is
66 66 the numerical release version
67 67
68 68 - generate summary of GitHub contributions, which can be done with::
69 69
70 70 python tools/github_stats.py --milestone $MILESTONE > stats.rst
71 71
72 72 which may need some manual cleanup of ``stats.rst``. Add the cleaned
73 73 ``stats.rst`` results to ``docs/source/whatsnew/github-stats-X.rst``
74 74 where ``X`` is the numerical release version (don't forget to add it to
75 75 the git repo as well). If creating a major release, make a new
76 76 ``github-stats-X.rst`` file; if creating a minor release, the content
77 77 from ``stats.rst`` may simply be added to the top of an existing
78 78 ``github-stats-X.rst`` file. Finally, edit
79 79 ``docs/source/whatsnew/index.rst`` to list the new ``github-stats-X``
80 80 file you just created and remove temporarily the first entry called
81 81 ``development`` (you'll need to add it back after release).
82 82
83 83 Make sure that the stats file has a header or it won't be rendered in
84 84 the final documentation.
85 85
86 86 To find duplicates and update `.mailmap`, use::
87 87
88 88 git log --format="%aN <%aE>" $PREV_RELEASE... | sort -u -f
89 89
90 90 If a minor release you might need to do some of the above points manually, and
91 91 forward port the changes.
92 92
93 93 3. Make sure the repository is clean
94 94 ------------------------------------
95 95
96 96 of any file that could be problematic.
97 97 Remove all non-tracked files with:
98 98
99 99 .. code::
100 100
101 101 git clean -xfdi
102 102
103 103 This will ask for confirmation before removing all untracked files. Make
104 104 sure the ``dist/`` folder is clean to avoid any stale builds from
105 105 previous build attempts.
106 106
107 107
108 108 4. Update the release version number
109 109 ------------------------------------
110 110
111 111 Edit ``IPython/core/release.py`` to have the current version.
112 112
113 113 in particular, update version number and ``_version_extra`` content in
114 114 ``IPython/core/release.py``.
115 115
116 116 Step 5 will validate your changes automatically, but you might still want to
117 117 make sure the version number matches pep440.
118 118
119 119 In particular, ``rc`` and ``beta`` are not separated by ``.`` or the ``sdist``
120 120 and ``bdist`` will appear as different releases. For example, a valid version
121 121 number for a release candidate (rc) release is: ``1.3rc1``. Notice that there
122 122 is no separator between the '3' and the 'r'. Check the environment variable
123 123 ``$VERSION`` as well.
124 124
125 125 You will likely just have to modify/comment/uncomment one of the lines setting
126 126 ``_version_extra``
127 127
128 128
129 129 5. Run the `tools/build_release` script
130 130 ---------------------------------------
131 131
132 132 Running ``tools/build_release`` does all the file checking and building that
133 133 the real release script will do. This makes test installations, checks that
134 134 the build procedure runs OK, and tests other steps in the release process.
135 135
136 136 The ``build_release`` script will in particular verify that the version number
137 137 match PEP 440, in order to avoid surprise at the time of build upload.
138 138
139 139 We encourage creating a test build of the docs as well.
140 140
141 141 6. Create and push the new tag
142 142 ------------------------------
143 143
144 144 Commit the changes to release.py::
145 145
146 146 git commit -am "release $VERSION"
147 147 git push origin $BRANCH
148 148
149 149 Create and push the tag::
150 150
151 151 git tag -am "release $VERSION" "$VERSION"
152 152 git push origin --tags
153 153
154 154 Update release.py back to ``x.y-dev`` or ``x.y-maint``, and re-add the
155 155 ``development`` entry in ``docs/source/whatsnew/index.rst`` and push::
156 156
157 157 git commit -am "back to development"
158 158 git push origin $BRANCH
159 159
160 160 7. Get a fresh clone
161 161 --------------------
162 162
163 163 Get a fresh clone of the tag for building the release::
164 164
165 165 cd /tmp
166 166 git clone --depth 1 https://github.com/ipython/ipython.git -b "$VERSION"
167 167 cd ipython
168 168
169 169 .. note::
170 170
171 You can aslo cleanup the current working repository with ``git clean -xfdi``
171 You can also cleanup the current working repository with ``git clean -xfdi``
172 172
173 173 8. Run the release script
174 174 -------------------------
175 175
176 .. important::
177
178 These steps cover instructions for creating releases of IPython 5.x LTS and
179 IPython 6.x. Ignore release steps for Python 2 when releasing IPython 6.x
180 which no longer supports Python 2.
181
182 176 Run the ``release`` script, this step requires having a current wheel, Python
183 177 >=3.4 and Python 2.7.::
184 178
185 179 ./tools/release
186 180
187 181 This makes the tarballs and wheels, and puts them under the ``dist/``
188 182 folder. Be sure to test the ``wheels`` and the ``sdist`` locally before
189 183 uploading them to PyPI. We do not use an universal wheel as each wheel
190 184 installs an ``ipython2`` or ``ipython3`` script, depending on the version of
191 185 Python it is built for. Using an universal wheel would prevent this.
192 186
193 187 Use the following to actually upload the result of the build::
194 188
195 189 ./tools/release upload
196 190
197 It should posts them to ``archive.ipython.org``.
198
199 You will need to use `twine <https://github.com/pypa/twine>`_ ) manually to
200 actually upload on PyPI. Unlike setuptools, twine is able to upload packages
201 over SSL::
202
203 twine upload dist/*
204
191 It should posts them to ``archive.ipython.org`` and to PyPI.
205 192
206 193 PyPI/Warehouse will automatically hide previous releases. If you are uploading
207 194 a non-stable version, make sure to log-in to PyPI and un-hide previous version.
208 195
209 196
210 197 9. Draft a short release announcement
211 198 -------------------------------------
212 199
213 200 The announcement should include:
214 201
215 202 - release highlights
216 203 - a link to the html version of the *What's new* section of the documentation
217 204 - a link to upgrade or installation tips (if necessary)
218 205
219 206 Post the announcement to the mailing list and or blog, and link from Twitter.
220 207
221 208 .. note::
222 209
223 210 If you are doing a RC or Beta, you can likely skip the next steps.
224 211
225 212 10. Update milestones on GitHub
226 213 -------------------------------
227 214
228 215 These steps will bring milestones up to date:
229 216
230 217 - close the just released milestone
231 218 - open a new milestone for the next release (x, y+1), if the milestone doesn't
232 219 exist already
233 220
234 221 11. Update the IPython website
235 222 ------------------------------
236 223
237 224 The IPython website should document the new release:
238 225
239 226 - add release announcement (news, announcements)
240 227 - update current version and download links
241 228 - update links on the documentation page (especially if a major release)
242 229
243 230 12. Update readthedocs
244 231 ----------------------
245 232
246 233 Make sure to update readthedocs and set the latest tag as stable, as well as
247 234 checking that previous release is still building under its own tag.
248 235
249 236 13. Update the Conda-Forge feedstock
250 237 ------------------------------------
251 238
252 239 Follow the instructions on `the repository <https://github.com/conda-forge/ipython-feedstock>`_
253 240
254 241 14. Celebrate!
255 242 --------------
256 243
257 244 Celebrate the release and please thank the contributors for their work. Great
258 245 job!
259 246
@@ -1,89 +1,94 b''
1 1 #!/usr/bin/env python
2 2 """IPython release script.
3 3
4 4 This should ONLY be run at real release time.
5 5 """
6 6 from __future__ import print_function
7 7
8 8 import os
9 from subprocess import call
9 10 import sys
10 11
11 12 from toollib import (get_ipdir, pjoin, cd, execfile, sh, archive,
12 13 sdists, archive_user, archive_dir, buildwheels)
13 14 from gh_api import post_download
14 15
15 16 # Get main ipython dir, this will raise if it doesn't pass some checks
16 17 ipdir = get_ipdir()
17 18 tooldir = pjoin(ipdir, 'tools')
18 19 distdir = pjoin(ipdir, 'dist')
19 20
20 21 # Where I keep static backups of each release
21 22 ipbackupdir = os.path.expanduser('~/ipython/backup')
22 23 if not os.path.exists(ipbackupdir):
23 24 os.makedirs(ipbackupdir)
24 25
25 26 # Start in main IPython dir
26 27 cd(ipdir)
27 28
28 29 # Load release info
29 30 version = None
30 31 execfile(pjoin('IPython','core','release.py'), globals())
31 32
32 33 # Build site addresses for file uploads
33 34 release_site = '%s/release/%s' % (archive, version)
34 35 backup_site = '%s/backup/' % archive
35 36
36 37 # Start actual release process
37 38 print()
38 39 print('Releasing IPython')
39 40 print('=================')
40 41 print()
41 42 print('Version:', version)
42 43 print()
43 44 print('Source IPython directory:', ipdir)
44 45 print()
45 46
46 47 # Perform local backup, go to tools dir to run it.
47 48 cd(tooldir)
48 49
49 50 if 'upload' in sys.argv:
50 51 cd(distdir)
51 print( 'Uploading distribution files to GitHub...')
52 #print( 'Uploading distribution files to GitHub...')
52 53
53 54 for fname in os.listdir('.'):
54 55 # TODO: update to GitHub releases API
55 56 continue
56 57 print('uploading %s to GitHub' % fname)
57 58 desc = "IPython %s source distribution" % version
58 59 post_download("ipython/ipython", fname, description=desc)
59 60
60 61 # Make target dir if it doesn't exist
61 print('Uploading IPython to backup site.')
62 print('1. Uploading IPython to archive.ipython.org')
62 63 sh('ssh %s "mkdir -p %s/release/%s" ' % (archive_user, archive_dir, version))
63 64 sh('scp * %s' % release_site)
64 65
65 print( 'Uploading backup files...')
66 print('2. Uploading backup files...')
66 67 cd(ipbackupdir)
67 68 sh('scp `ls -1tr *tgz | tail -1` %s' % backup_site)
68 69
69 print('Done!')
70 print('Use `twine upload dist/*` to upload the files to PyPI')
70 print('3. Uploading to PyPI using twine')
71 cd(distdir)
72 call(['twine', 'upload'] + os.listdir('.'))
73
71 74 else:
75 # Build, but don't upload
76
77 # Make backup tarball
72 78 sh('./make_tarball.py')
73 79 sh('mv ipython-*.tgz %s' % ipbackupdir)
74 80
75 81 # Build release files
76 82 sh('./build_release %s' % ipdir)
77 83
78 # Not Registering with PyPI, registering with setup.py is insecure as communication is not encrypted
79 84 cd(ipdir)
80 85
81 86 # Upload all files
82 87 sh(sdists)
83 88
84 89 buildwheels()
85 print("`./release upload` to upload source distribution on github and ipython archive")
90 print("`./release upload` to upload source distribution on PyPI and ipython archive")
86 91 sys.exit(0)
87 92
88 93
89 94
General Comments 0
You need to be logged in to leave comments. Login now