• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mozilla / relman-auto-nag / #4349

pending completion
#4349

push

coveralls-python

sosa-e
Revert "Minimizing config file"

This reverts commit 614159597.

564 of 3081 branches covered (18.31%)

24 of 24 new or added lines in 24 files covered. (100.0%)

1804 of 7980 relevant lines covered (22.61%)

0.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/auto_nag/scripts/defectenhancementtask.py
1
# This Source Code Form is subject to the terms of the Mozilla Public
2
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
3
# You can obtain one at http://mozilla.org/MPL/2.0/.
4

5
from auto_nag.bugbug_utils import get_bug_ids_classification
×
6
from auto_nag.bzcleaner import BzCleaner
×
7
from auto_nag.utils import nice_round
×
8

9

10
class DefectEnhancementTask(BzCleaner):
×
11
    def __init__(self):
×
12
        super().__init__()
×
13
        self.autofix_type = {}
×
14

15
    def description(self):
×
16
        return "[Using ML] Check that the bug type is the same as predicted by bugbug"
×
17

18
    def columns(self):
×
19
        return [
×
20
            "id",
21
            "summary",
22
            "type",
23
            "bugbug_type",
24
            "confidence",
25
            "confidences",
26
            "autofixed",
27
        ]
28

29
    def sort_columns(self):
×
30
        def _sort_columns(p):
×
31
            if (
×
32
                p[2] == "defect"
33
            ):  # defect -> non-defect is what we plan to autofix, so we show it first in the email.
34
                prio = 0
×
35
            elif (
×
36
                p[3] == "defect"
37
            ):  # non-defect -> defect has more priority than the rest, as 'enhancement' and 'task' can be often confused.
38
                prio = 1
×
39
            else:
40
                prio = 2
×
41

42
            # Then, we sort by confidence and ID.
43
            # p[0] is the id and is a string
44
            return (prio, -p[4], -int(p[0]))
×
45

46
        return _sort_columns
×
47

48
    def handle_bug(self, bug, data):
×
49
        # Summary and id are injected by BzCleaner.bughandler
50
        data[str(bug["id"])] = {"type": bug["type"]}
×
51
        return data
×
52

53
    def get_bz_params(self, date):
×
54
        start_date, _ = self.get_dates(date)
×
55

56
        reporter_skiplist = self.get_config("reporter_skiplist", default=[])
×
57
        reporter_skiplist = ",".join(reporter_skiplist)
×
58

59
        return {
×
60
            "include_fields": ["id", "type"],
61
            # Ignore closed bugs.
62
            "bug_status": "__open__",
63
            # Check only recently opened bugs.
64
            "f1": "creation_ts",
65
            "o1": "greaterthan",
66
            "v1": start_date,
67
            "f2": "reporter",
68
            "o2": "nowords",
69
            "v2": reporter_skiplist,
70
            "f3": "bug_type",
71
            "o3": "everchanged",
72
            "n3": "1",
73
        }
74

75
    def get_bugs(self, date="today", bug_ids=[]):
×
76
        # Retrieve the bugs with the fields defined in get_bz_params
77
        raw_bugs = super().get_bugs(date=date, bug_ids=bug_ids, chunk_size=7000)
×
78

79
        if len(raw_bugs) == 0:
×
80
            return {}
×
81

82
        # Extract the bug ids
83
        bug_ids = list(raw_bugs.keys())
×
84

85
        # Classify those bugs
86
        bugs = get_bug_ids_classification("defectenhancementtask", bug_ids)
×
87

88
        results = {}
×
89

90
        for bug_id in sorted(bugs.keys()):
×
91
            bug_data = bugs[bug_id]
×
92

93
            if not bug_data.get("available", True):
×
94
                # The bug was not available, it was either removed or is a
95
                # security bug
96
                continue
×
97

98
            if not {"prob", "index", "class", "extra_data"}.issubset(bug_data.keys()):
×
99
                raise Exception(f"Invalid bug response {bug_id}: {bug_data!r}")
×
100

101
            bug = raw_bugs[bug_id]
×
102
            prob = bug_data["prob"]
×
103
            index = bug_data["index"]
×
104
            suggestion = bug_data["class"]
×
105
            labels_map = bug_data["extra_data"]["labels_map"]
×
106

107
            assert suggestion in {
×
108
                "defect",
109
                "enhancement",
110
                "task",
111
            }, f"Suggestion {suggestion} is invalid"
112

113
            if bug["type"] == suggestion:
×
114
                continue
×
115

116
            defect_prob = prob[labels_map["defect"]]
×
117
            enhancement_prob = prob[labels_map["enhancement"]]
×
118
            task_prob = prob[labels_map["task"]]
×
119

120
            results[bug_id] = {
×
121
                "id": bug_id,
122
                "summary": bug["summary"],
123
                "type": bug["type"],
124
                "bugbug_type": suggestion,
125
                "confidence": nice_round(prob[index]),
126
                "confidences": f"defect {nice_round(defect_prob)}, enhancement {nice_round(enhancement_prob)}, task {nice_round(task_prob)}",
127
                "autofixed": False,
128
            }
129

130
            # Only autofix results for which we are sure enough.
131
            # And only autofix defect -> task/enhancement for now, unless we're 100% sure.
132
            """if prob[index] == 1.0 or (
133
                bug["type"] == "defect"
134
                and (enhancement_prob + task_prob)
135
                >= self.get_config("confidence_threshold")
136
            ):"""
137
            if prob[index] == 1.0:
×
138
                results[bug_id]["autofixed"] = True
×
139
                self.autofix_type[bug["id"]] = suggestion
×
140

141
        return results
×
142

143
    def get_autofix_change(self):
×
144
        cc = self.get_config("cc")
×
145
        return {
×
146
            bug_id: {
147
                "type": suggestion,
148
                "cc": {"add": cc},
149
                "comment": {
150
                    "body": f"The [Bugbug](https://github.com/mozilla/bugbug/) bot thinks this bug is a [{suggestion}](https://firefox-source-docs.mozilla.org/bug-mgmt/guides/bug-types.html), but please change it back in case of error."
151
                },
152
            }
153
            for bug_id, suggestion in self.autofix_type.items()
154
        }
155

156

157
if __name__ == "__main__":
×
158
    DefectEnhancementTask().run()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc