You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by kn...@apache.org on 2021/05/19 08:09:48 UTC
[flink-jira-bot] 26/47: [FLINK-22034] add rule for stale major+
tickets
This is an automated email from the ASF dual-hosted git repository.
knaufk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink-jira-bot.git
commit aa8c557fa1d1623b1c05d9c247fab2dd12a50533
Author: Konstantin Knauf <kn...@gmail.com>
AuthorDate: Wed Apr 21 13:16:15 2021 +0200
[FLINK-22034] add rule for stale major+ tickets
---
config.yaml | 23 ++++++++++
flink_jira_bot.py | 13 ++++++
flink_jira_rule.py | 7 +++
stale_major_or_above_rule.py | 107 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 150 insertions(+)
diff --git a/config.yaml b/config.yaml
index d1cb3bb..d0e7aff 100644
--- a/config.yaml
+++ b/config.yaml
@@ -32,3 +32,26 @@ stale_minor:
done_label: "auto-closed"
done_comment: 'This issue has been labeled "{warning_label}" for {warning_days} days. It is closed now. If you are still affected by this or would like to raise the priority of this ticket please re-open, removing the label "{done_label}" and raise the ticket priority accordingly.'
+stale_blocker:
+ stale_days: 1
+ warning_days: 7
+ warning_label: "stale-blocker"
+ warning_comment: 'This Blockers is unassigned and itself and all of its Sub-Tasks have not been updated for {stale_days} days. So, it has been labeled "{warning_label}". If this ticket is a Blocker, please either assign yourself or give an update. Afterwards, please remove the label. In {warning_days} days the issue will be deprioritized.'
+ done_label: "auto-deprioritized-blocker"
+ done_comment: 'This issue has been labeled "{warning_label}" for {warning_days} days. It is deprioritized now. If this ticket is actually a Blocker, please raise the ticket priority again and assign yourself or revive the public discussion.'
+
+stale_critical:
+ stale_days: 7
+ warning_days: 7
+ warning_label: "stale-critical"
+ warning_comment: 'This critical issue is unassigned and itself and all of its Sub-Tasks have not been updated for {stale_days} days. So, it has been labeled "{warning_label}". If this ticket is indeed critical, please either assign yourself or give an update. Afterwards, please remove the label. In {warning_days} days the issue will be deprioritized.'
+ done_label: "auto-deprioritized-critical"
+ done_comment: 'This issue has been labeled "{warning_label}" for {warning_days} days. It is deprioritized now. If this ticket is actually critical, please raise the ticket priority again and assign yourself or revive the public discussion.'
+
+stale_major:
+ stale_days: 30
+ warning_days: 7
+ warning_label: "stale-major"
+ warning_comment: 'This major issue is unassigned and itself and all of its Sub-Tasks have not been updated for {stale_days} days. So, it has been labeled "{warning_label}". If this ticket is indeed "major", please either assign yourself or give an update. Afterwards, please remove the label. In {warning_days} days the issue will be deprioritized.'
+ done_label: "auto-deprioritized-major"
+ done_comment: 'This issue has been labeled "{warning_label}" for {warning_days} days. It is deprioritized now. If this ticket is actually "major", please raise the ticket priority again and assign yourself or revive the public discussion.'
diff --git a/flink_jira_bot.py b/flink_jira_bot.py
index 211f855..80a58e9 100644
--- a/flink_jira_bot.py
+++ b/flink_jira_bot.py
@@ -24,6 +24,7 @@ from argparse import ArgumentParser
from pathlib import Path
from stale_assigned_rule import StaleAssignedRule
+from stale_major_or_above_rule import StaleMajorOrAboveRule
from stale_minor_rule import StaleMinorRule
@@ -63,5 +64,17 @@ if __name__ == "__main__":
stale_assigned_rule = StaleAssignedRule(jira, jira_bot_config, args.dryrun)
stale_minor_rule = StaleMinorRule(jira, jira_bot_config, args.dryrun)
+ stale_major_rule = StaleMajorOrAboveRule(
+ jira, jira_bot_config, args.dryrun, "Major"
+ )
+ stale_critical_rule = StaleMajorOrAboveRule(
+ jira, jira_bot_config, args.dryrun, "Critical"
+ )
+ stale_blocker_rule = StaleMajorOrAboveRule(
+ jira, jira_bot_config, args.dryrun, "Blocker"
+ )
stale_assigned_rule.run()
stale_minor_rule.run()
+ stale_major_rule.run()
+ stale_critical_rule.run()
+ stale_blocker_rule.run()
diff --git a/flink_jira_rule.py b/flink_jira_rule.py
index 9960aca..566fce7 100644
--- a/flink_jira_rule.py
+++ b/flink_jira_rule.py
@@ -98,6 +98,13 @@ class FlinkJiraRule:
else:
logging.info(f"DRY_RUN (({key})): Unassigning.")
+ def set_priority(self, key, priority):
+ if not self.is_dry_run:
+ fields = {"priority": {"name": priority}}
+ self.jira_client.update_issue_field(key, fields)
+ else:
+ logging.info(f"DRY_RUN (({key})): Setting to {priority}")
+
@abc.abstractmethod
def run(self):
return
diff --git a/stale_major_or_above_rule.py b/stale_major_or_above_rule.py
new file mode 100644
index 0000000..de3cb17
--- /dev/null
+++ b/stale_major_or_above_rule.py
@@ -0,0 +1,107 @@
+################################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+################################################################################
+
+import logging
+
+from flink_jira_rule import FlinkJiraRule
+
+
+class StaleMajorOrAboveRule(FlinkJiraRule):
+ """
+ Tickets major and above need an assignee, or an update within {stale_<blocker|critical|major>.stale_days},
+ otherwise the priority will be reduced after a warning period of {stale_<blocker|critical|major>.warning_days} days.
+ An update of on of the Sub-Tasks counts as an update to the ticket.
+ Before this happens the assignee/reporter/watchers are notified that the ticket is about to become stale and will
+ be deprioritized.
+ The time periods before warning differ based on the priority:
+ """
+
+ def __init__(self, jira_client, config, is_dry_run, priority):
+ super().__init__(jira_client, config, is_dry_run)
+ self.stale_days = config[f"stale_{priority.lower()}"]["stale_days"].get()
+ self.warning_days = config[f"stale_{priority.lower()}"]["warning_days"].get()
+ self.warning_label = config[f"stale_{priority.lower()}"]["warning_label"].get()
+ self.done_label = config[f"stale_{priority.lower()}"]["done_label"].get()
+ self.done_comment = config[f"stale_{priority.lower()}"]["done_comment"].get()
+ self.warning_comment = config[f"stale_{priority.lower()}"][
+ "warning_comment"
+ ].get()
+ self.priority = priority
+
+ LOWER_PRIORITIES = {"Blocker": "Critical", "Critical": "Major", "Major": "Minor"}
+
+ def run(self):
+ self.close_tickets_marked_stale()
+ self.mark_stale_tickets_stale()
+
+ def close_tickets_marked_stale(self):
+
+ tickets_marked_stale = (
+ f"project=FLINK AND Priority = {self.priority} AND resolution = Unresolved AND labels in "
+ f'("{self.warning_label}") AND updated < startOfDay(-{self.warning_days}d)'
+ )
+ logging.info(
+ f"Looking for {self.priority} tickets, which were previously marked as {self.warning_label}."
+ )
+ issues = self.get_issues(tickets_marked_stale)
+
+ for issue in issues:
+ key = issue["key"]
+ logging.info(
+ f"Found https://issues.apache.org/jira/browse/{key}. It is now deprioritized due to inactivity."
+ )
+
+ formatted_comment = self.done_comment.format(
+ warning_days=self.warning_days,
+ warning_label=self.warning_label,
+ done_label=self.done_label,
+ )
+
+ self.add_comment(key, formatted_comment)
+ self.replace_label(issue, self.warning_label, self.done_label)
+ self.set_priority(key, self.LOWER_PRIORITIES[self.priority])
+
+ def mark_stale_tickets_stale(self):
+
+ stale_tickets = f"project=FLINK AND priority = {self.priority} AND resolution = Unresolved AND assignee is " \
+ f"empty AND updated < startOfDay(-{self.stale_days}d)"
+ logging.info(f"Looking for {self.priority} tickets, which are stale.")
+ issues = self.get_issues(stale_tickets)
+
+ for issue in issues:
+ key = issue["key"]
+ issue = self.jira_client.get_issue(key)
+
+ if not self.has_recently_updated_subtask(key, self.stale_days):
+ logging.info(
+ f"Found https://issues.apache.org/jira/browse/{key}. It is marked stale now."
+ )
+ formatted_comment = self.warning_comment.format(
+ stale_days=self.stale_days,
+ warning_days=self.warning_days,
+ warning_label=self.warning_label,
+ )
+
+ self.add_label(issue, self.warning_label)
+ self.add_comment(key, formatted_comment)
+
+ else:
+ logging.info(
+ f"Found https://issues.apache.org/jira/browse/{key}, but is has recently updated Subtasks. "
+ f"Ignoring for now."
+ )