def execute(self, nick, args, tool, sheriff): svn_revision_list, rollout_reason = self._parse_args(args) if (not svn_revision_list or not rollout_reason): return self.usage(nick) revision_urls_string = join_with_separators([ urls.view_revision_url(revision) for revision in svn_revision_list ]) tool.irc().post("%s: Preparing rollout for %s ..." % (nick, revision_urls_string)) self._update_working_copy(tool) # FIXME: IRCCommand should bind to a tool and have a self._tool like Command objects do. # Likewise we should probably have a self._sheriff. nicks_string = self._nicks_string(tool, sheriff, nick, svn_revision_list) try: complete_reason = "%s (Requested by %s on %s)." % ( rollout_reason, nick, config_irc.channel) bug_id = sheriff.post_rollout_patch(svn_revision_list, complete_reason) bug_url = tool.bugs.bug_url_for_bug_id(bug_id) tool.irc().post("%s: Created rollout: %s" % (nicks_string, bug_url)) except ScriptError as e: tool.irc().post("%s: Failed to create rollout patch:" % nicks_string) diff_failure = self._check_diff_failure(e.output, tool) if diff_failure: return "%s: %s" % (nicks_string, diff_failure) _post_error_and_check_for_bug_url(tool, nicks_string, e)
def execute(self, nick, args, tool, sheriff): svn_revision_list, rollout_reason = self._parse_args(args) if (not svn_revision_list or not rollout_reason): # return is equivalent to an irc().post(), but makes for easier unit testing. return "%s: Usage: rollout SVN_REVISION [SVN_REVISIONS] REASON" % nick self._update_working_copy(tool) # FIXME: IRCCommand should bind to a tool and have a self._tool like Command objects do. # Likewise we should probably have a self._sheriff. nicks_string = self._nicks_string(tool, sheriff, nick, svn_revision_list) revision_urls_string = join_with_separators([urls.view_revision_url(revision) for revision in svn_revision_list]) tool.irc().post("%s: Preparing rollout for %s..." % (nicks_string, revision_urls_string)) try: complete_reason = "%s (Requested by %s on %s)." % ( rollout_reason, nick, config_irc.channel) bug_id = sheriff.post_rollout_patch(svn_revision_list, complete_reason) bug_url = tool.bugs.bug_url_for_bug_id(bug_id) tool.irc().post("%s: Created rollout: %s" % (nicks_string, bug_url)) except ScriptError, e: tool.irc().post("%s: Failed to create rollout patch:" % nicks_string) _post_error_and_check_for_bug_url(tool, nicks_string, e)
def _prepare_state(self, options, args, tool): state = AbstractRolloutPrepCommand._prepare_state(self, options, args, tool) # Currently, state["bug_id"] points to the bug that caused the # regression. We want to create a new bug that blocks the old bug # so we move state["bug_id"] to state["bug_blocked"] and delete the # old state["bug_id"] so that steps.CreateBug will actually create # the new bug that we want (and subsequently store its bug id into # state["bug_id"]) state["bug_blocked"] = state["bug_id"] del state["bug_id"] state["bug_title"] = "REGRESSION(r%s): %s" % (state["revision"], state["reason"]) state["bug_description"] = "%s broke the build:\n%s" % (urls.view_revision_url(state["revision"]), state["reason"]) # FIXME: If we had more context here, we could link to other open bugs # that mention the test that regressed. if options.parent_command == "sheriff-bot": state["bug_description"] += """ This is an automatic bug report generated by the sheriff-bot. If this bug report was created because of a flaky test, please file a bug for the flaky test (if we don't already have one on file) and dup this bug against that bug so that we can track how often these flaky tests case pain. "Only you can prevent forest fires." -- Smokey the Bear """ return state
def execute(self, nick, args, tool, sheriff): svn_revision_list, rollout_reason = self._parse_args(args) if (not svn_revision_list or not rollout_reason): return self.usage(nick) revision_urls_string = join_with_separators([urls.view_revision_url(revision) for revision in svn_revision_list]) tool.irc().post("%s: Preparing rollout for %s ..." % (nick, revision_urls_string)) self._update_working_copy(tool) # FIXME: IRCCommand should bind to a tool and have a self._tool like Command objects do. # Likewise we should probably have a self._sheriff. nicks_string = self._nicks_string(tool, sheriff, nick, svn_revision_list) try: complete_reason = "%s (Requested by %s on %s)." % ( rollout_reason, nick, config_irc.channel) bug_id = sheriff.post_rollout_patch(svn_revision_list, complete_reason) bug_url = tool.bugs.bug_url_for_bug_id(bug_id) tool.irc().post("%s: Created rollout: %s" % (nicks_string, bug_url)) except ScriptError, e: tool.irc().post("%s: Failed to create rollout patch:" % nicks_string) diff_failure = self._check_diff_failure(e.output, tool) if diff_failure: return "%s: %s" % (nicks_string, diff_failure) _post_error_and_check_for_bug_url(tool, nicks_string, e)
def run(self, state): self._commit_message = self._tool.checkout().commit_message_for_this_commit(self._options.git_commit).message() if len(self._commit_message) < 50: raise Exception("Attempted to commit with a commit message shorter than 50 characters. Either your patch is missing a ChangeLog or webkit-patch may have a bug.") self._state = state username = None force_squash = False num_tries = 0 while num_tries < 3: num_tries += 1 try: scm = self._tool.scm() commit_text = scm.commit_with_message(self._commit_message, git_commit=self._options.git_commit, username=username, force_squash=force_squash) svn_revision = scm.svn_revision_from_commit_text(commit_text) log("Committed r%s: <%s>" % (svn_revision, urls.view_revision_url(svn_revision))) self._state["commit_text"] = commit_text break; except AmbiguousCommitError, e: if self._tool.user.confirm(self._commit_warning(e)): force_squash = True else: # This will correctly interrupt the rest of the commit process. raise ScriptError(message="Did not commit") except AuthenticationError, e: username = self._tool.user.prompt("%s login: "******"You need to specify the username on %s to perform the commit as." % self.svn_server_host)
def execute(self, nick, args, tool, sheriff): svn_revision_list, rollout_reason = self._parse_args(args) if (not svn_revision_list or not rollout_reason): # return is equivalent to an irc().post(), but makes for easier unit testing. return "%s: Usage: rollout SVN_REVISION [SVN_REVISIONS] REASON" % nick revision_urls_string = join_with_separators([ urls.view_revision_url(revision) for revision in svn_revision_list ]) tool.irc().post("%s: Preparing rollout for %s..." % (nick, revision_urls_string)) self._update_working_copy(tool) # FIXME: IRCCommand should bind to a tool and have a self._tool like Command objects do. # Likewise we should probably have a self._sheriff. nicks_string = self._nicks_string(tool, sheriff, nick, svn_revision_list) try: complete_reason = "%s (Requested by %s on %s)." % ( rollout_reason, nick, config_irc.channel) bug_id = sheriff.post_rollout_patch(svn_revision_list, complete_reason) bug_url = tool.bugs.bug_url_for_bug_id(bug_id) tool.irc().post("%s: Created rollout: %s" % (nicks_string, bug_url)) except ScriptError, e: tool.irc().post("%s: Failed to create rollout patch:" % nicks_string) _post_error_and_check_for_bug_url(tool, nicks_string, e)
def run(self, state): self._commit_message = self._tool.checkout( ).commit_message_for_this_commit(self._options.git_commit).message() if len(self._commit_message) < 10: raise Exception( "Attempted to commit with a commit message shorter than 10 characters. Either your patch is missing a ChangeLog or webkit-patch may have a bug." ) self._check_test_expectations(self._changed_files(state)) self._state = state username = None password = None force_squash = False num_tries = 0 while num_tries < 3: num_tries += 1 try: scm = self._tool.scm() commit_text = scm.commit_with_message( self._commit_message, git_commit=self._options.git_commit, username=username, password=password, force_squash=force_squash, changed_files=self._changed_files(state)) svn_revision = scm.svn_revision_from_commit_text(commit_text) log("Committed r%s: <%s>" % (svn_revision, urls.view_revision_url(svn_revision))) self._state["commit_text"] = commit_text break except AmbiguousCommitError, e: if self._options.non_interactive or self._tool.user.confirm( self._commit_warning(e)): force_squash = True else: # This will correctly interrupt the rest of the commit process. raise ScriptError(message="Did not commit") except AuthenticationError, e: if self._options.non_interactive: raise ScriptError(message="Authentication required") username = self._tool.user.prompt("%s login: "******"You need to specify the username on %s to perform the commit as." % e.server_host) if e.prompt_for_password: password = self._tool.user.prompt_password( "%s password for %s: " % (e.server_host, username), repeat=5) if not password: raise ScriptError( "You need to specify the password for %s on %s to perform the commit." % (username, e.server_host))
def blame_string(self, bugs): string = "r%s:\n" % self.revision() string += " %s\n" % urls.view_revision_url(self.revision()) string += " Bug: %s (%s)\n" % (self.bug_id(), bugs.bug_url_for_bug_id(self.bug_id())) author_line = "\"%s\" <%s>" % (self.author_name(), self.author_email()) string += " Author: %s\n" % unicode(self.author() or author_line) string += " Reviewer: %s\n" % unicode(self.reviewer() or self.reviewer_text()) string += " Committer: %s" % unicode(self.committer()) return string
def post_irc_warning(self, commit_info, builders): irc_nicknames = sorted(self.responsible_nicknames_from_commit_info(commit_info)) irc_prefix = ": " if irc_nicknames else "" irc_message = "%s%s%s might have broken %s" % ( ", ".join(irc_nicknames), irc_prefix, urls.view_revision_url(commit_info.revision()), join_with_separators([builder.name() for builder in builders])) self._tool.irc().post(irc_message)
def post_irc_warning(self, commit_info, builders): irc_nicknames = sorted( self.responsible_nicknames_from_commit_info(commit_info)) irc_prefix = ": " if irc_nicknames else "" irc_message = "%s%s%s might have broken %s" % ( ", ".join(irc_nicknames), irc_prefix, urls.view_revision_url(commit_info.revision()), join_with_separators([builder.name() for builder in builders])) self._tool.irc().post(irc_message)
def _message_for_revert(cls, revision_list, reason, bug_url=None): message = "Unreviewed, rolling out %s.\n" % join_with_separators(['r' + str(revision) for revision in revision_list]) for revision in revision_list: message += "%s\n" % urls.view_revision_url(revision) if bug_url: message += "%s\n" % bug_url # Add an extra new line after the rollout links, before any reason. message += "\n" if reason: message += "%s\n\n" % reason return message
def post_blame_comment_on_bug(self, commit_info, builders, tests): if not commit_info.bug_id(): return comment = "%s might have broken %s" % ( urls.view_revision_url(commit_info.revision()), join_with_separators([builder.name() for builder in builders])) if tests: comment += "\nThe following tests are not passing:\n" comment += "\n".join(tests) self._tool.bugs.post_comment_to_bug(commit_info.bug_id(), comment, cc=self._sheriffbot.watchers)
def _prepare_state(self, options, args, tool): state = AbstractRolloutPrepCommand._prepare_state(self, options, args, tool) state["bug_title"] = "REGRESSION(r%s): %s" % (state["revision"], state["reason"]) state["bug_description"] = "%s broke the build:\n%s" % (urls.view_revision_url(state["revision"]), state["reason"]) # FIXME: If we had more context here, we could link to other open bugs # that mention the test that regressed. if options.parent_command == "sheriff-bot": state["bug_description"] += """ This is an automatic bug report generated by webkitbot. If this bug report was created because of a flaky test, please file a bug for the flaky test (if we don't already have one on file) and dup this bug against that bug so that we can track how often these flaky tests fail. """ return state
def _message_for_revert(cls, revision_list, reason, description_list, reverted_bug_url_list, rollout_bug_url=None): message = "Unreviewed, rolling out %s.\n" % grammar.join_with_separators(['r' + str(revision) for revision in revision_list]) if rollout_bug_url: message += "%s\n" % rollout_bug_url message += "\n" if reason: message += "%s\n" % reason message += "\n" message += "Reverted %s:\n\n" % grammar.pluralize(len(revision_list), "changeset", showCount=False) for index in range(len(revision_list)): if description_list[index]: message += "\"%s\"\n" % description_list[index] if reverted_bug_url_list[index]: message += "%s\n" % reverted_bug_url_list[index] message += "%s\n\n" % urls.view_revision_url(revision_list[index]) return message
def _message_for_revert(cls, revision_list, reason, description_list, reverted_bug_url_list, rollout_bug_url=None): message = "Unreviewed, rolling out %s.\n" % join_with_separators(['r' + str(revision) for revision in revision_list]) if rollout_bug_url: message += "%s\n" % rollout_bug_url message += "\n" if reason: message += "%s\n" % reason message += "\n" pluralSuffix = 's' if len(revision_list) > 1 else '' message += "Reverted changeset%s:\n\n" % pluralSuffix for index in range(len(revision_list)): if description_list[index]: message += "\"%s\"\n" % description_list[index] if reverted_bug_url_list[index]: message += "%s\n" % reverted_bug_url_list[index] message += "%s\n\n" % urls.view_revision_url(revision_list[index]) return message
def run(self, state): self._commit_message = self._tool.checkout().commit_message_for_this_commit(self._options.git_commit).message() if len(self._commit_message) < 10: raise Exception("Attempted to commit with a commit message shorter than 10 characters. Either your patch is missing a ChangeLog or webkit-patch may have a bug.") self._check_test_expectations(self._changed_files(state)) self._state = state username = None password = None force_squash = self._options.non_interactive num_tries = 0 while num_tries < 3: num_tries += 1 try: scm = self._tool.scm() commit_text = scm.commit_with_message(self._commit_message, git_commit=self._options.git_commit, username=username, password=password, force_squash=force_squash, changed_files=self._changed_files(state)) svn_revision = scm.svn_revision_from_commit_text(commit_text) _log.info("Committed r%s: <%s>" % (svn_revision, urls.view_revision_url(svn_revision))) self._state["commit_text"] = commit_text break except AmbiguousCommitError, e: if self._tool.user.confirm(self._commit_warning(e)): force_squash = True else: # This will correctly interrupt the rest of the commit process. raise ScriptError(message="Did not commit") except AuthenticationError, e: if self._options.non_interactive: raise ScriptError(message="Authentication required") username = self._tool.user.prompt("%s login: "******"You need to specify the username on %s to perform the commit as." % e.server_host) if e.prompt_for_password: password = self._tool.user.prompt_password("%s password for %s: " % (e.server_host, username), repeat=5) if not password: raise ScriptError("You need to specify the password for %s on %s to perform the commit." % (username, e.server_host))
def _message_for_revert(cls, revision_list, reason, description_list, reverted_bug_url_list, revert_bug_url=None): message = "Unreviewed, reverting %s.\n" % grammar.join_with_separators( ['r' + str(revision) for revision in revision_list]) if revert_bug_url: message += "%s\n" % revert_bug_url message += "\n" if reason: message += "%s\n" % reason message += "\n" message += "Reverted %s:\n\n" % grammar.pluralize( len(revision_list), "changeset", showCount=False) for index in range(len(revision_list)): if description_list[index]: message += "\"%s\"\n" % description_list[index] if reverted_bug_url_list[index]: message += "%s\n" % reverted_bug_url_list[index] message += "%s\n\n" % urls.view_revision_url(revision_list[index]) return message
def execute(self, nick, args, tool, sheriff): return "%s: %s" % (nick, urls.view_revision_url(tool.buildbot.last_green_revision()))
def execute(self, nick, args, tool, sheriff): return "%s: %s" % ( nick, urls.view_revision_url(tool.buildbot.last_green_revision()))
def bug_comment_from_svn_revision(svn_revision): return "Committed r%s: <%s>" % (svn_revision, urls.view_revision_url(svn_revision))