From a9eb3e67924dbd1c975266cfdd14368656a268fd Mon Sep 17 00:00:00 2001 From: eichisanden Date: Sat, 16 Sep 2023 10:22:36 +0900 Subject: [PATCH 1/3] ignore bot's comments --- test_time_to_first_response.py | 30 ++++++++++++++++++++++++++++++ time_to_first_response.py | 4 ++++ 2 files changed, 34 insertions(+) diff --git a/test_time_to_first_response.py b/test_time_to_first_response.py index af7177b..dc8c6b5 100644 --- a/test_time_to_first_response.py +++ b/test_time_to_first_response.py @@ -280,6 +280,36 @@ def test_measure_time_to_first_response_ignore_issue_owners_comment(self): # Check the results self.assertEqual(result, expected_result) + def test_measure_time_to_first_response_ignore_bot(self): + """Test that measure_time_to_first_response ignore bot's comment.""" + # Set up the mock GitHub issues + mock_issue1 = MagicMock() + mock_issue1.comments = 2 + mock_issue1.created_at = "2023-01-01T00:00:00Z" + + # Set up the mock GitHub issue comments + mock_comment1 = MagicMock() + mock_comment1.user.type = "Bot" + mock_comment1.created_at = datetime.fromisoformat("2023-01-02T00:00:00Z") + mock_issue1.issue.comments.return_value = [mock_comment1] + + # Set up the mock GitHub pull request comments + mock_pr_comment1 = MagicMock() + mock_pr_comment1.user.type = "Bot" + mock_pr_comment1.submitted_at = datetime.fromisoformat("2023-01-03T00:00:00Z") + mock_pr_comment2 = MagicMock() + mock_pr_comment2.user.type = "User" + mock_pr_comment2.submitted_at = datetime.fromisoformat("2023-01-04T00:00:00Z") # first response + mock_pull_request = MagicMock() + mock_pull_request.reviews.return_value = [mock_pr_comment1, mock_pr_comment2] + + # Call the function + result = measure_time_to_first_response(mock_issue1, None, mock_pull_request, None) + expected_result = timedelta(days=3) + + # Check the results + self.assertEqual(result, expected_result) + class TestGetAverageTimeToFirstResponse(unittest.TestCase): """Test the get_average_time_to_first_response function.""" diff --git a/time_to_first_response.py b/time_to_first_response.py index b59702d..6cd7ea7 100644 --- a/time_to_first_response.py +++ b/time_to_first_response.py @@ -59,6 +59,8 @@ def measure_time_to_first_response( for comment in comments: if comment.user.login in ignore_users: continue + if comment.user.type == "Bot": + continue if comment.user.login == issue.issue.user.login: continue if ready_for_review_at and comment.created_at < ready_for_review_at: @@ -73,6 +75,8 @@ def measure_time_to_first_response( for review_comment in review_comments: if review_comment.user.login in ignore_users: continue + if review_comment.user.type == "Bot": + continue if review_comment.user.login == issue.issue.user.login: continue if ready_for_review_at and review_comment.submitted_at < ready_for_review_at: From 4c4def8ef14217b22513b3d437cc933bd71de9e7 Mon Sep 17 00:00:00 2001 From: eichisanden Date: Sat, 16 Sep 2023 12:02:33 +0900 Subject: [PATCH 2/3] refactor: fix lint error Split function to avoid "too complex" error when executing lint. --- time_to_first_response.py | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/time_to_first_response.py b/time_to_first_response.py index 6cd7ea7..ab84975 100644 --- a/time_to_first_response.py +++ b/time_to_first_response.py @@ -57,13 +57,7 @@ def measure_time_to_first_response( number=20, sort="created", direction="asc" ) # type: ignore for comment in comments: - if comment.user.login in ignore_users: - continue - if comment.user.type == "Bot": - continue - if comment.user.login == issue.issue.user.login: - continue - if ready_for_review_at and comment.created_at < ready_for_review_at: + if ignore_comment(issue.issue.user, comment.user, ignore_users, comment.created_at, ready_for_review_at): continue first_comment_time = comment.created_at break @@ -73,13 +67,8 @@ def measure_time_to_first_response( if pull_request: review_comments = pull_request.reviews(number=50) # type: ignore for review_comment in review_comments: - if review_comment.user.login in ignore_users: - continue - if review_comment.user.type == "Bot": - continue - if review_comment.user.login == issue.issue.user.login: - continue - if ready_for_review_at and review_comment.submitted_at < ready_for_review_at: + if ignore_comment(issue.issue.user, review_comment.user, ignore_users, + review_comment.submitted_at, ready_for_review_at): continue first_review_comment_time = review_comment.submitted_at break @@ -113,6 +102,25 @@ def measure_time_to_first_response( return None +def ignore_comment( + issue_user: github3.users.User, + comment_user: github3.users.User, + ignore_users: List[str], + comment_created_at: datetime, + ready_for_review_at: Union[datetime, None], +) -> bool: + """Check if a comment should be ignored.""" + return ( + # ignore comments by IGNORE_USERS + comment_user.login in ignore_users + # ignore comments by bots + or comment_user.type == "Bot" + # ignore comments by the issue creator + or comment_user.login == issue_user.login + # ignore comments created before the issue was ready for review + or (ready_for_review_at and comment_created_at < ready_for_review_at)) + + def get_average_time_to_first_response( issues: List[IssueWithMetrics], ) -> Union[timedelta, None]: From 867f85517b21812690b005f41cb42d7d8ed0b8e7 Mon Sep 17 00:00:00 2001 From: eichisanden Date: Sat, 16 Sep 2023 12:26:46 +0900 Subject: [PATCH 3/3] doc: update README Added that the issue author's own comments and comments by bots are excluded. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a7a9fc9..1bb581d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,8 @@ The metrics that are measured are: | Time to answer | (Discussions only) The time between when a discussion is created and when it is answered. | | Time in label | The time between when a label has a specific label applied to an issue/pull request/discussion and when it is removed. This requires the LABELS_TO_MEASURE env variable to be set. | -*For pull requests, these metrics exclude the time the PR was in draft mode. +*For pull requests, these metrics exclude the time the PR was in draft mode. +*For Issue and pull requests, issue/pull request author's own comments and comments by bots are excluded. This action was developed by the GitHub OSPO for our own use and developed in a way that we could open source it that it might be useful to you as well! If you want to know more about how we use it, reach out in an issue in this repository.