| OLD | NEW |
| 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-present eyeo GmbH | 2 # Copyright (C) 2006-present 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 import zipfile | 44 import zipfile |
| 45 import contextlib | 45 import contextlib |
| 46 | 46 |
| 47 from xml.dom.minidom import parse as parseXml | 47 from xml.dom.minidom import parse as parseXml |
| 48 | 48 |
| 49 from sitescripts.extensions.utils import ( | 49 from sitescripts.extensions.utils import ( |
| 50 compareVersions, Configuration, | 50 compareVersions, Configuration, |
| 51 writeAndroidUpdateManifest | 51 writeAndroidUpdateManifest |
| 52 ) | 52 ) |
| 53 from sitescripts.utils import get_config, get_template | 53 from sitescripts.utils import get_config, get_template |
| 54 from sitescripts.extensions.bin.legacy import xarfile |
| 54 | 55 |
| 55 MAX_BUILDS = 50 | 56 MAX_BUILDS = 50 |
| 56 | 57 |
| 57 | 58 |
| 58 # Google and Microsoft APIs use HTTP error codes with error message in | 59 # Google and Microsoft APIs use HTTP error codes with error message in |
| 59 # body. So we add the response body to the HTTPError to get more | 60 # body. So we add the response body to the HTTPError to get more |
| 60 # meaningful error messages. | 61 # meaningful error messages. |
| 61 class HTTPErrorBodyHandler(urllib2.HTTPDefaultErrorHandler): | 62 class HTTPErrorBodyHandler(urllib2.HTTPDefaultErrorHandler): |
| 62 def http_error_default(self, req, fp, code, msg, hdrs): | 63 def http_error_default(self, req, fp, code, msg, hdrs): |
| 63 raise urllib2.HTTPError(req.get_full_url(), code, | 64 raise urllib2.HTTPError(req.get_full_url(), code, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 'defaults.id=', self.config.repository | 99 'defaults.id=', self.config.repository |
| 99 ] | 100 ] |
| 100 return subprocess.check_output(command).strip() | 101 return subprocess.check_output(command).strip() |
| 101 | 102 |
| 102 def getCurrentBuild(self): | 103 def getCurrentBuild(self): |
| 103 """ | 104 """ |
| 104 calculates the (typically numerical) build ID for the current build | 105 calculates the (typically numerical) build ID for the current build |
| 105 """ | 106 """ |
| 106 command = ['hg', 'id', '-n', '--config', 'defaults.id=', self.tempdir] | 107 command = ['hg', 'id', '-n', '--config', 'defaults.id=', self.tempdir] |
| 107 build = subprocess.check_output(command).strip() | 108 build = subprocess.check_output(command).strip() |
| 108 if self.config.type in {'gecko', 'gecko-webext'}: | 109 if self.config.type == 'gecko': |
| 109 build += 'beta' | 110 build += 'beta' |
| 110 return build | 111 return build |
| 111 | 112 |
| 112 def getChanges(self): | 113 def getChanges(self): |
| 113 """ | 114 """ |
| 114 retrieve changes between the current and previous ("first") revision | 115 retrieve changes between the current and previous ("first") revision |
| 115 """ | 116 """ |
| 116 command = [ | 117 command = [ |
| 117 'hg', 'log', '-R', self.tempdir, '-r', | 118 'hg', 'log', '-R', self.tempdir, '-r', |
| 118 'reverse(ancestors({}))'.format(self.config.revision), '-l', '50', | 119 'reverse(ancestors({}))'.format(self.config.revision), '-l', '50', |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 os.symlink(os.path.basename(changelogPath), linkPath) | 163 os.symlink(os.path.basename(changelogPath), linkPath) |
| 163 else: | 164 else: |
| 164 shutil.copyfile(changelogPath, linkPath) | 165 shutil.copyfile(changelogPath, linkPath) |
| 165 | 166 |
| 166 def readGeckoMetadata(self): | 167 def readGeckoMetadata(self): |
| 167 """ | 168 """ |
| 168 read Gecko-specific metadata file from a cloned repository | 169 read Gecko-specific metadata file from a cloned repository |
| 169 and parse id, version, basename and the compat section | 170 and parse id, version, basename and the compat section |
| 170 out of the file | 171 out of the file |
| 171 """ | 172 """ |
| 172 import buildtools.packagerGecko as packager | 173 import buildtools.packagerChrome as packager |
| 173 metadata = packager.readMetadata(self.tempdir, self.config.type) | 174 metadata = packager.readMetadata(self.tempdir, self.config.type) |
| 174 self.extensionID = metadata.get('general', 'id') | 175 self.extensionID = metadata.get('general', 'id') |
| 175 self.version = packager.getBuildVersion(self.tempdir, metadata, False, | 176 self.version = packager.getBuildVersion(self.tempdir, metadata, False, |
| 176 self.buildNum) | 177 self.buildNum) |
| 177 self.basename = metadata.get('general', 'basename') | 178 self.basename = metadata.get('general', 'basename') |
| 178 | 179 |
| 179 def readAndroidMetadata(self): | 180 def readAndroidMetadata(self): |
| 180 """ | 181 """ |
| 181 Read Android-specific metadata from AndroidManifest.xml file. | 182 Read Android-specific metadata from AndroidManifest.xml file. |
| 182 """ | 183 """ |
| (...skipping 30 matching lines...) Expand all Loading... |
| 213 metadata = packager.readMetadata(self.tempdir, self.config.type) | 214 metadata = packager.readMetadata(self.tempdir, self.config.type) |
| 214 self.version = packager.getBuildVersion(self.tempdir, metadata, False, | 215 self.version = packager.getBuildVersion(self.tempdir, metadata, False, |
| 215 self.buildNum) | 216 self.buildNum) |
| 216 self.basename = metadata.get('general', 'basename') | 217 self.basename = metadata.get('general', 'basename') |
| 217 | 218 |
| 218 self.compat = [] | 219 self.compat = [] |
| 219 if metadata.has_section('compat') and metadata.has_option('compat', 'chr
ome'): | 220 if metadata.has_section('compat') and metadata.has_option('compat', 'chr
ome'): |
| 220 self.compat.append({'id': 'chrome', 'minVersion': metadata.get('comp
at', 'chrome')}) | 221 self.compat.append({'id': 'chrome', 'minVersion': metadata.get('comp
at', 'chrome')}) |
| 221 | 222 |
| 222 def readSafariMetadata(self): | 223 def readSafariMetadata(self): |
| 223 import buildtools.packagerSafari as packager | 224 import sitescripts.extensions.bin.legacy.packagerSafari as packager |
| 224 from buildtools import xarfile | |
| 225 metadata = packager.readMetadata(self.tempdir, self.config.type) | 225 metadata = packager.readMetadata(self.tempdir, self.config.type) |
| 226 certs = xarfile.read_certificates_and_key(self.config.keyFile)[0] | 226 certs = xarfile.read_certificates_and_key(self.config.keyFile)[0] |
| 227 | 227 |
| 228 self.certificateID = packager.get_developer_identifier(certs) | 228 self.certificateID = packager.get_developer_identifier(certs) |
| 229 self.version = packager.getBuildVersion(self.tempdir, metadata, False, | 229 self.version = packager.getBuildVersion(self.tempdir, metadata, False, |
| 230 self.buildNum) | 230 self.buildNum) |
| 231 self.shortVersion = metadata.get('general', 'version') | 231 self.shortVersion = metadata.get('general', 'version') |
| 232 self.basename = metadata.get('general', 'basename') | 232 self.basename = metadata.get('general', 'basename') |
| 233 self.updatedFromGallery = False | 233 self.updatedFromGallery = False |
| 234 | 234 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 os.remove(self.path) | 340 os.remove(self.path) |
| 341 raise | 341 raise |
| 342 else: | 342 else: |
| 343 env = os.environ | 343 env = os.environ |
| 344 spiderMonkeyBinary = self.config.spiderMonkeyBinary | 344 spiderMonkeyBinary = self.config.spiderMonkeyBinary |
| 345 if spiderMonkeyBinary: | 345 if spiderMonkeyBinary: |
| 346 env = dict(env, SPIDERMONKEY_BINARY=spiderMonkeyBinary) | 346 env = dict(env, SPIDERMONKEY_BINARY=spiderMonkeyBinary) |
| 347 | 347 |
| 348 command = [os.path.join(self.tempdir, 'build.py'), | 348 command = [os.path.join(self.tempdir, 'build.py'), |
| 349 '-t', self.config.type, 'build', '-b', self.buildNum] | 349 '-t', self.config.type, 'build', '-b', self.buildNum] |
| 350 if self.config.type not in {'gecko', 'gecko-webext', 'edge'}: | 350 if self.config.type not in {'gecko', 'edge'}: |
| 351 command.extend(['-k', self.config.keyFile]) | 351 command.extend(['-k', self.config.keyFile]) |
| 352 command.append(self.path) | 352 command.append(self.path) |
| 353 subprocess.check_call(command, env=env) | 353 subprocess.check_call(command, env=env) |
| 354 | 354 |
| 355 if not os.path.exists(self.path): | 355 if not os.path.exists(self.path): |
| 356 raise Exception("Build failed, output file hasn't been created") | 356 raise Exception("Build failed, output file hasn't been created") |
| 357 | 357 |
| 358 linkPath = os.path.join(baseDir, '00latest%s' % self.config.packageSuffi
x) | 358 linkPath = os.path.join(baseDir, '00latest%s' % self.config.packageSuffi
x) |
| 359 if hasattr(os, 'symlink'): | 359 if hasattr(os, 'symlink'): |
| 360 if os.path.exists(linkPath): | 360 if os.path.exists(linkPath): |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 self.copyRepository() | 646 self.copyRepository() |
| 647 self.buildNum = self.getCurrentBuild() | 647 self.buildNum = self.getCurrentBuild() |
| 648 | 648 |
| 649 # get meta data from the repository | 649 # get meta data from the repository |
| 650 if self.config.type == 'android': | 650 if self.config.type == 'android': |
| 651 self.readAndroidMetadata() | 651 self.readAndroidMetadata() |
| 652 elif self.config.type == 'chrome': | 652 elif self.config.type == 'chrome': |
| 653 self.readChromeMetadata() | 653 self.readChromeMetadata() |
| 654 elif self.config.type == 'safari': | 654 elif self.config.type == 'safari': |
| 655 self.readSafariMetadata() | 655 self.readSafariMetadata() |
| 656 elif self.config.type in {'gecko', 'gecko-webext'}: | 656 elif self.config.type == 'gecko': |
| 657 self.readGeckoMetadata() | 657 self.readGeckoMetadata() |
| 658 elif self.config.type == 'edge': | 658 elif self.config.type == 'edge': |
| 659 self.read_edge_metadata() | 659 self.read_edge_metadata() |
| 660 else: | 660 else: |
| 661 raise Exception('Unknown build type {}' % self.config.type) | 661 raise Exception('Unknown build type {}' % self.config.type) |
| 662 | 662 |
| 663 # create development build | 663 # create development build |
| 664 self.build() | 664 self.build() |
| 665 | 665 |
| 666 # write out changelog | 666 # write out changelog |
| 667 self.writeChangelog(self.getChanges()) | 667 self.writeChangelog(self.getChanges()) |
| 668 | 668 |
| 669 # write update manifest | 669 # write update manifest |
| 670 self.writeUpdateManifest() | 670 self.writeUpdateManifest() |
| 671 | 671 |
| 672 # retire old builds | 672 # retire old builds |
| 673 versions = self.retireBuilds() | 673 versions = self.retireBuilds() |
| 674 | 674 |
| 675 if self.config.type == 'ie': | 675 if self.config.type == 'ie': |
| 676 self.writeIEUpdateManifest(versions) | 676 self.writeIEUpdateManifest(versions) |
| 677 | 677 |
| 678 # update index page | 678 # update index page |
| 679 self.updateIndex(versions) | 679 self.updateIndex(versions) |
| 680 | 680 |
| 681 # update nightlies config | 681 # update nightlies config |
| 682 self.config.latestRevision = self.revision | 682 self.config.latestRevision = self.revision |
| 683 | 683 |
| 684 if (self.config.type in {'gecko', 'gecko-webext'} and | 684 if (self.config.type == 'gecko' and |
| 685 self.config.galleryID and | 685 self.config.galleryID and |
| 686 get_config().has_option('extensions', 'amo_key')): | 686 get_config().has_option('extensions', 'amo_key')): |
| 687 self.uploadToMozillaAddons() | 687 self.uploadToMozillaAddons() |
| 688 elif self.config.type == 'chrome' and self.config.clientID and self.
config.clientSecret and self.config.refreshToken: | 688 elif self.config.type == 'chrome' and self.config.clientID and self.
config.clientSecret and self.config.refreshToken: |
| 689 self.uploadToChromeWebStore() | 689 self.uploadToChromeWebStore() |
| 690 elif self.config.type == 'edge' and self.config.clientID and self.co
nfig.clientSecret and self.config.refreshToken and self.config.tenantID: | 690 elif self.config.type == 'edge' and self.config.clientID and self.co
nfig.clientSecret and self.config.refreshToken and self.config.tenantID: |
| 691 self.upload_to_windows_store() | 691 self.upload_to_windows_store() |
| 692 | 692 |
| 693 finally: | 693 finally: |
| 694 # clean up | 694 # clean up |
| (...skipping 22 matching lines...) Expand all Loading... |
| 717 except Exception as ex: | 717 except Exception as ex: |
| 718 logging.error('The build for %s failed:', repo) | 718 logging.error('The build for %s failed:', repo) |
| 719 logging.exception(ex) | 719 logging.exception(ex) |
| 720 | 720 |
| 721 file = open(nightlyConfigFile, 'wb') | 721 file = open(nightlyConfigFile, 'wb') |
| 722 nightlyConfig.write(file) | 722 nightlyConfig.write(file) |
| 723 | 723 |
| 724 | 724 |
| 725 if __name__ == '__main__': | 725 if __name__ == '__main__': |
| 726 main() | 726 main() |
| OLD | NEW |