Example #1
0
    def validate_product_approval(self):
        """
        notify in channel if not product approved (applicable only to files/dir which require product approval)
        :return: relevant response dict
        """
        if self.pr.is_merged:
            if self.pr.opened_by in self.pr.config.superMembers:
                LOG.debug('pr_opened_by is super user of {repo} so NO alert, super_members={super_members}'
                          .format(repo=self.pr.repo, super_members=self.pr.config.superMembers))
                return {"msg": "Skipped product review because the PR=%s is by a Super User" % self.pr.link_pretty}

            if self.change_requires_product_plus1:
                comments = self.github.get_comments()
                is_product_plus1 = self.is_plus_1_in_comments(comments, self.pr.config.productTeamGithub)
                if not is_product_plus1:
                    bad_name_str = MSG_BAD_START + "@" + self.created_by
                    msg = MSG_NO_PRODUCT_REVIEW.format(name=bad_name_str, pr=self.pr.link_pretty, title=self.pr.title,
                                                    branch=self.pr.base_branch, team="".join(self.pr.config.productTeamToBeNotified))
                    LOG.debug(msg)
                    self.slack.postToSlack(self.pr.config.alertChannelName, msg)
                    LOG.info("Bad PR={msg} repo:{repo}".format(repo=self.pr.repo, msg=self.is_bad_pr))
                    return {"msg": "Bad PR={msg} repo:{repo}".format(repo=self.pr.repo, msg=self.is_bad_pr)}
                return {"msg":"Product approved so no alert, pr=%s" %self.pr.link_pretty}
            return {"msg":"Skipped product review because no changes found which requires product +1 as well, PR=%s"
                          %self.pr.link_pretty}
        return {"msg": "Skipped product review because the PR=%s is not merged" %self.pr.link_pretty}
Example #2
0
 def run_checks(self, request, data):
     ci = CheckImpl(PushPayloadParser(request, payload=data))
     response = {}
     checks = ci.pr.config.checks
     if ci.pr.is_sensitive_branch:
         if len(checks) == 0:
             import inspect
             method_names = [
                 attr for attr in dir(ci)
                 if inspect.ismethod(getattr(ci, attr))
             ]
             for check in method_names:
                 if check != "__init__":
                     self.execute_check(ci, check)
         else:
             try:
                 for check in checks:
                     try:
                         self.execute_check(ci, check)
                     except AttributeError:
                         LOG.debug("Exception in Run Checks",
                                   exc_info=traceback)
                         raise CheckNotFoundException(check)
             except Exception, e:
                 LOG.debug("Exception in Run Checks", exc_info=traceback)
                 if 'invalid_auth' not in e:
                     raise Exception(
                         str(e) + ISSUE_FOUND.format(issue_link=ISSUE_LINK))
         return response
Example #3
0
 def notify_channel_on_merge(self):
     """
     pass entry in fixed channel for all code merge details (merged to any of sensitive branch)
     :return: relevant response dict
     """
     if self.pr.is_merged:
         LOG.debug(
             "**** Repo=%s, new merge came to=%s, setting trace to=%s channel"
             % (self.pr.repo, self.pr.base_branch,
                self.pr.config.codeChannelName))
         msg = MSG_CODE_CHANNEL.format(title=self.pr.title,
                                       desc=self.pr.description,
                                       pr=self.pr.link,
                                       head_branch=self.pr.head_branch,
                                       base_branch=self.pr.base_branch,
                                       pr_by=self.created_by,
                                       merge_by=self.merged_by)
         self.slack.postToSlack(self.pr.config.codeChannelName, msg)
         LOG.info(
             "informed %s because pr=%s is merged into sensitive branch=%s"
             % (self.pr.config.codeChannelName, self.pr.link_pretty,
                self.pr.base_branch))
         return {
             "msg":
             "informed %s because pr=%s is merged into sensitive branch=%s"
             % (self.pr.config.codeChannelName, self.pr.link_pretty,
                self.pr.base_branch)
         }
     return {
         "msg",
         "Skipped posting to code channel because '%s' is not merge event" %
         self.pr.action
     }
Example #4
0
 def modify_pr(self, msg, state):
     data = {
         "title": msg,
         "state": state
     }
     resp = requests.post(self.pr_api_link, json.dumps(data), headers=self.headers)
     LOG.debug(resp.content)
Example #5
0
 def validate_tech_approval(self):
     """
     notify in channel if not tech approved
     :return: relevant response dict
     """
     if self.pr.is_merged:  # and self.head_branch in PushPayload.PROTECTED_BRANCH_LIST:  TO ENABLE
         is_bad_pr = self.is_bad_pr()
         bad_name_str = MSG_BAD_START + "@" + self.created_by
         if is_bad_pr:
             msg = MSG_NO_TECH_REVIEW.format(
                 name=bad_name_str,
                 pr=self.pr.link_pretty,
                 title=self.pr.title,
                 branch=self.pr.base_branch,
                 team=self.pr.config.cc_tech_team)
             LOG.debug(msg)
             self.slack.postToSlack(self.pr.config.alertChannelName, msg)
             LOG.info("Bad PR={msg} repo:{repo}".format(repo=self.pr.repo,
                                                        msg=is_bad_pr))
             return {
                 "msg":
                 "Bad PR={msg} repo:{repo}".format(repo=self.pr.repo,
                                                   msg=is_bad_pr)
             }
         return {"msg": "PR is approved so No Alerts"}
     return {"msg": "Skipped review because its not PR merge event"}
Example #6
0
    def is_bad_pr(self):
        """
        parse approval's content to identify if PR is actually approved or just random approval click
        :return: bad_pr (boolean)
        """
        reviews = self.github.get_reviews()
        if 200 != reviews.status_code:
            raise Exception(reviews.content)

        bad_pr = True
        LOG.info("***** Reading Reviews *****")
        for item in json.loads(reviews.content):
            if "APPROVED" == item["state"]:
                review_comment = item["body"]
                LOG.debug("review body= %s" + review_comment)
                thumbsUpIcon = THUMBS_UP_ICON in json.dumps(review_comment)
                LOG.debug("unicode thumbsUp icon present=%s" % (thumbsUpIcon))
                if self.pr.opened_by in self.pr.config.superMembers:  # FEW FOLKS TO ALLOW TO HAVE SUPER POWER
                    LOG.debug("PR is opened by %s who is the super user of repo %s, so NO alert'"
                              % (self.pr.opened_by_slack, self.pr.repo))
                    bad_pr = False
                    break
                print "***** review_comment", review_comment
                created_by = self.pr.config.getSlackName(self.pr.opened_by)
                if item["user"]["login"] != created_by and (review_comment.find("+1") != -1 or thumbsUpIcon):
                    LOG.debug("+1 is found from reviewer=%s marking No Alert " % item["user"]["login"])
                    bad_pr = False
                    break
        return bad_pr
Example #7
0
    def notify_code_freeze(self):
        """
        gathers accumulated data after last qa_signOff and send an attachment into channel announcing details of code freeze
        :return: relevant response dict
        """
        if self.pr.is_merged and (self.pr.base_branch == self.pr.config.testBranch \
                and self.pr.head_branch == self.pr.config.devBranch):
            LOG.debug(
                "*** PR merged from {dev_branch} to {qa_branch}, posting release items to slack"
                .format(dev_branch=self.pr.config.devBranch,
                        qa_branch=self.pr.config.testBranch))

            write_to_file_from_top(
                self.pr.config.codeFreezeDetailsPath, ":clubs:" + str(
                    datetime.now(pytz.timezone(self.pr.config.timezone)).
                    strftime('%B %d at %I.%M %p')) + " with <" +
                self.pr.link_pretty + "|PR>")

            try:
                msg = read_from_file(self.pr.config.releaseItemsFilePath)
                LOG.debug("final msg =" + msg)
            except Exception, e:
                return {
                    "msg":
                    "Skipped posting code-freeze because no details found in file %s"
                    % self.pr.config.releaseItemsFilePath
                }

            CODE_FREEZE_TEXT[0]["pretext"] = CODE_FREEZE_TEXT[0][
                "pretext"].format(dev_branch=self.pr.config.devBranch,
                                  test_branch=self.pr.config.testBranch)
            CODE_FREEZE_TEXT[0]["fields"][0]["title"] =  CODE_FREEZE_TEXT[0]["fields"][0].get("title")\
                .format(test_branch=self.pr.config.testBranch)
            CODE_FREEZE_TEXT[0]["fields"][1]["value"] = CODE_FREEZE_TEXT[0][
                "fields"][1]["value"].format(pr=self.pr.link_pretty)
            CODE_FREEZE_TEXT[0]["text"] = CODE_FREEZE_TEXT[0]["text"].format(
                msg=msg)
            CODE_FREEZE_TEXT[0]["title_link"] = CODE_FREEZE_TEXT[0]["title_link"]\
                .format(release_notes_link=self.pr.config.release_notes_link)

            self.slack.postToSlack(channel=self.pr.config.alertChannelName,
                                   attachments=CODE_FREEZE_TEXT)
            self.remind_all_finally_to_update_release_notes()
            return {
                "msg":
                "informed code-freeze on %s for pr=%s" %
                (self.pr.config.alertChannelName, self.pr.link_pretty)
            }
Example #8
0
    def remind_all_finally_to_update_release_notes(self):
        """
        Final reminder to the folks who had merged code till the time code freeze was taken
        """
        names = read_from_file(self.pr.config.releaseItemsFileMergedBy)
        LOG.debug("final names list =" + names)
        if names:
            time.sleep(10)

            msg = RELEASE_NOTES_REMINDER.format(
                msg=names,
                release_notes_link=self.pr.config.release_notes_link,
                qa_team=self.pr.config.qaTeamMembers)
            self.slack.postToSlack(channel=self.pr.config.alertChannelName,
                                   msg=msg)
            self.clean_up_for_next_cycle()
Example #9
0
 def save_data_for_later(self):
     """
     saves merge event data on file to use for code freeze notification later on
     :return:
     """
     if self.pr.is_merged and self.pr.base_branch == self.pr.config.devBranch:
         msg = DATA_SAVE_MERGED.format(title=self.pr.title,
                                       desc=self.pr.description,
                                       pr=self.pr.link_pretty,
                                       by=self.pr.opened_by_slack)
         write_to_file_from_top(self.pr.config.releaseItemsFilePath, msg)
         with open(self.pr.config.releaseItemsFileMergedBy, "a+") as f:
             name = "<@{0}>".format(self.pr.opened_by_slack)
             existing_names = f.read()
             if name not in existing_names:
                 f.write(name + ", ")
                 LOG.debug(msg + ' added unique names to file ' +
                           self.pr.config.releaseItemsFileMergedBy)
             f.close()
Example #10
0
def setup_logging():
    if not app.debug:
        LOG.debug('************ log from setup_config *********')
Example #11
0
 def execute_check(self, ci, check):
     LOG.debug("************* Starting check=%s *****************" % check)
     response = getattr(ci, check)()
     LOG.debug("for check= %s, response= %s" % (check, response))
Example #12
0
 def comment_pr(self, comment_section, comment):
     resp = requests.post(comment_section, headers=self.headers,
                          data=json.dumps(comment))
     LOG.debug(resp.content)
Example #13
0
def clear_file(_file):
    LOG.debug("************** CLEARNING FILE=" + _file)
    open(_file, 'w').close()
Example #14
0
 def __init__(self, request, payload):
     self.request = request
     self.payload = payload
     self.pr = payload["pull_request"]
     LOG.debug("Repo=" + self.repo)
     self.config = ConfigProvider(self.repo)