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

Delta Between Two Patch Sets: sitescripts/extensions/bin/createNightlies.py

Issue 29345508: Issue 4098 - Get rid of special build setup for development builds (Closed)
Left Patch Set: Created June 1, 2016, 2:47 p.m.
Right Patch Set: Improved ensure_dependencies call Created June 6, 2016, 11:49 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « .sitescripts.example ('k') | sitescripts/extensions/utils.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # This file is part of the Adblock Plus web scripts, 1 # This file is part of the Adblock Plus web scripts,
2 # Copyright (C) 2006-2016 Eyeo GmbH 2 # Copyright (C) 2006-2016 Eyeo GmbH
3 # 3 #
4 # Adblock Plus is free software: you can redistribute it and/or modify 4 # Adblock Plus is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 3 as 5 # it under the terms of the GNU General Public License version 3 as
6 # published by the Free Software Foundation. 6 # published by the Free Software Foundation.
7 # 7 #
8 # Adblock Plus is distributed in the hope that it will be useful, 8 # Adblock Plus is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 """ 62 """
63 Creates a NightlyBuild instance; we are simply 63 Creates a NightlyBuild instance; we are simply
64 recording the configuration settings here. 64 recording the configuration settings here.
65 """ 65 """
66 self.config = config 66 self.config = config
67 self.revision = self.getCurrentRevision() 67 self.revision = self.getCurrentRevision()
68 try: 68 try:
69 self.previousRevision = config.latestRevision 69 self.previousRevision = config.latestRevision
70 except: 70 except:
71 self.previousRevision = '0' 71 self.previousRevision = '0'
72 self.buildNum = None 72 self.buildNum = None
Wladimir Palant 2016/06/01 14:57:12 With these changes, self.revision is a revision ha
Vasily Kuznetsov 2016/06/01 17:14:15 Acknowledged.
73 self.tempdir = None 73 self.tempdir = None
74 self.outputFilename = None 74 self.outputFilename = None
75 self.changelogFilename = None 75 self.changelogFilename = None
76 76
77 def hasChanges(self): 77 def hasChanges(self):
78 return self.revision != self.previousRevision 78 return self.revision != self.previousRevision
79 79
80 def getCurrentRevision(self): 80 def getCurrentRevision(self):
81 """ 81 """
82 retrieves the current revision ID from the repository 82 retrieves the current revision ID from the repository
83 """ 83 """
84 command = [ 84 command = [
85 'hg', 'id', '-i', '-r', 'default', '--config', 'defaults.id=', 85 'hg', 'id', '-i', '-r', 'default', '--config', 'defaults.id=',
Vasily Kuznetsov 2016/06/01 17:14:15 This `--config defaults.id=` is there to make sure
Wladimir Palant 2016/06/03 14:14:05 "Breaking automation is only one of the reason to
Vasily Kuznetsov 2016/06/03 16:04:49 Acknowledged.
86 self.config.repository 86 self.config.repository
87 ] 87 ]
88 return subprocess.check_output(command).strip() 88 return subprocess.check_output(command).strip()
89 89
90 def getCurrentBuild(self): 90 def getCurrentBuild(self):
91 """ 91 """
92 calculates the (typically numerical) build ID for the current build 92 calculates the (typically numerical) build ID for the current build
93 """ 93 """
94 command = ['hg', 'id', '-n', '--config', 'defaults.id=', self.tempdir] 94 command = ['hg', 'id', '-n', '--config', 'defaults.id=', self.tempdir]
95 build = subprocess.check_output(command).strip() 95 build = subprocess.check_output(command).strip()
(...skipping 19 matching lines...) Expand all
115 115
116 def copyRepository(self): 116 def copyRepository(self):
117 """ 117 """
118 Create a repository copy in a temporary directory 118 Create a repository copy in a temporary directory
119 """ 119 """
120 self.tempdir = tempfile.mkdtemp(prefix=self.config.repositoryName) 120 self.tempdir = tempfile.mkdtemp(prefix=self.config.repositoryName)
121 command = ['hg', 'clone', '-q', self.config.repository, '-u', 'default', self.tempdir] 121 command = ['hg', 'clone', '-q', self.config.repository, '-u', 'default', self.tempdir]
122 subprocess.check_call(command) 122 subprocess.check_call(command)
123 123
124 # Make sure to run ensure_dependencies.py if present 124 # Make sure to run ensure_dependencies.py if present
125 command = [os.path.join(self.tempdir, 'ensure_dependencies.py'), '-q'] 125 depscript = os.path.join(self.tempdir, 'ensure_dependencies.py')
126 if os.path.isfile(command[0]): 126 if os.path.isfile(depscript):
Vasily Kuznetsov 2016/06/01 17:14:15 Are we sure that `ensure_dependecies.py` is always
Wladimir Palant 2016/06/03 14:14:06 You are right, build.py calls Python explicitly so
127 subprocess.check_call(command) 127 subprocess.check_call([sys.executable, depscript, '-q'])
128 128
129 def writeChangelog(self, changes): 129 def writeChangelog(self, changes):
130 """ 130 """
131 write the changelog file into the cloned repository 131 write the changelog file into the cloned repository
132 """ 132 """
133 baseDir = os.path.join(self.config.nightliesDirectory, self.basename) 133 baseDir = os.path.join(self.config.nightliesDirectory, self.basename)
134 if not os.path.exists(baseDir): 134 if not os.path.exists(baseDir):
135 os.makedirs(baseDir) 135 os.makedirs(baseDir)
136 changelogFile = '%s-%s.changelog.xhtml' % (self.basename, self.version) 136 changelogFile = '%s-%s.changelog.xhtml' % (self.basename, self.version)
137 changelogPath = os.path.join(baseDir, changelogFile) 137 changelogPath = os.path.join(baseDir, changelogFile)
138 self.changelogURL = urlparse.urljoin(self.config.nightliesURL, self.base name + '/' + changelogFile) 138 self.changelogURL = urlparse.urljoin(self.config.nightliesURL, self.base name + '/' + changelogFile)
139 139
140 template = get_template(get_config().get('extensions', 'changelogTemplat e')) 140 template = get_template(get_config().get('extensions', 'changelogTemplat e'))
141 template.stream({'changes': changes}).dump(changelogPath, encoding='utf- 8') 141 template.stream({'changes': changes}).dump(changelogPath, encoding='utf- 8')
142 142
143 linkPath = os.path.join(baseDir, '00latest.changelog.xhtml') 143 linkPath = os.path.join(baseDir, '00latest.changelog.xhtml')
144 if hasattr(os, 'symlink'): 144 if hasattr(os, 'symlink'):
145 if os.path.exists(linkPath): 145 if os.path.exists(linkPath):
146 os.remove(linkPath) 146 os.remove(linkPath)
147 os.symlink(os.path.basename(changelogPath), linkPath) 147 os.symlink(os.path.basename(changelogPath), linkPath)
148 else: 148 else:
149 shutil.copyfile(changelogPath, linkPath) 149 shutil.copyfile(changelogPath, linkPath)
150 150
151 def readGeckoMetadata(self): 151 def readGeckoMetadata(self):
152 """ 152 """
153 read Gecko-specific metadata file from a cloned repository 153 read Gecko-specific metadata file from a cloned repository
154 and parse id, version, basename and the compat section 154 and parse id, version, basename and the compat section
155 out of the file 155 out of the file
156 """ 156 """
157 import buildtools.packagerGecko as packager 157 import buildtools.packagerGecko as packager
Wladimir Palant 2016/06/01 14:57:12 We are still using latest buildtools revision to r
Vasily Kuznetsov 2016/06/01 17:14:15 Acknowledged.
158 metadata = packager.readMetadata(self.tempdir, self.config.type) 158 metadata = packager.readMetadata(self.tempdir, self.config.type)
159 self.extensionID = metadata.get('general', 'id') 159 self.extensionID = metadata.get('general', 'id')
160 self.version = packager.getBuildVersion(self.tempdir, metadata, False, s elf.buildNum) 160 self.version = packager.getBuildVersion(self.tempdir, metadata, False,
Vasily Kuznetsov 2016/06/01 17:14:15 This line is too long, although of course, it's no
Wladimir Palant 2016/06/03 14:14:04 This add too many unrelated changes for my taste b
161 self.buildNum)
161 self.basename = metadata.get('general', 'basename') 162 self.basename = metadata.get('general', 'basename')
162 self.compat = [] 163 self.compat = []
163 for key, value in packager.KNOWN_APPS.iteritems(): 164 for key, value in packager.KNOWN_APPS.iteritems():
164 if metadata.has_option('compat', key): 165 if metadata.has_option('compat', key):
165 minVersion, maxVersion = metadata.get('compat', key).split('/') 166 minVersion, maxVersion = metadata.get('compat', key).split('/')
166 self.compat.append({'id': value, 'minVersion': minVersion, 'maxV ersion': maxVersion}) 167 self.compat.append({'id': value, 'minVersion': minVersion, 'maxV ersion': maxVersion})
167 168
168 def readAndroidMetadata(self): 169 def readAndroidMetadata(self):
169 """ 170 """
170 Read Android-specific metadata from AndroidManifest.xml file. 171 Read Android-specific metadata from AndroidManifest.xml file.
(...skipping 22 matching lines...) Expand all
193 # (see http://supercollider.dk/2010/01/calculating-chrome-extension-id-f rom-your-private-key-233) 194 # (see http://supercollider.dk/2010/01/calculating-chrome-extension-id-f rom-your-private-key-233)
194 import buildtools.packagerChrome as packager 195 import buildtools.packagerChrome as packager
195 publicKey = packager.getPublicKey(self.config.keyFile) 196 publicKey = packager.getPublicKey(self.config.keyFile)
196 hash = hashlib.sha256() 197 hash = hashlib.sha256()
197 hash.update(publicKey) 198 hash.update(publicKey)
198 self.extensionID = hash.hexdigest()[0:32] 199 self.extensionID = hash.hexdigest()[0:32]
199 self.extensionID = ''.join(map(lambda c: chr(97 + int(c, 16)), self.exte nsionID)) 200 self.extensionID = ''.join(map(lambda c: chr(97 + int(c, 16)), self.exte nsionID))
200 201
201 # Now read metadata file 202 # Now read metadata file
202 metadata = packager.readMetadata(self.tempdir, self.config.type) 203 metadata = packager.readMetadata(self.tempdir, self.config.type)
203 self.version = packager.getBuildVersion(self.tempdir, metadata, False, s elf.buildNum) 204 self.version = packager.getBuildVersion(self.tempdir, metadata, False,
205 self.buildNum)
204 self.basename = metadata.get('general', 'basename') 206 self.basename = metadata.get('general', 'basename')
205 207
206 self.compat = [] 208 self.compat = []
207 if metadata.has_section('compat') and metadata.has_option('compat', 'chr ome'): 209 if metadata.has_section('compat') and metadata.has_option('compat', 'chr ome'):
208 self.compat.append({'id': 'chrome', 'minVersion': metadata.get('comp at', 'chrome')}) 210 self.compat.append({'id': 'chrome', 'minVersion': metadata.get('comp at', 'chrome')})
209 211
210 def readSafariMetadata(self): 212 def readSafariMetadata(self):
211 import buildtools.packagerSafari as packager 213 import buildtools.packagerSafari as packager
212 metadata = packager.readMetadata(self.tempdir, self.config.type) 214 metadata = packager.readMetadata(self.tempdir, self.config.type)
213 certs = packager.get_certificates_and_key(self.config.keyFile)[0] 215 certs = packager.get_certificates_and_key(self.config.keyFile)[0]
214 216
215 self.certificateID = packager.get_developer_identifier(certs) 217 self.certificateID = packager.get_developer_identifier(certs)
216 self.version = packager.getBuildVersion(self.tempdir, metadata, False, s elf.buildNum) 218 self.version = packager.getBuildVersion(self.tempdir, metadata, False,
219 self.buildNum)
217 self.shortVersion = metadata.get('general', 'version') 220 self.shortVersion = metadata.get('general', 'version')
218 self.basename = metadata.get('general', 'basename') 221 self.basename = metadata.get('general', 'basename')
219 self.updatedFromGallery = False 222 self.updatedFromGallery = False
220 223
221 def writeUpdateManifest(self): 224 def writeUpdateManifest(self):
222 """ 225 """
223 Writes update.rdf file for the current build 226 Writes update.rdf file for the current build
224 """ 227 """
225 baseDir = os.path.join(self.config.nightliesDirectory, self.basename) 228 baseDir = os.path.join(self.config.nightliesDirectory, self.basename)
226 if self.config.type == 'safari': 229 if self.config.type == 'safari':
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 295
293 if self.config.type == 'android': 296 if self.config.type == 'android':
294 apkFile = open(self.path, 'wb') 297 apkFile = open(self.path, 'wb')
295 298
296 try: 299 try:
297 try: 300 try:
298 port = get_config().get('extensions', 'androidBuildPort') 301 port = get_config().get('extensions', 'androidBuildPort')
299 except ConfigParser.NoOptionError: 302 except ConfigParser.NoOptionError:
300 port = '22' 303 port = '22'
301 buildCommand = ['ssh', '-p', port, get_config().get('extensions' , 'androidBuildHost')] 304 buildCommand = ['ssh', '-p', port, get_config().get('extensions' , 'androidBuildHost')]
302 buildCommand.extend(map(pipes.quote, ['/home/android/bin/makedeb ugbuild.py', '--revision', self.buildNum, '--version', self.version, '--stdout'] )) 305 buildCommand.extend(map(pipes.quote, [
306 '/home/android/bin/makedebugbuild.py', '--revision',
307 self.buildNum, '--version', self.version, '--stdout'
308 ]))
303 subprocess.check_call(buildCommand, stdout=apkFile, close_fds=Tr ue) 309 subprocess.check_call(buildCommand, stdout=apkFile, close_fds=Tr ue)
304 except: 310 except:
305 # clear broken output if any 311 # clear broken output if any
306 if os.path.exists(self.path): 312 if os.path.exists(self.path):
307 os.remove(self.path) 313 os.remove(self.path)
308 raise 314 raise
309 else: 315 else:
316 env = os.environ
317 spiderMonkeyBinary = self.config.spiderMonkeyBinary
318 if spiderMonkeyBinary:
319 env = dict(env, SPIDERMONKEY_BINARY=spiderMonkeyBinary)
320
310 buildCommand = [ 321 buildCommand = [
Vasily Kuznetsov 2016/06/01 17:14:15 A nice side effect that we got rid of this branchi
Wladimir Palant 2016/06/03 14:14:04 It will come back, as soon as we remove signing su
Vasily Kuznetsov 2016/06/03 16:04:49 :)
311 os.path.join(self.tempdir, 'build.py'), '-t', self.config.type, 322 os.path.join(self.tempdir, 'build.py'), '-t', self.config.type,
312 'build', '-b', self.buildNum, '-k', self.config.keyFile, 323 'build', '-b', self.buildNum, '-k', self.config.keyFile,
313 self.path 324 self.path
314 ] 325 ]
315 subprocess.check_call(buildCommand) 326 subprocess.check_call(buildCommand, env=env)
316 327
317 if not os.path.exists(self.path): 328 if not os.path.exists(self.path):
318 raise Exception("Build failed, output file hasn't been created") 329 raise Exception("Build failed, output file hasn't been created")
319 330
320 linkPath = os.path.join(baseDir, '00latest%s' % self.config.packageSuffi x) 331 linkPath = os.path.join(baseDir, '00latest%s' % self.config.packageSuffi x)
321 if hasattr(os, 'symlink'): 332 if hasattr(os, 'symlink'):
322 if os.path.exists(linkPath): 333 if os.path.exists(linkPath):
323 os.remove(linkPath) 334 os.remove(linkPath)
324 os.symlink(os.path.basename(self.path), linkPath) 335 os.symlink(os.path.basename(self.path), linkPath)
325 else: 336 else:
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 except Exception, ex: 630 except Exception, ex:
620 logging.error('The build for %s failed:', repo) 631 logging.error('The build for %s failed:', repo)
621 logging.exception(ex) 632 logging.exception(ex)
622 633
623 file = open(nightlyConfigFile, 'wb') 634 file = open(nightlyConfigFile, 'wb')
624 nightlyConfig.write(file) 635 nightlyConfig.write(file)
625 636
626 637
627 if __name__ == '__main__': 638 if __name__ == '__main__':
628 main() 639 main()
LEFTRIGHT

Powered by Google App Engine
This is Rietveld