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

Side by Side Diff: sitescripts/extensions/bin/createNightlies.py

Issue 29345508: Issue 4098 - Get rid of special build setup for development builds (Closed)
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:
View unified diff | Download patch
« no previous file with comments | « .sitescripts.example ('k') | sitescripts/extensions/utils.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 generating changelogs and documentation. 58 generating changelogs and documentation.
59 """ 59 """
60 60
61 def __init__(self, config): 61 def __init__(self, config):
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 if self.config.type == 'gecko':
69 self.revision += '-beta'
70 try: 68 try:
71 self.previousRevision = config.latestRevision 69 self.previousRevision = config.latestRevision
72 except: 70 except:
73 self.previousRevision = '0' 71 self.previousRevision = '0'
72 self.buildNum = None
74 self.tempdir = None 73 self.tempdir = None
75 self.outputFilename = None 74 self.outputFilename = None
76 self.changelogFilename = None 75 self.changelogFilename = None
77 76
78 def hasChanges(self): 77 def hasChanges(self):
79 return self.revision != self.previousRevision 78 return self.revision != self.previousRevision
80 79
81 def getCurrentRevision(self): 80 def getCurrentRevision(self):
82 """ 81 """
83 retrieves the current revision number from the repository 82 retrieves the current revision ID from the repository
84 """ 83 """
85 command = ['hg', 'log', '-R', self.config.repository, '-r', 'default', 84 command = [
86 '--template', '{rev}', '--config', 'defaults.log='] 85 'hg', 'id', '-i', '-r', 'default', '--config', 'defaults.id=',
87 return subprocess.check_output(command) 86 self.config.repository
87 ]
88 return subprocess.check_output(command).strip()
89
90 def getCurrentBuild(self):
91 """
92 calculates the (typically numerical) build ID for the current build
93 """
94 command = ['hg', 'id', '-n', '--config', 'defaults.id=', self.tempdir]
95 build = subprocess.check_output(command).strip()
96 if self.config.type == 'gecko':
97 build += '-beta'
98 return build
88 99
89 def getChanges(self): 100 def getChanges(self):
90 """ 101 """
91 retrieve changes between the current and previous ("first") revision 102 retrieve changes between the current and previous ("first") revision
92 """ 103 """
93 104
94 command = ['hg', 'log', '-R', self.config.repository, '-r', 'tip:0', 105 command = ['hg', 'log', '-R', self.tempdir, '-r', 'tip:0',
95 '-b', 'default', '-l', '50', '--encoding', 'utf-8', 106 '-b', 'default', '-l', '50', '--encoding', 'utf-8',
96 '--template', '{date|isodate}\\0{author|person}\\0{rev}\\0{de sc}\\0\\0', 107 '--template', '{date|isodate}\\0{author|person}\\0{rev}\\0{de sc}\\0\\0',
97 '--config', 'defaults.log='] 108 '--config', 'defaults.log=']
98 result = subprocess.check_output(command).decode('utf-8') 109 result = subprocess.check_output(command).decode('utf-8')
99 110
100 for change in result.split('\x00\x00'): 111 for change in result.split('\x00\x00'):
101 if change: 112 if change:
102 date, author, revision, description = change.split('\x00') 113 date, author, revision, description = change.split('\x00')
103 yield {'date': date, 'author': author, 'revision': revision, 'de scription': description} 114 yield {'date': date, 'author': author, 'revision': revision, 'de scription': description}
104 115
105 def copyRepository(self): 116 def copyRepository(self):
106 """ 117 """
107 Create a repository copy in a temporary directory 118 Create a repository copy in a temporary directory
108 """ 119 """
109 # We cannot use hg archive here due to
110 # http://bz.selenic.com/show_bug.cgi?id=3747, have to clone properly :-(
111 self.tempdir = tempfile.mkdtemp(prefix=self.config.repositoryName) 120 self.tempdir = tempfile.mkdtemp(prefix=self.config.repositoryName)
112 command = ['hg', 'clone', '-q', self.config.repository, '-u', 'default', self.tempdir] 121 command = ['hg', 'clone', '-q', self.config.repository, '-u', 'default', self.tempdir]
113 subprocess.check_call(command) 122 subprocess.check_call(command)
114 123
115 # Make sure to process the dependencies file if it is present 124 # Make sure to run ensure_dependencies.py if present
116 import logging 125 depscript = os.path.join(self.tempdir, 'ensure_dependencies.py')
117 logging.disable(logging.WARNING) 126 if os.path.isfile(depscript):
118 try: 127 subprocess.check_call([sys.executable, depscript, '-q'])
119 from buildtools.ensure_dependencies import resolve_deps
120 resolve_deps(self.tempdir, self_update=False,
121 overrideroots={'hg': os.path.abspath(
122 os.path.join(self.config.repository, os.pardir)
123 )},
124 skipdependencies={'buildtools'})
125 finally:
126 logging.disable(logging.NOTSET)
127 128
128 def writeChangelog(self, changes): 129 def writeChangelog(self, changes):
129 """ 130 """
130 write the changelog file into the cloned repository 131 write the changelog file into the cloned repository
131 """ 132 """
132 baseDir = os.path.join(self.config.nightliesDirectory, self.basename) 133 baseDir = os.path.join(self.config.nightliesDirectory, self.basename)
133 if not os.path.exists(baseDir): 134 if not os.path.exists(baseDir):
134 os.makedirs(baseDir) 135 os.makedirs(baseDir)
135 changelogFile = '%s-%s.changelog.xhtml' % (self.basename, self.version) 136 changelogFile = '%s-%s.changelog.xhtml' % (self.basename, self.version)
136 changelogPath = os.path.join(baseDir, changelogFile) 137 changelogPath = os.path.join(baseDir, changelogFile)
(...skipping 12 matching lines...) Expand all
149 150
150 def readGeckoMetadata(self): 151 def readGeckoMetadata(self):
151 """ 152 """
152 read Gecko-specific metadata file from a cloned repository 153 read Gecko-specific metadata file from a cloned repository
153 and parse id, version, basename and the compat section 154 and parse id, version, basename and the compat section
154 out of the file 155 out of the file
155 """ 156 """
156 import buildtools.packagerGecko as packager 157 import buildtools.packagerGecko as packager
157 metadata = packager.readMetadata(self.tempdir, self.config.type) 158 metadata = packager.readMetadata(self.tempdir, self.config.type)
158 self.extensionID = metadata.get('general', 'id') 159 self.extensionID = metadata.get('general', 'id')
159 self.version = packager.getBuildVersion(self.tempdir, metadata, False, s elf.revision) 160 self.version = packager.getBuildVersion(self.tempdir, metadata, False,
161 self.buildNum)
160 self.basename = metadata.get('general', 'basename') 162 self.basename = metadata.get('general', 'basename')
161 self.compat = [] 163 self.compat = []
162 for key, value in packager.KNOWN_APPS.iteritems(): 164 for key, value in packager.KNOWN_APPS.iteritems():
163 if metadata.has_option('compat', key): 165 if metadata.has_option('compat', key):
164 minVersion, maxVersion = metadata.get('compat', key).split('/') 166 minVersion, maxVersion = metadata.get('compat', key).split('/')
165 self.compat.append({'id': value, 'minVersion': minVersion, 'maxV ersion': maxVersion}) 167 self.compat.append({'id': value, 'minVersion': minVersion, 'maxV ersion': maxVersion})
166 168
167 def readAndroidMetadata(self): 169 def readAndroidMetadata(self):
168 """ 170 """
169 Read Android-specific metadata from AndroidManifest.xml file. 171 Read Android-specific metadata from AndroidManifest.xml file.
170 """ 172 """
171 manifestFile = open(os.path.join(self.tempdir, 'AndroidManifest.xml'), ' r') 173 manifestFile = open(os.path.join(self.tempdir, 'AndroidManifest.xml'), ' r')
172 manifest = parseXml(manifestFile) 174 manifest = parseXml(manifestFile)
173 manifestFile.close() 175 manifestFile.close()
174 176
175 root = manifest.documentElement 177 root = manifest.documentElement
176 self.version = root.attributes['android:versionName'].value 178 self.version = root.attributes['android:versionName'].value
177 while self.version.count('.') < 2: 179 while self.version.count('.') < 2:
178 self.version += '.0' 180 self.version += '.0'
179 self.version = '%s.%s' % (self.version, self.revision) 181 self.version = '%s.%s' % (self.version, self.buildNum)
180 182
181 usesSdk = manifest.getElementsByTagName('uses-sdk')[0] 183 usesSdk = manifest.getElementsByTagName('uses-sdk')[0]
182 self.minSdkVersion = usesSdk.attributes['android:minSdkVersion'].value 184 self.minSdkVersion = usesSdk.attributes['android:minSdkVersion'].value
183 self.basename = os.path.basename(self.config.repository) 185 self.basename = os.path.basename(self.config.repository)
184 186
185 def readChromeMetadata(self): 187 def readChromeMetadata(self):
186 """ 188 """
187 Read Chrome-specific metadata from metadata file. This will also 189 Read Chrome-specific metadata from metadata file. This will also
188 calculate extension ID from the private key. 190 calculate extension ID from the private key.
189 """ 191 """
190 192
191 # Calculate extension ID from public key 193 # Calculate extension ID from public key
192 # (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)
193 import buildtools.packagerChrome as packager 195 import buildtools.packagerChrome as packager
194 publicKey = packager.getPublicKey(self.config.keyFile) 196 publicKey = packager.getPublicKey(self.config.keyFile)
195 hash = hashlib.sha256() 197 hash = hashlib.sha256()
196 hash.update(publicKey) 198 hash.update(publicKey)
197 self.extensionID = hash.hexdigest()[0:32] 199 self.extensionID = hash.hexdigest()[0:32]
198 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))
199 201
200 # Now read metadata file 202 # Now read metadata file
201 metadata = packager.readMetadata(self.tempdir, self.config.type) 203 metadata = packager.readMetadata(self.tempdir, self.config.type)
202 self.version = packager.getBuildVersion(self.tempdir, metadata, False, s elf.revision) 204 self.version = packager.getBuildVersion(self.tempdir, metadata, False,
205 self.buildNum)
203 self.basename = metadata.get('general', 'basename') 206 self.basename = metadata.get('general', 'basename')
204 207
205 self.compat = [] 208 self.compat = []
206 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'):
207 self.compat.append({'id': 'chrome', 'minVersion': metadata.get('comp at', 'chrome')}) 210 self.compat.append({'id': 'chrome', 'minVersion': metadata.get('comp at', 'chrome')})
208 211
209 def readSafariMetadata(self): 212 def readSafariMetadata(self):
210 import buildtools.packagerSafari as packager 213 import buildtools.packagerSafari as packager
211 metadata = packager.readMetadata(self.tempdir, self.config.type) 214 metadata = packager.readMetadata(self.tempdir, self.config.type)
212 certs = packager.get_certificates_and_key(self.config.keyFile)[0] 215 certs = packager.get_certificates_and_key(self.config.keyFile)[0]
213 216
214 self.certificateID = packager.get_developer_identifier(certs) 217 self.certificateID = packager.get_developer_identifier(certs)
215 self.version = packager.getBuildVersion(self.tempdir, metadata, False, s elf.revision) 218 self.version = packager.getBuildVersion(self.tempdir, metadata, False,
219 self.buildNum)
216 self.shortVersion = metadata.get('general', 'version') 220 self.shortVersion = metadata.get('general', 'version')
217 self.basename = metadata.get('general', 'basename') 221 self.basename = metadata.get('general', 'basename')
218 self.updatedFromGallery = False 222 self.updatedFromGallery = False
219 223
220 def writeUpdateManifest(self): 224 def writeUpdateManifest(self):
221 """ 225 """
222 Writes update.rdf file for the current build 226 Writes update.rdf file for the current build
223 """ 227 """
224 baseDir = os.path.join(self.config.nightliesDirectory, self.basename) 228 baseDir = os.path.join(self.config.nightliesDirectory, self.basename)
225 if self.config.type == 'safari': 229 if self.config.type == 'safari':
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 295
292 if self.config.type == 'android': 296 if self.config.type == 'android':
293 apkFile = open(self.path, 'wb') 297 apkFile = open(self.path, 'wb')
294 298
295 try: 299 try:
296 try: 300 try:
297 port = get_config().get('extensions', 'androidBuildPort') 301 port = get_config().get('extensions', 'androidBuildPort')
298 except ConfigParser.NoOptionError: 302 except ConfigParser.NoOptionError:
299 port = '22' 303 port = '22'
300 buildCommand = ['ssh', '-p', port, get_config().get('extensions' , 'androidBuildHost')] 304 buildCommand = ['ssh', '-p', port, get_config().get('extensions' , 'androidBuildHost')]
301 buildCommand.extend(map(pipes.quote, ['/home/android/bin/makedeb ugbuild.py', '--revision', self.revision, '--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 ]))
302 subprocess.check_call(buildCommand, stdout=apkFile, close_fds=Tr ue) 309 subprocess.check_call(buildCommand, stdout=apkFile, close_fds=Tr ue)
303 except: 310 except:
304 # clear broken output if any 311 # clear broken output if any
305 if os.path.exists(self.path): 312 if os.path.exists(self.path):
306 os.remove(self.path) 313 os.remove(self.path)
307 raise 314 raise
308 elif self.config.type == 'chrome':
309 import buildtools.packagerChrome as packager
310 packager.createBuild(self.tempdir, type=self.config.type, outFile=se lf.path, buildNum=self.revision, keyFile=self.config.keyFile)
311 elif self.config.type == 'safari':
312 import buildtools.packagerSafari as packager
313 packager.createBuild(self.tempdir, type=self.config.type, outFile=se lf.path, buildNum=self.revision, keyFile=self.config.keyFile)
314 else: 315 else:
315 import buildtools.packagerGecko as packager 316 env = os.environ
316 packager.createBuild(self.tempdir, outFile=self.path, buildNum=self. revision, keyFile=self.config.keyFile) 317 spiderMonkeyBinary = self.config.spiderMonkeyBinary
318 if spiderMonkeyBinary:
319 env = dict(env, SPIDERMONKEY_BINARY=spiderMonkeyBinary)
320
321 buildCommand = [
322 os.path.join(self.tempdir, 'build.py'), '-t', self.config.type,
323 'build', '-b', self.buildNum, '-k', self.config.keyFile,
324 self.path
325 ]
326 subprocess.check_call(buildCommand, env=env)
317 327
318 if not os.path.exists(self.path): 328 if not os.path.exists(self.path):
319 raise Exception("Build failed, output file hasn't been created") 329 raise Exception("Build failed, output file hasn't been created")
320 330
321 linkPath = os.path.join(baseDir, '00latest%s' % self.config.packageSuffi x) 331 linkPath = os.path.join(baseDir, '00latest%s' % self.config.packageSuffi x)
322 if hasattr(os, 'symlink'): 332 if hasattr(os, 'symlink'):
323 if os.path.exists(linkPath): 333 if os.path.exists(linkPath):
324 os.remove(linkPath) 334 os.remove(linkPath)
325 os.symlink(os.path.basename(self.path), linkPath) 335 os.symlink(os.path.basename(self.path), linkPath)
326 else: 336 else:
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 Run the nightly build process for one extension 558 Run the nightly build process for one extension
549 """ 559 """
550 try: 560 try:
551 if self.config.type == 'ie': 561 if self.config.type == 'ie':
552 # We cannot build IE builds, simply list the builds already in 562 # We cannot build IE builds, simply list the builds already in
553 # the directory. Basename has to be deduced from the repository name. 563 # the directory. Basename has to be deduced from the repository name.
554 self.basename = os.path.basename(self.config.repository) 564 self.basename = os.path.basename(self.config.repository)
555 else: 565 else:
556 # copy the repository into a temporary directory 566 # copy the repository into a temporary directory
557 self.copyRepository() 567 self.copyRepository()
568 self.buildNum = self.getCurrentBuild()
558 569
559 # get meta data from the repository 570 # get meta data from the repository
560 if self.config.type == 'android': 571 if self.config.type == 'android':
561 self.readAndroidMetadata() 572 self.readAndroidMetadata()
562 elif self.config.type == 'chrome': 573 elif self.config.type == 'chrome':
563 self.readChromeMetadata() 574 self.readChromeMetadata()
564 elif self.config.type == 'safari': 575 elif self.config.type == 'safari':
565 self.readSafariMetadata() 576 self.readSafariMetadata()
566 else: 577 else:
567 self.readGeckoMetadata() 578 self.readGeckoMetadata()
(...skipping 51 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()
OLDNEW
« no previous file with comments | « .sitescripts.example ('k') | sitescripts/extensions/utils.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld