def reopen_intermittent_bugs()

in treeherder/etl/bugzilla.py [0:0]


def reopen_intermittent_bugs(minimum_failures_to_reopen=1):
    # Don't reopen bugs from non-production deployments.
    if settings.BUGFILER_API_KEY is None:
        return

    incomplete_bugs = set(
        Bugscache.objects.filter(resolution="INCOMPLETE", bugzilla_id__isnull=False).values_list(
            "bugzilla_id", flat=True
        )
    )
    # Intermittent bugs get closed after 3 weeks of inactivity if other conditions don't apply:
    # https://github.com/mozilla/relman-auto-nag/blob/c7439e247677333c1cd8c435234b3ef3adc49680/auto_nag/scripts/close_intermittents.py#L17
    recent_days = 7
    recently_used_bugs = set(
        BugJobMap.objects.filter(created__gt=(datetime.now() - timedelta(recent_days)))
        .filter(bug__bugzilla_id__isnull=False)
        .values("bug__bugzilla_id")
        .annotate(num_failures=Count("bug__bugzilla_id"))
        .filter(num_failures__gte=minimum_failures_to_reopen)
        .values_list("bug__bugzilla_id", flat=True)
    )
    bugs_to_reopen = incomplete_bugs & recently_used_bugs

    for bugzilla_id in bugs_to_reopen:
        bug_data = (
            BugJobMap.objects.filter(bug__bugzilla_id=bugzilla_id)
            .select_related("job__repository")
            .order_by("-created")
            .values("job_id", "job__repository__name")[0]
        )
        job_id = bug_data.get("job_id")
        repository = bug_data.get("job__repository__name")
        log_url = f"https://treeherder.mozilla.org/logviewer?job_id={job_id}&repo={repository}"

        comment = {"body": "New failure instance: " + log_url}
        url = settings.BUGFILER_API_URL + "/rest/bug/" + str(bugzilla_id)
        headers = {
            "x-bugzilla-api-key": settings.BUGFILER_API_KEY,
            "Accept": "application/json",
        }
        data = {
            "status": "REOPENED",
            "comment": comment,
            "comment_tags": "treeherder",
        }

        try:
            reopen_request(url, method="PUT", headers=headers, json=data)
            # NOTE: this will only toggle 1 bug_job_map entry, not all (if there are retriggers)
            BugJobMap.objects.filter(job_id=job_id, bug__bugzilla_id=bugzilla_id).update(
                bug_open=True
            )
        except requests.exceptions.HTTPError as e:
            try:
                message = e.response.json()["message"]
            except (ValueError, KeyError):
                message = e.response.text
            logger.error(f"Reopening bug {str(bugzilla_id)} failed: {message}")