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