Skip to content

Commit

Permalink
Cleaning of warning comments (#7)
Browse files Browse the repository at this point in the history
* clean_warning_comments initial

* clean_warning_comments remove pull_request trigger from workflow
  • Loading branch information
soehms authored Mar 26, 2023
1 parent 631daf4 commit c829525
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 15 deletions.
103 changes: 92 additions & 11 deletions .github/sync_labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@

import os
import sys
from logging import info, warning, getLogger, INFO
from logging import info, warning, debug, getLogger, INFO, DEBUG
from json import loads
from enum import Enum
from datetime import datetime, timedelta
from subprocess import check_output, CalledProcessError

datetime_format = '%Y-%m-%dT%H:%M:%SZ'


class Action(Enum):
r"""
Expand Down Expand Up @@ -102,6 +107,7 @@ def __init__(self, url, actor):
"""
self._url = url
self._actor = actor
self._warning_prefix = 'Label Sync Warning:'
self._labels = None
self._author = None
self._draft = None
Expand All @@ -118,6 +124,7 @@ def __init__(self, url, actor):
self._issue = 'issue #%s' % number
self._pr = False
info('Create label handler for %s and actor %s' % (self._issue, self._actor))
self.clean_warnings()

# -------------------------------------------------------------------------
# methods to obtain properties of the issue
Expand All @@ -141,6 +148,21 @@ def reset_view(self):
self._commits = None
self._commit_date = None

def rest_api(self, path_args, method=None, query=''):
r"""
Return data obtained from ``gh`` command ``api``.
"""
s = self._url.split('/')
owner = s[3]
repo = s[4]
meth = '-X GET'
if method:
meth='-X %s' % method
cmd = 'gh api %s -H \"Accept: application/vnd.github+json\" /repos/%s/%s/%s %s' % (meth, owner, repo, path_args, query)
if method:
return check_output(cmd, shell=True)
return loads(check_output(cmd, shell=True))

def view(self, key):
r"""
Return data obtained from ``gh`` command ``view``.
Expand All @@ -149,7 +171,6 @@ def view(self, key):
if self._pr:
issue = 'pr'
cmd = 'gh %s view %s --json %s' % (issue, self._url, key)
from subprocess import check_output
return loads(check_output(cmd, shell=True))[key]

def is_open(self):
Expand Down Expand Up @@ -178,6 +199,49 @@ def is_draft(self):
info('Issue %s is draft %s' % (self._issue, self._draft))
return self._draft

def clean_warnings(self):
r"""
Remove all warnings that have been posted by ``GhLabelSynchronizer``
more than ``warning_lifetime`` ago.
"""
warning_lifetime = timedelta(minutes=5)
time_frame = timedelta(hours=12) # timedelta to search for comments
per_page = 100
today = datetime.today()
since = today - time_frame
query = '-F per_page=%s -F page={} -f since=%s' % (per_page, since.strftime(datetime_format))
path = 'issues/comments'
page = 1
comments = []
while True:
comments_page = self.rest_api(path, query=query.format(page))
comments += comments_page
if len(comments_page) < per_page:
break
page += 1

info('Cleaning warning comments since %s (total found %s)' % (since, len(comments)))

for c in comments:
login = c['user']['login']
body = c['body']
comment_id = c['id']
issue = c['issue_url'].split('/').pop()
created_at = c['created_at']
if login.startswith('github-actions'):
debug('github-actions comment %s created at %s on issue %s found' % (comment_id, created_at, issue))
if body.startswith(self._warning_prefix):
created = datetime.strptime(created_at, datetime_format)
lifetime = today - created
debug('github-actions %s %s is %s old' % (self._warning_prefix, comment_id, lifetime))
if lifetime > warning_lifetime:
try:
self.rest_api('%s/%s' % (path, comment_id), method='DELETE')
info('Comment %s on issue %s deleted' % (comment_id, issue))
except CalledProcessError:
# the comment may have been deleted by a bot running in parallel
info('Comment %s on issue %s has been deleted already' % (comment_id, issue))

def get_labels(self):
r"""
Return the list of labels of the issue resp. PR.
Expand Down Expand Up @@ -244,7 +308,7 @@ def get_reviews(self, complete=False):

if self._reviews is None:
self._reviews = self.view('reviews')
info('Reviews for %s: %s' % (self._issue, self._reviews))
debug('Reviews for %s: %s' % (self._issue, self._reviews))

if complete or not self._reviews:
return self._reviews
Expand Down Expand Up @@ -418,7 +482,7 @@ def gh_cmd(self, cmd, arg, option):
if self._pr:
issue = 'pr'
cmd_str = 'gh %s %s %s %s "%s"' % (issue, cmd, self._url, option, arg)
info('Execute command: %s' % cmd_str)
debug('Execute command: %s' % cmd_str)
ex_code = os.system(cmd_str)
if ex_code:
warning('Execution of %s failed with exit code: %s' % (cmd_str, ex_code))
Expand Down Expand Up @@ -466,10 +530,15 @@ def add_comment(self, text):
r"""
Perform a system call to ``gh`` to add a comment to an issue or PR.
"""

self.gh_cmd('comment', text, '-b')
info('Add comment to %s: %s' % (self._issue, text))

def add_warning(self, text):
r"""
Perform a system call to ``gh`` to add a warning to an issue or PR.
"""
self.add_comment('%s %s' % (self._warning_prefix, text))

def add_label(self, label):
r"""
Add the given label to the issue or PR.
Expand Down Expand Up @@ -508,10 +577,12 @@ def reject_label_addition(self, item):
Post a comment that the given label can not be added and select
a corresponding other one.
"""
if self.is_pull_request():
self.add_comment('Label *%s* can not be added. Please use the corresponding functionality of GitHub' % item.value)
if not self.is_pull_request():
self.add_warning('Label *%s* can not be added to an issue. Please use it on the corresponding PR' % item.value)
elif item is State.needs_review:
self.add_warning('Label *%s* can not be added, since there are unresolved reviews' % item.value)
else:
self.add_comment('Label *%s* can not be added to an issue. Please use it on the corresponding PR' % item.value)
self.add_warning('Label *%s* can not be added. Please use the GitHub review functionality' % item.value)
self.remove_label(item.value)
return

Expand All @@ -524,7 +595,7 @@ def reject_label_removal(self, item):
sel_list = 'state'
else:
sel_list = 'priority'
self.add_comment('Label *%s* can not be removed. Please add the %s-label which should replace it' % (item.value, sel_list))
self.add_warning('Label *%s* can not be removed. Please add the %s-label which should replace it' % (item.value, sel_list))
self.add_label(item.value)
return

Expand All @@ -549,7 +620,7 @@ def on_label_add(self, label):
# on the `on_label_add` of the first of the two labels
partn = self.active_partners(item)
if partn:
self.add_comment('Label *%s* can not be added due to *%s*!' % (label, partn[0].value))
self.add_warning('Label *%s* can not be added due to *%s*!' % (label, partn[0].value))
else:
warning('Label %s of %s not found!' % (label, self._issue))
return
Expand Down Expand Up @@ -731,7 +802,9 @@ def run_tests(self):
cmdline_args = sys.argv[1:]
num_args = len(cmdline_args)

getLogger().setLevel(INFO)
# getLogger().setLevel(INFO)
getLogger().setLevel(DEBUG)

info('cmdline_args (%s) %s' % (num_args, cmdline_args))

if num_args == 5:
Expand All @@ -756,6 +829,14 @@ def run_tests(self):
gh = GhLabelSynchronizer(url, actor)
gh.run_tests()

elif num_args == 1:
url, = cmdline_args

info('url: %s' % url)

gh = GhLabelSynchronizer(url, 'sagetrac-github-bot')

else:
print('Need 5 arguments: action, url, actor, label, rev_state' )
print('Running tests is possible with 2 arguments: url, actor' )
print('Cleaning warning comments is possible with 1 argument: url' )
6 changes: 2 additions & 4 deletions .github/workflows/sync_labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
name: Synchronize selection list lables

on:
pull_request_review:
types: [submitted]
issues:
types: [opened, reopened, closed, labeled, unlabeled]
pull_request:
types: [opened, reopened, closed, ready_for_review, converted_to_draft, synchronize, labeled, unlabeled]
pull_request_review:
types: [submitted]
pull_request_target:
types: [opened, reopened, closed, ready_for_review, converted_to_draft, synchronize, labeled, unlabeled]

Expand Down

0 comments on commit c829525

Please sign in to comment.