Skip to content

Commit

Permalink
Merge pull request #379 from github/ignored-users-in-report
Browse files Browse the repository at this point in the history
fix: Remove ignore_users authored items from markdown results
  • Loading branch information
jmeridth authored Sep 24, 2024
2 parents c2911b8 + 04a9ee2 commit 8cee549
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 23 deletions.
38 changes: 19 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,25 +139,25 @@ This action can be configured to authenticate with GitHub App Installation or Pe

#### Other Configuration Options

| field | required | default | description |
| ----------------------------- | -------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GH_ENTERPRISE_URL` | False | `""` | URL of GitHub Enterprise instance to use for auth instead of github.com |
| `HIDE_AUTHOR` | False | False | If set to `true`, the author will not be displayed in the generated Markdown file. |
| `HIDE_ITEMS_CLOSED_COUNT` | False | False | If set to `true`, the number of items closed metric will not be displayed in the generated Markdown file. |
| `HIDE_LABEL_METRICS` | False | False | If set to `true`, the time in label metrics will not be displayed in the generated Markdown file. |
| `HIDE_TIME_TO_ANSWER` | False | False | If set to `true`, the time to answer a discussion will not be displayed in the generated Markdown file. |
| `HIDE_TIME_TO_CLOSE` | False | False | If set to `true`, the time to close will not be displayed in the generated Markdown file. |
| `HIDE_TIME_TO_FIRST_RESPONSE` | False | False | If set to `true`, the time to first response will not be displayed in the generated Markdown file. |
| `IGNORE_USERS` | False | False | A comma separated list of users to ignore when calculating metrics. (ie. `IGNORE_USERS: 'user1,user2'`). To ignore bots, append `[bot]` to the user (ie. `IGNORE_USERS: 'github-actions[bot]'`) |
| `ENABLE_MENTOR_COUNT` | False | False | If set to 'TRUE' count number of comments users left on discussions, issues and PRs and display number of active mentors |
| `MIN_MENTOR_COMMENTS` | False | 10 | Minimum number of comments to count as a mentor |
| `MAX_COMMENTS_EVAL` | False | 20 | Maximum number of comments per thread to evaluate for mentor stats |
| `HEAVILY_INVOLVED_CUTOFF` | False | 3 | Cutoff after which a mentor's comments in one issue are no longer counted against their total score |
| `LABELS_TO_MEASURE` | False | `""` | A comma separated list of labels to measure how much time the label is applied. If not provided, no labels durations will be measured. Not compatible with discussions at this time. |
| `NON_MENTIONING_LINKS` | False | False | If set to `true`, will use non-mentioning GitHub links to avoid linking to the generated issue from the source repository. Links of the form `https://www.github.com` will be used. |
| `OUTPUT_FILE` | False | `issue_metrics.md` or `issue_metrics.json` | Output filename. |
| `REPORT_TITLE` | False | `"Issue Metrics"` | Title to have on the report issue. |
| `SEARCH_QUERY` | True | `""` | The query by which you can filter issues/PRs which must contain a `repo:`, `org:`, `owner:`, or a `user:` entry. For discussions, include `type:discussions` in the query. |
| field | required | default | description |
| ----------------------------- | -------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GH_ENTERPRISE_URL` | False | `""` | URL of GitHub Enterprise instance to use for auth instead of github.com |
| `HIDE_AUTHOR` | False | False | If set to `true`, the author will not be displayed in the generated Markdown file. |
| `HIDE_ITEMS_CLOSED_COUNT` | False | False | If set to `true`, the number of items closed metric will not be displayed in the generated Markdown file. |
| `HIDE_LABEL_METRICS` | False | False | If set to `true`, the time in label metrics will not be displayed in the generated Markdown file. |
| `HIDE_TIME_TO_ANSWER` | False | False | If set to `true`, the time to answer a discussion will not be displayed in the generated Markdown file. |
| `HIDE_TIME_TO_CLOSE` | False | False | If set to `true`, the time to close will not be displayed in the generated Markdown file. |
| `HIDE_TIME_TO_FIRST_RESPONSE` | False | False | If set to `true`, the time to first response will not be displayed in the generated Markdown file. |
| `IGNORE_USERS` | False | False | A comma separated list of users to ignore when calculating metrics. (ie. `IGNORE_USERS: 'user1,user2'`). To ignore bots, append `[bot]` to the user (ie. `IGNORE_USERS: 'github-actions[bot]'`) Users in this list will also have their authored issues and pull requests removed from the Markdown table. |
| `ENABLE_MENTOR_COUNT` | False | False | If set to 'TRUE' count number of comments users left on discussions, issues and PRs and display number of active mentors |
| `MIN_MENTOR_COMMENTS` | False | 10 | Minimum number of comments to count as a mentor |
| `MAX_COMMENTS_EVAL` | False | 20 | Maximum number of comments per thread to evaluate for mentor stats |
| `HEAVILY_INVOLVED_CUTOFF` | False | 3 | Cutoff after which a mentor's comments in one issue are no longer counted against their total score |
| `LABELS_TO_MEASURE` | False | `""` | A comma separated list of labels to measure how much time the label is applied. If not provided, no labels durations will be measured. Not compatible with discussions at this time. |
| `NON_MENTIONING_LINKS` | False | False | If set to `true`, will use non-mentioning GitHub links to avoid linking to the generated issue from the source repository. Links of the form `https://www.github.com` will be used. |
| `OUTPUT_FILE` | False | `issue_metrics.md` or `issue_metrics.json` | Output filename. |
| `REPORT_TITLE` | False | `"Issue Metrics"` | Title to have on the report issue. |
| `SEARCH_QUERY` | True | `""` | The query by which you can filter issues/PRs which must contain a `repo:`, `org:`, `owner:`, or a `user:` entry. For discussions, include `type:discussions` in the query. |

## Further Documentation

Expand Down
3 changes: 3 additions & 0 deletions issue_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ def get_per_issue_metrics(
else:
num_issues_open += 1
else:
if ignore_users and issue.user["login"] in ignore_users: # type: ignore
continue

issue_with_metrics = IssueWithMetrics(
issue.title, # type: ignore
issue.html_url, # type: ignore
Expand Down
96 changes: 92 additions & 4 deletions test_issue_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def test_get_per_issue_metrics_with_hide_envs(self):
mock_issue1 = MagicMock(
title="Issue 1",
html_url="https://github.com/user/repo/issues/1",
author="alice",
user={"login": "alice"},
state="open",
comments=1,
created_at="2023-01-01T00:00:00Z",
Expand All @@ -209,7 +209,7 @@ def test_get_per_issue_metrics_with_hide_envs(self):
mock_issue2 = MagicMock(
title="Issue 2",
html_url="https://github.com/user/repo/issues/2",
author="bob",
user={"login": "bob"},
state="closed",
comments=1,
created_at="2023-01-01T00:00:00Z",
Expand Down Expand Up @@ -304,7 +304,7 @@ def test_get_per_issue_metrics_without_hide_envs(self):
mock_issue1 = MagicMock(
title="Issue 1",
html_url="https://github.com/user/repo/issues/1",
author="alice",
user={"login": "alice"},
state="open",
comments=1,
created_at="2023-01-01T00:00:00Z",
Expand All @@ -318,7 +318,7 @@ def test_get_per_issue_metrics_without_hide_envs(self):
mock_issue2 = MagicMock(
title="Issue 2",
html_url="https://github.com/user/repo/issues/2",
author="bob",
user={"login": "bob"},
state="closed",
comments=1,
created_at="2023-01-01T00:00:00Z",
Expand Down Expand Up @@ -391,6 +391,94 @@ def test_get_per_issue_metrics_without_hide_envs(self):
expected_issues_with_metrics[1].time_to_close,
)

@patch.dict(
os.environ,
{
"GH_TOKEN": "test_token",
"SEARCH_QUERY": "is:issue is:open repo:user/repo",
"IGNORE_USERS": "alice",
},
)
def test_get_per_issue_metrics_with_ignore_users(self):
"""
Test that the function correctly filters out issues with authors in the IGNORE_USERS variable
"""

# Create mock data
mock_issue1 = MagicMock(
title="Issue 1",
html_url="https://github.com/user/repo/issues/1",
user={"login": "alice"},
state="open",
comments=1,
created_at="2023-01-01T00:00:00Z",
)

mock_comment1 = MagicMock()
mock_comment1.created_at = datetime.fromisoformat("2023-01-02T00:00:00Z")
mock_issue1.issue.comments.return_value = [mock_comment1]
mock_issue1.issue.pull_request_urls = None

mock_issue2 = MagicMock(
title="Issue 2",
html_url="https://github.com/user/repo/issues/2",
user={"login": "bob"},
state="closed",
comments=1,
created_at="2023-01-01T00:00:00Z",
closed_at="2023-01-04T00:00:00Z",
)

mock_comment2 = MagicMock()
mock_comment2.created_at = datetime.fromisoformat("2023-01-03T00:00:00Z")
mock_issue2.issue.comments.return_value = [mock_comment2]
mock_issue2.issue.pull_request_urls = None

issues = [
mock_issue1,
mock_issue2,
]

# Call the function and check the result
with unittest.mock.patch( # type:ignore
"issue_metrics.measure_time_to_first_response",
measure_time_to_first_response,
), unittest.mock.patch( # type:ignore
"issue_metrics.measure_time_to_close", measure_time_to_close
):
(
result_issues_with_metrics,
result_num_issues_open,
result_num_issues_closed,
) = get_per_issue_metrics(
issues,
env_vars=get_env_vars(test=True),
ignore_users=["alice"],
)
expected_issues_with_metrics = [
IssueWithMetrics(
"Issue 2",
"https://github.com/user/repo/issues/2",
"bob",
timedelta(days=2),
timedelta(days=3),
None,
None,
),
]
expected_num_issues_open = 0
expected_num_issues_closed = 1
self.assertEqual(result_num_issues_open, expected_num_issues_open)
self.assertEqual(result_num_issues_closed, expected_num_issues_closed)
self.assertEqual(
result_issues_with_metrics[0].time_to_first_response,
expected_issues_with_metrics[0].time_to_first_response,
)
self.assertEqual(
result_issues_with_metrics[0].time_to_close,
expected_issues_with_metrics[0].time_to_close,
)


class TestDiscussionMetrics(unittest.TestCase):
"""Test suite for the discussion_metrics function."""
Expand Down

0 comments on commit 8cee549

Please sign in to comment.