-
Notifications
You must be signed in to change notification settings - Fork 89
feat: add time_to_first_review metric for pull requests #683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
zkoppert
merged 19 commits into
github-community-projects:main
from
meoyushi:feat-time-to-first-review
Mar 28, 2026
Merged
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
6e0c7ea
feat: add time_to_first_review metric for pull requests
meoyushi 98baab9
Merge branch 'github-community-projects:main' into feat-time-to-first…
meoyushi 346e6b5
fix: add tests, remove comment and lint fixed
meoyushi fe0b84e
fix: initialize first_review_time to None
meoyushi 694d390
fix: resolve lint issues and formatting
meoyushi 5c98ea6
fix: resolve remaining lint issues
meoyushi f8b44d7
fix: resolve isort formatting errors by removing blank lines
meoyushi 627921c
feat: add time_to_first_review in json and markdown
meoyushi 7317684
feat: add time to first review metric and update tests likewise
meoyushi 49e361c
Merge pull request #1 from github-community-projects/main
meoyushi 319ca22
fix: style and lint fix
meoyushi 1a23450
Merge branch 'main' into feat-time-to-first-review
meoyushi 6b25327
test: implement all requested coverage for time_to_first_review
meoyushi 04649aa
test: implement all requested coverage for time_to_first_review
meoyushi d5dbdb0
test: implement full coverage and fix all linting/formatting
meoyushi 4c11a67
Merge branch 'main' into feat-time-to-first-review
meoyushi 1038350
doc: README.md edited for time_to_first_review metric
meoyushi 676b5cf
doc: README.md edited for time_to_first_review metric
meoyushi be94607
doc: mdformat for README.md
meoyushi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| from datetime import datetime, timedelta | ||
| from typing import List, Union | ||
|
|
||
| import github3 | ||
| import numpy | ||
| from classes import IssueWithMetrics | ||
| from time_to_first_response import ignore_comment | ||
|
|
||
|
|
||
| def measure_time_to_first_review( | ||
| issue: Union[github3.issues.Issue, None], | ||
| pull_request: Union[github3.pulls.PullRequest, None], | ||
| ready_for_review_at: Union[datetime, None] = None, | ||
| ignore_users: Union[List[str], None] = None, | ||
| ) -> Union[timedelta, None]: | ||
| '''Measures duration between pull request creation time and the timestamp when the first review is submitted''' | ||
|
|
||
| if not issue or not pull_request: | ||
| return None | ||
|
|
||
| if ignore_users is None: | ||
| ignore_users = [] | ||
|
|
||
| '''first_review_time = None''' | ||
|
|
||
| try: | ||
| reviews = pull_request.reviews(number=50) | ||
| for review in reviews: | ||
| if ignore_comment( | ||
| issue.issue.user, | ||
| review.user, | ||
| ignore_users, | ||
| review.submitted_at, | ||
| ready_for_review_at, | ||
| ): | ||
| continue | ||
|
|
||
| first_review_time = review.submitted_at | ||
| break | ||
|
|
||
| except TypeError: | ||
| return None | ||
|
|
||
| if not first_review_time: | ||
| return None | ||
|
|
||
| if ready_for_review_at: | ||
| pr_created_time = ready_for_review_at | ||
| else: | ||
| pr_created_time = datetime.fromisoformat(issue.created_at) | ||
|
|
||
| return first_review_time - pr_created_time | ||
|
|
||
| def get_stats_time_to_first_review( | ||
| issues: List[IssueWithMetrics], | ||
| ) -> Union[dict[str, timedelta], None]: | ||
|
|
||
| review_times = [] | ||
| none_count = 0 | ||
| for issue in issues: | ||
| if issue.time_to_first_review: | ||
| review_times.append(issue.time_to_first_review.total_seconds()) | ||
| else: | ||
| none_count += 1 | ||
|
|
||
| if len(issues) - none_count <= 0: | ||
| return None | ||
|
|
||
| average_seconds_to_first_review = numpy.round(numpy.average(review_times)) | ||
| med_seconds_to_first_review = numpy.round(numpy.median(review_times)) | ||
| ninety_percentile_seconds_to_first_review = numpy.round(numpy.percentile(review_times, 90, axis=0)) | ||
|
|
||
| stats = { | ||
| "avg": timedelta(seconds=average_seconds_to_first_review), | ||
| "med": timedelta(seconds=med_seconds_to_first_review), | ||
| "90p": timedelta(seconds=ninety_percentile_seconds_to_first_review), | ||
| } | ||
|
|
||
| # Print the average time to first review converting seconds to a readable time format | ||
| print( | ||
| f"Average time to first review: {timedelta(seconds=average_seconds_to_first_review)}" | ||
| ) | ||
|
|
||
| return stats |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.