diff --git a/.env-example b/.env-example index f50b62c..c905ee3 100644 --- a/.env-example +++ b/.env-example @@ -4,6 +4,7 @@ GH_APP_PRIVATE_KEY="" GH_ENTERPRISE_URL = "" GH_TOKEN = "" HIDE_AUTHOR = "false" +HIDE_ITEMS_CLOSED_COUNT="false" HIDE_LABEL_METRICS = "false" HIDE_TIME_TO_ANSWER = "false" HIDE_TIME_TO_CLOSE = "false" diff --git a/README.md b/README.md index 456a781..241fc77 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,7 @@ This action can be configured to authenticate with GitHub App Installation or Pe |-------------------------------|----------|---------|-------------| | `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. | diff --git a/config.py b/config.py index d6c2c75..5186d44 100644 --- a/config.py +++ b/config.py @@ -28,6 +28,7 @@ class EnvVars: gh_token (str | None): GitHub personal access token (PAT) for API authentication ghe (str): The GitHub Enterprise URL to use for authentication hide_author (bool): If true, the author's information is hidden in the output + hide_items_closed_count (bool): If true, the number of items closed metric is hidden in the output hide_label_metrics (bool): If true, the label metrics are hidden in the output hide_time_to_answer (bool): If true, the time to answer discussions is hidden in the output hide_time_to_close (bool): If true, the time to close metric is hidden in the output @@ -49,6 +50,7 @@ def __init__( gh_token: str | None, ghe: str | None, hide_author: bool, + hide_items_closed_count: bool, hide_label_metrics: bool, hide_time_to_answer: bool, hide_time_to_close: bool, @@ -69,6 +71,7 @@ def __init__( self.ignore_users = ignore_user self.labels_to_measure = labels_to_measure self.hide_author = hide_author + self.hide_items_closed_count = hide_items_closed_count self.hide_label_metrics = hide_label_metrics self.hide_time_to_answer = hide_time_to_answer self.hide_time_to_close = hide_time_to_close @@ -88,6 +91,7 @@ def __repr__(self): f"{self.gh_token}," f"{self.ghe}," f"{self.hide_author}," + f"{self.hide_items_closed_count})," f"{self.hide_label_metrics}," f"{self.hide_time_to_answer}," f"{self.hide_time_to_close}," @@ -98,7 +102,7 @@ def __repr__(self): f"{self.min_mentor_comments}," f"{self.max_comments_eval}," f"{self.heavily_involved_cutoff}," - f"{self.search_query})" + f"{self.search_query}" ) @@ -182,6 +186,7 @@ def get_env_vars(test: bool = False) -> EnvVars: # Hidden columns hide_author = get_bool_env_var("HIDE_AUTHOR", False) + hide_items_closed_count = get_bool_env_var("HIDE_ITEMS_CLOSED_COUNT", False) hide_label_metrics = get_bool_env_var("HIDE_LABEL_METRICS", False) hide_time_to_answer = get_bool_env_var("HIDE_TIME_TO_ANSWER", False) hide_time_to_close = get_bool_env_var("HIDE_TIME_TO_CLOSE", False) @@ -198,6 +203,7 @@ def get_env_vars(test: bool = False) -> EnvVars: gh_token, ghe, hide_author, + hide_items_closed_count, hide_label_metrics, hide_time_to_answer, hide_time_to_close, diff --git a/issue_metrics.py b/issue_metrics.py index dfe57f2..3d62d30 100644 --- a/issue_metrics.py +++ b/issue_metrics.py @@ -305,6 +305,7 @@ def main(): search_query = env_vars.search_query token = env_vars.gh_token ignore_users = env_vars.ignore_users + hide_items_closed_count = env_vars.hide_items_closed_count gh_app_id = env_vars.gh_app_id gh_app_installation_id = env_vars.gh_app_installation_id @@ -412,6 +413,7 @@ def main(): num_mentor_count, labels, search_query, + hide_items_closed_count, ) max_char_count = 65535 diff --git a/markdown_writer.py b/markdown_writer.py index 0b587ae..5e3e300 100644 --- a/markdown_writer.py +++ b/markdown_writer.py @@ -84,6 +84,7 @@ def write_to_markdown( labels=None, search_query=None, hide_label_metrics=False, + hide_items_closed_count=False, ) -> None: """Write the issues with metrics to a markdown file. @@ -102,6 +103,7 @@ def write_to_markdown( labels (List[str]): A list of the labels that are used in the issues. search_query (str): The search query used to find the issues. hide_label_metrics (bool): Represents whether the user has chosen to hide label metrics in the output + hide_items_closed_count (bool): Represents whether the user has chosen to hide the number of items closed Returns: None. @@ -135,6 +137,7 @@ def write_to_markdown( columns, file, hide_label_metrics, + hide_items_closed_count, ) # Write second table with individual issue/pr/discussion metrics @@ -193,6 +196,7 @@ def write_overall_metrics_tables( columns, file, hide_label_metrics, + hide_items_closed_count=False, ): """Write the overall metrics tables to the markdown file.""" if ( @@ -250,6 +254,7 @@ def write_overall_metrics_tables( file.write("| Metric | Count |\n") file.write("| --- | ---: |\n") file.write(f"| Number of items that remain open | {num_issues_opened} |\n") - file.write(f"| Number of items closed | {num_issues_closed} |\n") + if not hide_items_closed_count: + file.write(f"| Number of items closed | {num_issues_closed} |\n") file.write(f"| Number of most active mentors | {num_mentor_count} |\n") file.write(f"| Total number of items created | {len(issues_with_metrics)} |\n\n") diff --git a/test_config.py b/test_config.py index d2f1bd1..6c2abef 100644 --- a/test_config.py +++ b/test_config.py @@ -72,6 +72,7 @@ def setUp(self): "GH_TOKEN", "GHE", "HIDE_AUTHOR", + "HIDE_ITEMS_CLOSED_COUNT", "HIDE_LABEL_METRICS", "HIDE_TIME_TO_ANSWER", "HIDE_TIME_TO_CLOSE", @@ -93,6 +94,7 @@ def setUp(self): "GH_TOKEN": "", "GH_ENTERPRISE_URL": "", "HIDE_AUTHOR": "", + "HIDE_ITEMS_CLOSED_COUNT": "false", "HIDE_LABEL_METRICS": "", "HIDE_TIME_TO_ANSWER": "", "HIDE_TIME_TO_CLOSE": "", @@ -116,6 +118,7 @@ def test_get_env_vars_with_github_app(self): False, False, False, + False, [], [], False, @@ -136,6 +139,7 @@ def test_get_env_vars_with_github_app(self): "GH_ENTERPRISE_URL": "", "GH_TOKEN": TOKEN, "HIDE_AUTHOR": "", + "HIDE_ITEMS_CLOSED_COUNT": "false", "HIDE_LABEL_METRICS": "", "HIDE_TIME_TO_ANSWER": "", "HIDE_TIME_TO_CLOSE": "", @@ -159,6 +163,7 @@ def test_get_env_vars_with_token(self): False, False, False, + False, [], [], False, @@ -170,6 +175,41 @@ def test_get_env_vars_with_token(self): result = get_env_vars(True) self.assertEqual(str(result), str(expected_result)) + @patch.dict( + os.environ, + { + "GH_APP_ID": "", + "GH_APP_INSTALLATION_ID": "", + "GH_APP_PRIVATE_KEY": "", + "GH_TOKEN": "", + "SEARCH_QUERY": SEARCH_QUERY, + "HIDE_ITEMS_CLOSED_COUNT": "false", + }, + clear=True, + ) + def test_get_env_vars_missing_token(self): + """Test that an error is raised if the TOKEN environment variables is not set""" + with self.assertRaises(ValueError): + get_env_vars(True) + + @patch.dict( + os.environ, + { + "GH_APP_ID": "", + "GH_APP_INSTALLATION_ID": "", + "GH_APP_PRIVATE_KEY": "", + "GH_TOKEN": TOKEN, + "SEARCH_QUERY": "", + "HIDE_ITEMS_CLOSED_COUNT": "false", + }, + clear=True, + ) + def test_get_env_vars_missing_query(self): + """Test that an error is raised if the SEARCH_QUERY environment variable is not set.""" + + with self.assertRaises(ValueError): + get_env_vars(True) + @patch.dict( os.environ, { @@ -179,6 +219,7 @@ def test_get_env_vars_with_token(self): "GH_TOKEN": TOKEN, "GH_ENTERPRISE_URL": "", "HIDE_AUTHOR": "true", + "HIDE_ITEMS_CLOSED_COUNT": "true", "HIDE_LABEL_METRICS": "true", "HIDE_TIME_TO_ANSWER": "true", "HIDE_TIME_TO_CLOSE": "true", @@ -201,6 +242,7 @@ def test_get_env_vars_optional_values(self): True, True, True, + True, [], ["waiting-for-review", "waiting-for-manager"], False, @@ -218,32 +260,35 @@ def test_get_env_vars_optional_values(self): "GH_APP_ID": "", "GH_APP_INSTALLATION_ID": "", "GH_APP_PRIVATE_KEY": "", - "GH_TOKEN": "", + "GH_TOKEN": "TOKEN", "SEARCH_QUERY": SEARCH_QUERY, }, clear=True, ) - def test_get_env_vars_missing_token(self): - """Test that an error is raised if the TOKEN environment variables is not set""" - with self.assertRaises(ValueError): - get_env_vars(True) - - @patch.dict( - os.environ, - { - "GH_APP_ID": "", - "GH_APP_INSTALLATION_ID": "", - "GH_APP_PRIVATE_KEY": "", - "GH_TOKEN": TOKEN, - "SEARCH_QUERY": "", - }, - clear=True, - ) - def test_get_env_vars_missing_query(self): - """Test that an error is raised if the SEARCH_QUERY environment variable is not set.""" - - with self.assertRaises(ValueError): - get_env_vars(True) + def test_get_env_vars_optionals_are_defaulted(self): + """Test that optional values are set to their default values if not provided""" + expected_result = EnvVars( + None, + None, + b"", + "TOKEN", + "", + False, + False, + False, + False, + False, + False, + [], + [], + False, + "10", + "20", + "3", + SEARCH_QUERY, + ) + result = get_env_vars(True) + self.assertEqual(str(result), str(expected_result)) if __name__ == "__main__": diff --git a/test_markdown_writer.py b/test_markdown_writer.py index 3ebb692..4328f70 100644 --- a/test_markdown_writer.py +++ b/test_markdown_writer.py @@ -313,6 +313,7 @@ def test_writes_markdown_file_with_non_hidden_columns_only(self): labels=["label1"], search_query="repo:user/repo is:issue", hide_label_metrics=True, + hide_items_closed_count=True, ) # Check that the function writes the correct markdown file @@ -323,7 +324,6 @@ def test_writes_markdown_file_with_non_hidden_columns_only(self): "| Metric | Count |\n" "| --- | ---: |\n" "| Number of items that remain open | 2 |\n" - "| Number of items closed | 2 |\n" "| Number of most active mentors | 5 |\n" "| Total number of items created | 2 |\n\n" "| Title | URL | Author |\n"