Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: releaseAutomation.py

Issue 29508667: Issue 4354, 4355 - handle dirty/outdated repos on release (Closed)
Patch Set: Move sanity-function to toplevel Created Aug. 16, 2017, 8:52 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # This Source Code Form is subject to the terms of the Mozilla Public 1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this 2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 from __future__ import print_function
Sebastian Noack 2017/08/16 09:16:13 There should be a blank line below the license dis
tlucas 2017/08/16 10:24:24 Done.
4 5
5 import os 6 import os
6 import re 7 import re
7 import codecs 8 import codecs
8 import subprocess 9 import subprocess
9 import tarfile 10 import tarfile
10 import json 11 import json
11 12
12 from packager import readMetadata, getDefaultFileName 13 from packager import readMetadata, getDefaultFileName
13 14
(...skipping 24 matching lines...) Expand all
38 if os.path.basename(fileinfo.name) in ('.hgtags', '.hgig nore'): 39 if os.path.basename(fileinfo.name) in ('.hgtags', '.hgig nore'):
39 continue 40 continue
40 filedata = repoarchive.extractfile(fileinfo) 41 filedata = repoarchive.extractfile(fileinfo)
41 fileinfo.name = re.sub(r'^[^/]+/', prefix, fileinfo.name ) 42 fileinfo.name = re.sub(r'^[^/]+/', prefix, fileinfo.name )
42 archive.addfile(fileinfo, filedata) 43 archive.addfile(fileinfo, filedata)
43 finally: 44 finally:
44 process.stdout.close() 45 process.stdout.close()
45 process.wait() 46 process.wait()
46 47
47 48
49 def repo_has_uncommitted():
50 """Checks if the given repository is clean"""
51 buff = subprocess.check_output(['hg', 'status'])
52
53 if len(buff):
54 print('Dirty / uncommitted changes in repository!')
55 return True
56
57 return False
58
59
60 def repo_has_outgoing():
61 """Checks whether there would be outgoing changesets to the given path"""
62 try:
63 subprocess.check_output(['hg', 'outgoing'])
64 print('Detected outgoing changesets!')
65 return True
66 except subprocess.CalledProcessError as e:
67 if e.returncode == 1:
68 return False
69 raise
70
71
72 def repo_has_incoming(repo_paths):
73 """Checks whether the local repositories are up-to-date"""
74 incoming = False
75
76 for repo_path in repo_paths:
77 try:
78 subprocess.check_output(['hg', 'incoming', '-R', repo_path])
79 print('Detected incoming changesets in "{}"'.format(repo_path))
80 incoming = True
81 except subprocess.CalledProcessError as e:
82 if e.returncode != 1:
83 raise
84
85 return incoming
86
87
88 def continue_with_outgoing():
89 """Asks the user if he wants to continue despite facing warnings"""
90
91 print('If you proceed with the release, they will be included in the '
92 'release and pushed.')
93 print('Are you sure about continuing the release-process?')
94
95 while True:
96 choice = raw_input('Please choose (yes / no): ').lower()
97
98 if choice == 'yes':
99 return True
100 if choice == 'no':
101 return False
102
103 print('Please answer "yes" or "no"!')
104
105
106 def can_safely_release():
107 # run repository-checks and bail out early, in case the user does not
Sebastian Noack 2017/08/16 09:16:13 Perhaps this comment should rather be a docstring?
tlucas 2017/08/16 10:24:24 Done, also reduced the sentence to a minimum.
108 # explicitly want to continue OR if the check would cause the process to
109 # abort anyway
110 if repo_has_uncommitted():
111 return False
112 if repo_has_incoming():
113 return False
114 if repo_has_outgoing():
115 return continue_with_outgoing()
116
117
48 def run(baseDir, type, version, keyFile, downloadsRepo): 118 def run(baseDir, type, version, keyFile, downloadsRepo):
119 if not can_safely_release():
120 print('Aborting release.')
121 return 1
122
49 if type == 'gecko': 123 if type == 'gecko':
50 import buildtools.packagerGecko as packager 124 import buildtools.packagerGecko as packager
51 elif type == 'safari': 125 elif type == 'safari':
52 import buildtools.packagerSafari as packager 126 import buildtools.packagerSafari as packager
53 elif type == 'edge': 127 elif type == 'edge':
54 import buildtools.packagerEdge as packager 128 import buildtools.packagerEdge as packager
55 elif type == 'chrome': 129 elif type == 'chrome':
56 import buildtools.packagerChrome as packager 130 import buildtools.packagerChrome as packager
57 131
58 # Replace version number in metadata file "manually", ConfigParser will mess 132 # Replace version number in metadata file "manually", ConfigParser will mess
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 create_sourcearchive(baseDir, archivePath) 190 create_sourcearchive(baseDir, archivePath)
117 downloads.append(archivePath) 191 downloads.append(archivePath)
118 192
119 # Now add the downloads and commit 193 # Now add the downloads and commit
120 subprocess.check_call(['hg', 'add', '-R', downloadsRepo] + downloads) 194 subprocess.check_call(['hg', 'add', '-R', downloadsRepo] + downloads)
121 subprocess.check_call(['hg', 'commit', '-R', downloadsRepo, '-m', 'Releasing %s %s' % (extensionName, version)]) 195 subprocess.check_call(['hg', 'commit', '-R', downloadsRepo, '-m', 'Releasing %s %s' % (extensionName, version)])
122 196
123 # Push all changes 197 # Push all changes
124 subprocess.check_call(['hg', 'push', '-R', baseDir]) 198 subprocess.check_call(['hg', 'push', '-R', baseDir])
125 subprocess.check_call(['hg', 'push', '-R', downloadsRepo]) 199 subprocess.check_call(['hg', 'push', '-R', downloadsRepo])
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld