Skip to content

Commit

Permalink
Merge pull request #11 from github/count
Browse files Browse the repository at this point in the history
feat: add issue open and close counts
  • Loading branch information
zkoppert authored Jun 3, 2023
2 parents 74f66de + ce86b80 commit d70895a
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 11 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
REPOSITORY_URL: https://github.com/owner/repo
ISSUE_SEARCH_QUERY: "is:issue closed:2023-05-01..2023-05-31 reason:completed"
ISSUE_SEARCH_QUERY: 'is:issue created:2023-05-01..2023-05-31 -reason:"not planned"'

- name: Create issue
uses: peter-evans/create-issue-from-file@v4
Expand All @@ -60,7 +60,9 @@ jobs:
# Issue Metrics

Average time to first response: 2 days, 3:30:00
Number of issues: 2
Number of issues that remain open: 0
Number of issues closed: 2
Total number of issues created: 2

| Title | URL | TTFR |
| --- | --- | ---: |
Expand Down
72 changes: 66 additions & 6 deletions issue_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,49 @@ def get_average_time_to_first_response(issues):
return timedelta(seconds=average_seconds_to_first_response)


def write_to_markdown(issues_with_metrics, average_time_to_first_response, file=None):
def get_number_of_issues_open(issues):
"""Get the number of issues that were opened.
Args:
issues (list of github3.Issue): A list of GitHub issues.
Returns:
int: The number of issues that were opened.
"""
num_issues_opened = 0
for issue in issues:
if issue.state == "open":
num_issues_opened += 1

return num_issues_opened


def get_number_of_issues_closed(issues):
"""Get the number of issues that were closed.
Args:
issues (list of github3.Issue): A list of GitHub issues.
Returns:
int: The number of issues that were closed.
"""
num_issues_closed = 0
for issue in issues:
if issue.state == "closed":
num_issues_closed += 1

return num_issues_closed


def write_to_markdown(
issues_with_metrics,
average_time_to_first_response,
num_issues_opened,
num_issues_closed,
file=None,
):
"""Write the issues with metrics to a markdown file.
Args:
Expand All @@ -156,12 +198,19 @@ def write_to_markdown(issues_with_metrics, average_time_to_first_response, file=
response for the issues.
file (file object, optional): The file object to write to. If not provided,
a file named "issue_metrics.md" will be created.
num_issues_opened (int): The number of issues that remain opened.
num_issues_closed (int): The number of issues that were closed.
Returns:
None.
"""
if not issues_with_metrics and not average_time_to_first_response:
if (
not issues_with_metrics
and not average_time_to_first_response
and not num_issues_opened
and not num_issues_closed
):
with file or open("issue_metrics.md", "w", encoding="utf-8") as file:
file.write("no issues found for the given search criteria\n\n")
else:
Expand All @@ -171,7 +220,11 @@ def write_to_markdown(issues_with_metrics, average_time_to_first_response, file=
file.write(
f"Average time to first response: {average_time_to_first_response}\n"
)
file.write(f"Number of issues: {len(issues_with_metrics)}\n\n")
file.write(f"Number of issues that remain open: {num_issues_opened}\n")
file.write(f"Number of issues closed: {num_issues_closed}\n")
file.write(
f"Total number of issues created: {len(issues_with_metrics)}\n\n"
)
file.write("| Title | URL | TTFR |\n")
file.write("| --- | --- | ---: |\n")
for title, url, ttfr in issues_with_metrics:
Expand Down Expand Up @@ -214,17 +267,24 @@ def main():
issues = search_issues(repo_url, issue_search_query, github_connection)
if len(issues.items) <= 0:
print("No issues found")
write_to_markdown(None, None)
write_to_markdown(None, None, None, None)

return
# Find the time to first response
# Find the time to first response, average, open, and closed issues
issues_with_ttfr = measure_time_to_first_response(issues)
average_time_to_first_response = get_average_time_to_first_response(
issues_with_ttfr
)
num_issues_open = get_number_of_issues_open(issues)
num_issues_closed = get_number_of_issues_closed(issues)

# Write the results to a markdown file
write_to_markdown(issues_with_ttfr, average_time_to_first_response)
write_to_markdown(
issues_with_ttfr,
average_time_to_first_response,
num_issues_open,
num_issues_closed,
)


if __name__ == "__main__":
Expand Down
61 changes: 58 additions & 3 deletions test_issue_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,52 @@ def test_get_average_time_to_first_response(self):
)


class TestGetNumberOfIssuesOpened(unittest.TestCase):
"""Test case class for the get_number_of_issues_opened function in the issue_metrics module.
This class contains test cases for the get_number_of_issues_opened function,
which calculates the number of open issues in a list of GitHub issues.
"""

def test_get_number_of_issues_opened(self):
"""Test that get_number_of_issues_opened returns the correct number of open issues."""
# Set up the mock issues
mock_issues = [
MagicMock(state="open"),
MagicMock(state="closed"),
MagicMock(state="open"),
]

# Call get_number_of_issues_opened and check that it returns the
# correct number of open issues
num_issues_opened = issue_metrics.get_number_of_issues_open(mock_issues)
self.assertEqual(num_issues_opened, 2)


class TestGetNumberOfIssuesClosed(unittest.TestCase):
"""Test case class for the get_number_of_issues_closeded function in the issue_metrics module.
This class contains test cases for the get_number_of_issues_closed function,
which calculates the number of open issues in a list of GitHub issues.
"""

def test_get_number_of_issues_closed(self):
"""Test that get_number_of_issues_closed returns the correct number of closed issues."""
# Set up the mock issues
mock_issues = [
MagicMock(state="open"),
MagicMock(state="closed"),
MagicMock(state="open"),
]

# Call get_number_of_issues_opened and check that it returns the
# correct number of open issues
num_issues_closed = issue_metrics.get_number_of_issues_closed(mock_issues)
self.assertEqual(num_issues_closed, 1)


class TestWriteToMarkdown(unittest.TestCase):
"""Test the write_to_markdown function."""

Expand Down Expand Up @@ -192,8 +238,15 @@ def test_write_to_markdown(self):

# Call write_to_markdown with the list of issues and the average time to first response
average_time_to_first_response = timedelta(days=1, hours=3, minutes=10)
num_issues_open = 1
num_issues_closed = 2

write_to_markdown(
issues_with_metrics, average_time_to_first_response, file=None
issues_with_metrics,
average_time_to_first_response,
num_issues_open,
num_issues_closed,
file=None,
)

# Check that the function writes the correct markdown file
Expand All @@ -202,7 +255,9 @@ def test_write_to_markdown(self):
expected_content = (
"# Issue Metrics\n\n"
"Average time to first response: 1 day, 3:10:00\n"
"Number of issues: 3\n\n"
"Number of issues that remain open: 1\n"
"Number of issues closed: 2\n"
"Total number of issues created: 3\n\n"
"| Title | URL | TTFR |\n"
"| --- | --- | ---: |\n"
"| Issue 3 | https://github.com/user/repo/issues/3 | 0:30:00 |\n"
Expand Down Expand Up @@ -314,7 +369,7 @@ def test_main_no_issues_found(

# Call main and check that it writes 'No issues found'
issue_metrics.main()
mock_write_to_markdown.assert_called_once_with(None, None)
mock_write_to_markdown.assert_called_once_with(None, None, None, None)


if __name__ == "__main__":
Expand Down

0 comments on commit d70895a

Please sign in to comment.