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

mozilla / relman-auto-nag / #4562

pending completion
#4562

push

coveralls-python

suhaibmujahid
[no_severity] Re-enable for bugs imported by Move to Bugzilla add-on

This reverts commit d86f8a9a1.

641 of 3222 branches covered (19.89%)

1821 of 8004 relevant lines covered (22.75%)

0.23 hits per line

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

0.0
/bugbot/rules/workflow/no_severity.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
import numpy
×
6
from libmozdata import utils as lmdutils
×
7

8
from bugbot import utils
×
9
from bugbot.bzcleaner import BzCleaner
×
10
from bugbot.escalation import Escalation
×
11
from bugbot.nag_me import Nag
×
12
from bugbot.round_robin import RoundRobin
×
13

14

15
class NoSeverity(BzCleaner, Nag):
×
16
    def __init__(self, typ, inactivity_days: int = 4):
×
17
        """Constructor
18

19
        Args:
20
            typ: the mode that the rule should run with (first or second). Nag
21
                emails will be sent only if `typ` is second.
22
            inactivity_days: number of days that a bug should be inactive before
23
                being considered.
24
        """
25
        super(NoSeverity, self).__init__()
×
26
        assert typ in {"first", "second"}
×
27
        self.typ = typ
×
28
        self.lookup_first = utils.get_config(self.name(), "first-step", 2)
×
29
        self.lookup_second = utils.get_config(self.name(), "second-step", 4)
×
30
        self.escalation = Escalation(
×
31
            self.people,
32
            data=utils.get_config(self.name(), "escalation-{}".format(typ)),
33
            skiplist=utils.get_config("workflow", "supervisor_skiplist", []),
34
        )
35
        self.round_robin = RoundRobin.get_instance()
×
36
        self.components_skiplist = utils.get_config("workflow", "components_skiplist")
×
37
        self.activity_date = str(
×
38
            numpy.busday_offset(lmdutils.get_date("today"), -inactivity_days)
39
        )
40

41
    def description(self):
×
42
        return "Bugs without a severity or statuses set"
×
43

44
    def nag_template(self):
×
45
        return self.template()
×
46

47
    def nag_preamble(self):
×
48
        return """<p>
×
49
  <ul>
50
    <li><a href="https://firefox-source-docs.mozilla.org/bug-mgmt/policies/triage-bugzilla.html#why-triage">Why triage?</a></li>
51
    <li><a href="https://firefox-source-docs.mozilla.org/bug-mgmt/policies/triage-bugzilla.html#what-do-you-triage">What do you triage?</a></li>
52
    <li><a href="https://firefox-source-docs.mozilla.org/bug-mgmt/guides/priority.html">Priority definitions</a></li>
53
    <li><a href="https://firefox-source-docs.mozilla.org/bug-mgmt/guides/severity.html">Severity definitions</a></li>
54
  </ul>
55
</p>"""
56

57
    def get_extra_for_template(self):
×
58
        return {
×
59
            "nweeks": self.lookup_first if self.typ == "first" else self.lookup_second
60
        }
61

62
    def get_extra_for_needinfo_template(self):
×
63
        return self.get_extra_for_template()
×
64

65
    def get_extra_for_nag_template(self):
×
66
        return self.get_extra_for_template()
×
67

68
    def has_product_component(self):
×
69
        return True
×
70

71
    def ignore_meta(self):
×
72
        return True
×
73

74
    def columns(self):
×
75
        return ["component", "id", "summary"]
×
76

77
    def handle_bug(self, bug, data):
×
78
        if (
×
79
            # check if the product::component is in the list
80
            utils.check_product_component(self.components_skiplist, bug)
81
            or utils.get_last_no_bot_comment_date(bug) > self.activity_date
82
        ):
83
            return None
×
84
        return bug
×
85

86
    def get_mail_to_auto_ni(self, bug):
×
87
        if self.typ == "second":
×
88
            return None
×
89

90
        mail, nick = self.round_robin.get(bug, self.date)
×
91
        if mail and nick:
×
92
            return {"mail": mail, "nickname": nick}
×
93

94
        return None
×
95

96
    def set_people_to_nag(self, bug, buginfo):
×
97
        priority = "default"
×
98
        if not self.filter_bug(priority):
×
99
            return None
×
100

101
        # don't nag in the first step (just a ni is enough)
102
        if self.typ == "first":
×
103
            return bug
×
104

105
        owners = self.round_robin.get(bug, self.date, only_one=False, has_nick=False)
×
106
        real_owner = bug["triage_owner"]
×
107
        self.add_triage_owner(owners, real_owner=real_owner)
×
108
        if not self.add(owners, buginfo, priority=priority):
×
109
            self.add_no_manager(buginfo["id"])
×
110
        return bug
×
111

112
    def get_bz_params(self, date):
×
113
        fields = [
×
114
            "triage_owner",
115
            "flags",
116
            "comments.creator",
117
            "comments.creation_time",
118
        ]
119
        params = {
×
120
            "include_fields": fields,
121
            "keywords": "intermittent-failure",
122
            "keywords_type": "nowords",
123
            "email2": "wptsync@mozilla.bugs",
124
            "emailreporter2": "1",
125
            "emailtype2": "notequals",
126
            "resolution": "---",
127
            "f31": "bug_type",
128
            "o31": "equals",
129
            "v31": "defect",
130
            "f32": "flagtypes.name",
131
            "o32": "notsubstring",
132
            "v32": "needinfo?",
133
            "f33": "bug_severity",
134
            "o33": "anyexact",
135
            "v33": "--, n/a",
136
        }
137
        self.date = lmdutils.get_date_ymd(date)
×
138
        first = f"-{self.lookup_first * 7}d"
×
139
        second = f"-{self.lookup_second * 7}d"
×
140
        if self.typ == "first":
×
141
            # TODO: change this when https://bugzilla.mozilla.org/1543984 will be fixed
142
            # Here we have to get bugs where product/component have been set (bug has been triaged)
143
            # between 4 and 2 weeks
144
            # If the product/component never changed after bug creation, we need to get them too
145
            # (second < p < first && c < first) ||
146
            # (second < c < first && p < first) ||
147
            # ((second < creation < first) && pc never changed)
148
            params.update(
×
149
                {
150
                    "f2": "flagtypes.name",
151
                    "o2": "notequals",
152
                    "v2": "needinfo?",
153
                    "j3": "OR",
154
                    "f3": "OP",
155
                    "j4": "AND",
156
                    "f4": "OP",
157
                    "n5": 1,  # we use a negation here to be sure that no change after first
158
                    "f5": "product",
159
                    "o5": "changedafter",
160
                    "v5": first,
161
                    "f6": "product",  # here the bug has changed
162
                    "o6": "changedafter",
163
                    "v6": second,
164
                    "n7": 1,
165
                    "f7": "component",
166
                    "o7": "changedafter",
167
                    "v7": first,
168
                    "f8": "CP",
169
                    "j9": "AND",
170
                    "f9": "OP",
171
                    "n10": 1,
172
                    "f10": "component",
173
                    "o10": "changedafter",
174
                    "v10": first,
175
                    "f11": "component",
176
                    "o11": "changedafter",
177
                    "v11": second,
178
                    "n12": 1,
179
                    "f12": "product",
180
                    "o12": "changedafter",
181
                    "v12": first,
182
                    "f13": "CP",
183
                    "j14": "AND",
184
                    "f14": "OP",
185
                    "f15": "creation_ts",
186
                    "o15": "lessthaneq",
187
                    "v15": first,
188
                    "f16": "creation_ts",
189
                    "o16": "greaterthan",
190
                    "v16": second,
191
                    "n17": 1,
192
                    "f17": "product",
193
                    "o17": "everchanged",
194
                    "n18": 1,
195
                    "f18": "component",
196
                    "o18": "everchanged",
197
                    "f19": "CP",
198
                    "j20": "OR",
199
                    "f20": "OP",
200
                    "f21": "bug_severity",
201
                    "o21": "changedfrom",
202
                    "v21": "critical",
203
                    "f22": "bug_severity",
204
                    "o22": "changedfrom",
205
                    "v22": "major",
206
                    "f23": "bug_severity",
207
                    "o23": "changedfrom",
208
                    "v23": "blocker",
209
                    "f24": "CP",
210
                    "f30": "CP",
211
                }
212
            )
213
        else:
214
            params.update(
×
215
                {
216
                    "j2": "OR",
217
                    "f2": "OP",
218
                    "j3": "AND",
219
                    "f3": "OP",
220
                    "f4": "product",
221
                    "o4": "changedbefore",
222
                    "v4": second,
223
                    "n5": 1,
224
                    "f5": "product",
225
                    "o5": "changedafter",
226
                    "v5": second,
227
                    "n6": 1,
228
                    "f6": "component",
229
                    "o6": "changedafter",
230
                    "v6": second,
231
                    "f7": "CP",
232
                    "j8": "AND",
233
                    "f8": "OP",
234
                    "f9": "component",
235
                    "o9": "changedbefore",
236
                    "v9": second,
237
                    "n10": 1,
238
                    "f10": "product",
239
                    "o10": "changedafter",
240
                    "v10": second,
241
                    "n11": 1,
242
                    "f11": "component",
243
                    "o11": "changedafter",
244
                    "v11": second,
245
                    "f12": "CP",
246
                    "j13": "AND",
247
                    "f13": "OP",
248
                    "f14": "creation_ts",
249
                    "o14": "lessthaneq",
250
                    "v14": second,
251
                    "n15": 1,
252
                    "f15": "product",
253
                    "o15": "everchanged",
254
                    "n16": 1,
255
                    "f16": "component",
256
                    "o16": "everchanged",
257
                    "f17": "CP",
258
                    "f18": "CP",
259
                    "n20": 1,
260
                    "j20": "OR",
261
                    "f20": "OP",
262
                    "f21": "bug_severity",
263
                    "o21": "changedfrom",
264
                    "v21": "critical",
265
                    "f22": "bug_severity",
266
                    "o22": "changedfrom",
267
                    "v22": "major",
268
                    "f23": "bug_severity",
269
                    "o23": "changedfrom",
270
                    "v23": "blocker",
271
                    "f30": "CP",
272
                }
273
            )
274

275
        return params
×
276

277

278
if __name__ == "__main__":
×
279
    NoSeverity("first").run()
×
280
    NoSeverity("second").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