Skip to content
Permalink
Browse files
[FLINK-22034] add rule for stale major+ tickets
  • Loading branch information
knaufk committed Apr 22, 2021
1 parent 425f75f commit aa8c557fa1d1623b1c05d9c247fab2dd12a50533
Showing 4 changed files with 150 additions and 0 deletions.
@@ -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.'
@@ -24,6 +24,7 @@
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 @@ def get_args():

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()
@@ -98,6 +98,13 @@ def unassign(self, key):
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
@@ -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."
)

0 comments on commit aa8c557

Please sign in to comment.