| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
| 6 | 6 |
| 7 """CBuildbot is wrapper around the build process used by the pre-flight queue""" | 7 """CBuildbot is wrapper around the build process used by the pre-flight queue""" |
| 8 | 8 |
| 9 import errno | 9 import errno |
| 10 import re | 10 import re |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 | 50 |
| 51 # Print out the command before running. | 51 # Print out the command before running. |
| 52 if print_cmd: | 52 if print_cmd: |
| 53 print >> sys.stderr, 'CBUILDBOT -- RunCommand: ', ' '.join(cmd) | 53 print >> sys.stderr, 'CBUILDBOT -- RunCommand: ', ' '.join(cmd) |
| 54 | 54 |
| 55 proc = subprocess.Popen(cmd, cwd=cwd, stdin=stdin, | 55 proc = subprocess.Popen(cmd, cwd=cwd, stdin=stdin, |
| 56 stdout=stdout, stderr=stderr) | 56 stdout=stdout, stderr=stderr) |
| 57 (output, error) = proc.communicate(input) | 57 (output, error) = proc.communicate(input) |
| 58 if exit_code: | 58 if exit_code: |
| 59 return proc.returncode | 59 return proc.returncode |
| 60 |
| 60 if not error_ok and proc.returncode != 0: | 61 if not error_ok and proc.returncode != 0: |
| 61 raise Exception('Command "%s" failed.\n' % (' '.join(cmd)) + | 62 raise Exception('Command "%s" failed.\n' % (' '.join(cmd)) + |
| 62 (error_message or error or output or '')) | 63 (error_message or error or output or '')) |
| 64 |
| 63 return output | 65 return output |
| 64 | 66 |
| 65 | 67 |
| 66 def MakeDir(path, parents=False): | 68 def MakeDir(path, parents=False): |
| 67 """Basic wrapper around os.mkdirs. | 69 """Basic wrapper around os.mkdirs. |
| 68 | 70 |
| 69 Keyword arguments: | 71 Keyword arguments: |
| 70 path -- Path to create. | 72 path -- Path to create. |
| 71 parents -- Follow mkdir -p logic. | 73 parents -- Follow mkdir -p logic. |
| 72 | 74 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 90 """ | 92 """ |
| 91 while retries > 0: | 93 while retries > 0: |
| 92 try: | 94 try: |
| 93 RunCommand(['repo', 'sync'], cwd=buildroot) | 95 RunCommand(['repo', 'sync'], cwd=buildroot) |
| 94 if rw_checkout: | 96 if rw_checkout: |
| 95 # Always re-run in case of new git repos or repo sync | 97 # Always re-run in case of new git repos or repo sync |
| 96 # failed in a previous run because of a forced Stop Build. | 98 # failed in a previous run because of a forced Stop Build. |
| 97 RunCommand(['repo', 'forall', '-c', 'git', 'config', | 99 RunCommand(['repo', 'forall', '-c', 'git', 'config', |
| 98 'url.ssh://git@gitrw.chromium.org:9222.pushinsteadof', | 100 'url.ssh://git@gitrw.chromium.org:9222.pushinsteadof', |
| 99 'http://git.chromium.org/git'], cwd=buildroot) | 101 'http://git.chromium.org/git'], cwd=buildroot) |
| 102 |
| 100 retries = 0 | 103 retries = 0 |
| 101 except: | 104 except: |
| 102 retries -= 1 | 105 retries -= 1 |
| 103 if retries > 0: | 106 if retries > 0: |
| 104 print >> sys.stderr, 'CBUILDBOT -- Repo Sync Failed, retrying' | 107 print >> sys.stderr, 'CBUILDBOT -- Repo Sync Failed, retrying' |
| 105 else: | 108 else: |
| 106 print >> sys.stderr, 'CBUILDBOT -- Retries exhausted' | 109 print >> sys.stderr, 'CBUILDBOT -- Retries exhausted' |
| 107 raise | 110 raise |
| 108 | 111 |
| 109 # =========================== Command Helpers ================================= | 112 # =========================== Command Helpers ================================= |
| (...skipping 13 matching lines...) Expand all Loading... |
| 123 # Parse line using re to get tuple. | 126 # Parse line using re to get tuple. |
| 124 result_array = re.findall('.+name=\"([\w-]+)\".+path=\"(\S+)".+', output) | 127 result_array = re.findall('.+name=\"([\w-]+)\".+path=\"(\S+)".+', output) |
| 125 | 128 |
| 126 # Create the array. | 129 # Create the array. |
| 127 for result in result_array: | 130 for result in result_array: |
| 128 if len(result) != 2: | 131 if len(result) != 2: |
| 129 print >> sys.stderr, 'Found in correct xml object %s', result | 132 print >> sys.stderr, 'Found in correct xml object %s', result |
| 130 else: | 133 else: |
| 131 # Remove pre-pended src directory from manifest. | 134 # Remove pre-pended src directory from manifest. |
| 132 manifest_tuples.append([result[0], result[1].replace('src/', '')]) | 135 manifest_tuples.append([result[0], result[1].replace('src/', '')]) |
| 136 |
| 133 return manifest_tuples | 137 return manifest_tuples |
| 134 | 138 |
| 135 | 139 |
| 136 def _GetCrosWorkOnSrcPath(buildroot, board, package, debug=False): | 140 def _GetCrosWorkOnSrcPath(buildroot, board, package, debug=False): |
| 137 """Returns ${CROS_WORKON_SRC_PATH} for given package.""" | 141 """Returns ${CROS_WORKON_SRC_PATH} for given package.""" |
| 138 cwd = os.path.join(buildroot, 'src', 'scripts') | 142 cwd = os.path.join(buildroot, 'src', 'scripts') |
| 139 equery_cmd = ('equery-%s which %s' % (board, package)).split() | 143 equery_cmd = ('equery-%s which %s' % (board, package)).split() |
| 140 ebuild_path = RunCommand(equery_cmd, cwd=cwd, redirect_stdout=True, | 144 ebuild_path = RunCommand(equery_cmd, cwd=cwd, redirect_stdout=True, |
| 141 redirect_stderr=True, enter_chroot=True, | 145 redirect_stderr=True, enter_chroot=True, |
| 142 error_ok=True, print_cmd=debug) | 146 error_ok=True, print_cmd=debug) |
| 143 if ebuild_path: | 147 if ebuild_path: |
| 144 ebuild_cmd = ('ebuild-%s %s info' % (board, ebuild_path)).split() | 148 ebuild_cmd = ('ebuild-%s %s info' % (board, ebuild_path)).split() |
| 145 cros_workon_output = RunCommand(ebuild_cmd, cwd=cwd, | 149 cros_workon_output = RunCommand(ebuild_cmd, cwd=cwd, |
| 146 redirect_stdout=True, redirect_stderr=True, | 150 redirect_stdout=True, redirect_stderr=True, |
| 147 enter_chroot=True, print_cmd=debug) | 151 enter_chroot=True, print_cmd=debug) |
| 148 | 152 |
| 149 temp = re.findall('CROS_WORKON_SRCDIR="(\S+)"', cros_workon_output) | 153 temp = re.findall('CROS_WORKON_SRCDIR="(\S+)"', cros_workon_output) |
| 150 if temp: | 154 if temp: |
| 151 return temp[0] | 155 return temp[0] |
| 156 |
| 152 return None | 157 return None |
| 153 | 158 |
| 154 | 159 |
| 155 def _CreateRepoDictionary(buildroot, board, debug=False): | 160 def _CreateRepoDictionary(buildroot, board, debug=False): |
| 156 """Returns the repo->list_of_ebuilds dictionary.""" | 161 """Returns the repo->list_of_ebuilds dictionary.""" |
| 157 repo_dictionary = {} | 162 repo_dictionary = {} |
| 158 manifest_tuples = _GetAllGitRepos(buildroot) | 163 manifest_tuples = _GetAllGitRepos(buildroot) |
| 159 print >> sys.stderr, 'Creating dictionary of git repos to portage packages ...
' | 164 print >> sys.stderr, ( |
| 165 'Creating dictionary of git repos to portage packages ...') |
| 160 | 166 |
| 161 cwd = os.path.join(buildroot, 'src', 'scripts') | 167 cwd = os.path.join(buildroot, 'src', 'scripts') |
| 162 get_all_workon_pkgs_cmd = './cros_workon list --all'.split() | 168 get_all_workon_pkgs_cmd = './cros_workon list --all'.split() |
| 163 packages = RunCommand(get_all_workon_pkgs_cmd, cwd=cwd, | 169 packages = RunCommand(get_all_workon_pkgs_cmd, cwd=cwd, |
| 164 redirect_stdout=True, redirect_stderr=True, | 170 redirect_stdout=True, redirect_stderr=True, |
| 165 enter_chroot=True, print_cmd=debug) | 171 enter_chroot=True, print_cmd=debug) |
| 166 for package in packages.split(): | 172 for package in packages.split(): |
| 167 cros_workon_src_path = _GetCrosWorkOnSrcPath(buildroot, board, package) | 173 cros_workon_src_path = _GetCrosWorkOnSrcPath(buildroot, board, package) |
| 168 if cros_workon_src_path: | 174 if cros_workon_src_path: |
| 169 for tuple in manifest_tuples: | 175 for tuple in manifest_tuples: |
| 170 # This path tends to have the user's home_dir prepended to it. | 176 # This path tends to have the user's home_dir prepended to it. |
| 171 if cros_workon_src_path.endswith(tuple[1]): | 177 if cros_workon_src_path.endswith(tuple[1]): |
| 172 print >> sys.stderr, ('For %s found matching package %s' % | 178 print >> sys.stderr, ('For %s found matching package %s' % |
| 173 (tuple[0], package)) | 179 (tuple[0], package)) |
| 174 if repo_dictionary.has_key(tuple[0]): | 180 if repo_dictionary.has_key(tuple[0]): |
| 175 repo_dictionary[tuple[0]] += [package] | 181 repo_dictionary[tuple[0]] += [package] |
| 176 else: | 182 else: |
| 177 repo_dictionary[tuple[0]] = [package] | 183 repo_dictionary[tuple[0]] = [package] |
| 184 |
| 178 return repo_dictionary | 185 return repo_dictionary |
| 179 | 186 |
| 180 | 187 |
| 181 def _ParseRevisionString(revision_string, repo_dictionary): | 188 def _ParseRevisionString(revision_string, repo_dictionary): |
| 182 """Parses the given revision_string into a revision dictionary. | 189 """Parses the given revision_string into a revision dictionary. |
| 183 | 190 |
| 184 Returns a list of tuples that contain [portage_package_name, commit_id] to | 191 Returns a list of tuples that contain [portage_package_name, commit_id] to |
| 185 update. | 192 update. |
| 186 | 193 |
| 187 Keyword arguments: | 194 Keyword arguments: |
| 188 revision_string -- revision_string with format | 195 revision_string -- revision_string with format |
| 189 'repo1.git@commit_1 repo2.git@commit2 ...'. | 196 'repo1.git@commit_1 repo2.git@commit2 ...'. |
| 190 repo_dictionary -- dictionary with git repository names as keys (w/out git) | 197 repo_dictionary -- dictionary with git repository names as keys (w/out git) |
| 191 to portage package names. | 198 to portage package names. |
| 192 | 199 |
| 193 """ | 200 """ |
| 194 # Using a dictionary removes duplicates. | 201 # Using a dictionary removes duplicates. |
| 195 revisions = {} | 202 revisions = {} |
| 196 for revision in revision_string.split(): | 203 for revision in revision_string.split(): |
| 197 # Format 'package@commit-id'. | 204 # Format 'package@commit-id'. |
| 198 revision_tuple = revision.split('@') | 205 revision_tuple = revision.split('@') |
| 199 if len(revision_tuple) != 2: | 206 if len(revision_tuple) != 2: |
| 200 print >> sys.stderr, 'Incorrectly formatted revision %s' % revision | 207 print >> sys.stderr, 'Incorrectly formatted revision %s' % revision |
| 208 |
| 201 repo_name = revision_tuple[0].replace('.git', '') | 209 repo_name = revision_tuple[0].replace('.git', '') |
| 202 # Might not have entry if no matching ebuild. | 210 # Might not have entry if no matching ebuild. |
| 203 if repo_dictionary.has_key(repo_name): | 211 if repo_dictionary.has_key(repo_name): |
| 204 # May be many corresponding packages to a given git repo e.g. kernel). | 212 # May be many corresponding packages to a given git repo e.g. kernel). |
| 205 for package in repo_dictionary[repo_name]: | 213 for package in repo_dictionary[repo_name]: |
| 206 revisions[package] = revision_tuple[1] | 214 revisions[package] = revision_tuple[1] |
| 215 |
| 207 return revisions.items() | 216 return revisions.items() |
| 208 | 217 |
| 209 | 218 |
| 210 def _UprevFromRevisionList(buildroot, revision_list): | 219 def _UprevFromRevisionList(buildroot, revision_list): |
| 211 """Uprevs based on revision list.""" | 220 """Uprevs based on revision list.""" |
| 212 if not revision_list: | 221 if not revision_list: |
| 213 print >> sys.stderr, 'No packages found to uprev' | 222 print >> sys.stderr, 'No packages found to uprev' |
| 214 return | 223 return |
| 224 |
| 215 package_str = '' | 225 package_str = '' |
| 216 commit_str = '' | 226 commit_str = '' |
| 217 for package, revision in revision_list: | 227 for package, revision in revision_list: |
| 218 package_str += package + ' ' | 228 package_str += package + ' ' |
| 219 commit_str += revision + ' ' | 229 commit_str += revision + ' ' |
| 230 |
| 220 package_str = package_str.strip() | 231 package_str = package_str.strip() |
| 221 commit_str = commit_str.strip() | 232 commit_str = commit_str.strip() |
| 222 | 233 |
| 223 cwd = os.path.join(buildroot, 'src', 'scripts') | 234 cwd = os.path.join(buildroot, 'src', 'scripts') |
| 224 RunCommand(['./cros_mark_as_stable', | 235 RunCommand(['./cros_mark_as_stable', |
| 225 '--tracking_branch="cros/master"', | 236 '--tracking_branch="cros/master"', |
| 226 '--packages="%s"' % package_str, | 237 '--packages="%s"' % package_str, |
| 227 '--commit_ids="%s"' % commit_str, | 238 '--commit_ids="%s"' % commit_str, |
| 228 'commit'], | 239 'commit'], |
| 229 cwd=cwd, enter_chroot=True) | 240 cwd=cwd, enter_chroot=True) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 def _SetupBoard(buildroot, board='x86-generic'): | 273 def _SetupBoard(buildroot, board='x86-generic'): |
| 263 """Wrapper around setup_board.""" | 274 """Wrapper around setup_board.""" |
| 264 cwd = os.path.join(buildroot, 'src', 'scripts') | 275 cwd = os.path.join(buildroot, 'src', 'scripts') |
| 265 RunCommand(['./setup_board', '--fast', '--default', '--board=%s' % board], | 276 RunCommand(['./setup_board', '--fast', '--default', '--board=%s' % board], |
| 266 cwd=cwd) | 277 cwd=cwd) |
| 267 | 278 |
| 268 | 279 |
| 269 def _Build(buildroot): | 280 def _Build(buildroot): |
| 270 """Wrapper around build_packages.""" | 281 """Wrapper around build_packages.""" |
| 271 cwd = os.path.join(buildroot, 'src', 'scripts') | 282 cwd = os.path.join(buildroot, 'src', 'scripts') |
| 272 RunCommand(['./build_packages'], cwd=cwd) | 283 RunCommand(['./build_packages'], cwd=cwd, enter_chroot=True) |
| 284 |
| 285 def _BuildImage(buildroot): |
| 286 cwd = os.path.join(buildroot, 'src', 'scripts') |
| 287 RunCommand(['./build_image'], cwd=cwd) |
| 288 |
| 289 def _RunUnitTests(buildroot): |
| 290 cwd = os.path.join(buildroot, 'src', 'scripts') |
| 291 RunCommand(['./cros_run_unit_tests'], cwd=cwd) |
| 273 | 292 |
| 274 | 293 |
| 275 def _UprevPackages(buildroot, revisionfile, board): | 294 def _UprevPackages(buildroot, revisionfile, board): |
| 276 """Uprevs a package based on given revisionfile. | 295 """Uprevs a package based on given revisionfile. |
| 277 | 296 |
| 278 If revisionfile is set to None or does not resolve to an actual file, this | 297 If revisionfile is set to None or does not resolve to an actual file, this |
| 279 function will uprev all packages. | 298 function will uprev all packages. |
| 280 | 299 |
| 281 Keyword arguments: | 300 Keyword arguments: |
| 282 revisionfile -- string specifying a file that contains a list of revisions to | 301 revisionfile -- string specifying a file that contains a list of revisions to |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 RunCommand(['./cros_mark_as_stable', '--srcroot=..', | 340 RunCommand(['./cros_mark_as_stable', '--srcroot=..', |
| 322 '--tracking_branch="cros/master"', | 341 '--tracking_branch="cros/master"', |
| 323 '--push_options', '--bypass-hooks -f', 'push'], | 342 '--push_options', '--bypass-hooks -f', 'push'], |
| 324 cwd=cwd) | 343 cwd=cwd) |
| 325 | 344 |
| 326 | 345 |
| 327 def _GetConfig(config_name): | 346 def _GetConfig(config_name): |
| 328 """Gets the configuration for the build""" | 347 """Gets the configuration for the build""" |
| 329 default = config['default'] | 348 default = config['default'] |
| 330 buildconfig = {} | 349 buildconfig = {} |
| 331 if config.has_key(config_name): | 350 if not config.has_key(config_name): |
| 332 buildconfig = config[config_name] | 351 print >> sys.stderr, 'Non-existent configuration specified.' |
| 352 print >> sys.stderr, 'Please specify one of:' |
| 353 config_names = config.keys() |
| 354 config_names.sort() |
| 355 for name in config_names: |
| 356 print >> sys.stderr, ' %s' % name |
| 357 sys.exit(1) |
| 358 |
| 359 buildconfig = config[config_name] |
| 360 |
| 333 for key in default.iterkeys(): | 361 for key in default.iterkeys(): |
| 334 if not buildconfig.has_key(key): | 362 if not buildconfig.has_key(key): |
| 335 buildconfig[key] = default[key] | 363 buildconfig[key] = default[key] |
| 364 |
| 336 return buildconfig | 365 return buildconfig |
| 337 | 366 |
| 338 | 367 |
| 339 def main(): | 368 def main(): |
| 340 # Parse options | 369 # Parse options |
| 341 usage = "usage: %prog [options] cbuildbot_config" | 370 usage = "usage: %prog [options] cbuildbot_config" |
| 342 parser = optparse.OptionParser(usage=usage) | 371 parser = optparse.OptionParser(usage=usage) |
| 343 parser.add_option('-r', '--buildroot', | 372 parser.add_option('-r', '--buildroot', |
| 344 help='root directory where build occurs', default=".") | 373 help='root directory where build occurs', default=".") |
| 345 parser.add_option('-n', '--buildnumber', | 374 parser.add_option('-n', '--buildnumber', |
| 346 help='build number', type='int', default=0) | 375 help='build number', type='int', default=0) |
| 347 parser.add_option('-f', '--revisionfile', | 376 parser.add_option('-f', '--revisionfile', |
| 348 help='file where new revisions are stored') | 377 help='file where new revisions are stored') |
| 349 parser.add_option('--noclobber', action='store_false', dest='clobber', | 378 parser.add_option('--noclobber', action='store_false', dest='clobber', |
| 350 default=True, | 379 default=True, |
| 351 help='Disables clobbering the buildroot on failure') | 380 help='Disables clobbering the buildroot on failure') |
| 352 (options, args) = parser.parse_args() | 381 (options, args) = parser.parse_args() |
| 353 | 382 |
| 354 buildroot = options.buildroot | 383 buildroot = options.buildroot |
| 355 revisionfile = options.revisionfile | 384 revisionfile = options.revisionfile |
| 356 clobber = options.clobber | 385 clobber = options.clobber |
| 357 | 386 |
| 358 if len(args) == 1: | 387 if len(args) == 1: |
| 359 buildconfig = _GetConfig(args[0]) | 388 buildconfig = _GetConfig(args[0]) |
| 360 else: | 389 else: |
| 361 print >> sys.stderr, "Missing configuration description" | 390 print >> sys.stderr, "Missing configuration description" |
| 362 parser.print_usage() | 391 parser.print_usage() |
| 363 sys.exit(1) | 392 sys.exit(1) |
| 393 |
| 364 try: | 394 try: |
| 365 if not os.path.isdir(buildroot): | 395 if not os.path.isdir(buildroot): |
| 366 _FullCheckout(buildroot) | 396 _FullCheckout(buildroot) |
| 367 else: | 397 else: |
| 368 _IncrementalCheckout(buildroot) | 398 _IncrementalCheckout(buildroot) |
| 399 |
| 369 chroot_path = os.path.join(buildroot, 'chroot') | 400 chroot_path = os.path.join(buildroot, 'chroot') |
| 370 if not os.path.isdir(chroot_path): | 401 if not os.path.isdir(chroot_path): |
| 371 _MakeChroot(buildroot) | 402 _MakeChroot(buildroot) |
| 403 |
| 372 boardpath = os.path.join(chroot_path, 'build', buildconfig['board']) | 404 boardpath = os.path.join(chroot_path, 'build', buildconfig['board']) |
| 373 if not os.path.isdir(boardpath): | 405 if not os.path.isdir(boardpath): |
| 374 _SetupBoard(buildroot, board=buildconfig['board']) | 406 _SetupBoard(buildroot, board=buildconfig['board']) |
| 407 |
| 375 if buildconfig['uprev']: | 408 if buildconfig['uprev']: |
| 376 _UprevPackages(buildroot, revisionfile, board=buildconfig['board']) | 409 _UprevPackages(buildroot, revisionfile, board=buildconfig['board']) |
| 410 |
| 377 _Build(buildroot) | 411 _Build(buildroot) |
| 412 if buildconfig['unittests']: |
| 413 _RunUnitTests(buildroot) |
| 414 |
| 415 _BuildImage(buildroot) |
| 378 if buildconfig['uprev']: | 416 if buildconfig['uprev']: |
| 379 if buildconfig['master']: | 417 if buildconfig['master']: |
| 380 # Master bot needs to check if the other slaves completed. | 418 # Master bot needs to check if the other slaves completed. |
| 381 if cbuildbot_comm.HaveSlavesCompleted(config): | 419 if cbuildbot_comm.HaveSlavesCompleted(config): |
| 382 _UprevPush(buildroot) | 420 _UprevPush(buildroot) |
| 383 _UprevCleanup(buildroot) | 421 _UprevCleanup(buildroot) |
| 384 else: | 422 else: |
| 385 # At least one of the slaves failed or we timed out. | 423 # At least one of the slaves failed or we timed out. |
| 386 _UprevCleanup(buildroot) | 424 _UprevCleanup(buildroot) |
| 387 sys.stderr('CBUILDBOT - One of the slaves has failed!!!') | 425 sys.stderr('CBUILDBOT - One of the slaves has failed!!!') |
| 388 sys.exit(1) | 426 sys.exit(1) |
| 389 else: | 427 else: |
| 390 # Publish my status to the master. | 428 # Publish my status to the master if its expecting it. |
| 391 cbuildbot_comm.PublishStatus(cbuildbot_comm.STATUS_BUILD_COMPLETE) | 429 if buildconfig['important']: |
| 430 cbuildbot_comm.PublishStatus(cbuildbot_comm.STATUS_BUILD_COMPLETE) |
| 431 |
| 392 _UprevCleanup(buildroot) | 432 _UprevCleanup(buildroot) |
| 393 except: | 433 except: |
| 394 # Something went wrong, cleanup (being paranoid) for next build. | 434 # Something went wrong, cleanup (being paranoid) for next build. |
| 395 if clobber: | 435 if clobber: |
| 396 RunCommand(['sudo', 'rm', '-rf', buildroot], print_cmd=False) | 436 RunCommand(['sudo', 'rm', '-rf', buildroot], print_cmd=False) |
| 437 |
| 397 # Send failure to master bot. | 438 # Send failure to master bot. |
| 398 if not buildconfig['master']: | 439 if not buildconfig['master'] and buildconfig['important']: |
| 399 cbuildbot_comm.PublishStatus(cbuildbot_comm.STATUS_BUILD_FAILED) | 440 cbuildbot_comm.PublishStatus(cbuildbot_comm.STATUS_BUILD_FAILED) |
| 441 |
| 400 raise | 442 raise |
| 401 | 443 |
| 402 | 444 |
| 403 if __name__ == '__main__': | 445 if __name__ == '__main__': |
| 404 main() | 446 main() |
| OLD | NEW |