Repository: github/issue-metrics
Pull request #370 (2024-09-17 09:56:33)

feat: add non-mentioning links option
# Pull Request

Adds a new env var which allows you to specify non-mentioning links to the issues.

Non-mentioning links are possible using this [workaround](https://github.com/orgs/community/discussions/23123)

## Proposed Changes

The links still work as before, but they do not cause a notification in the desitnation repository, which helps reduce "spam" there.

## Readiness Checklist

### Author/Contributor

- [x] If documentation is needed for this change, has that been included in this pull request
- [x] run `make lint` and fix any issues that you have introduced
- [x] run `make test` and ensure you have test coverage for the lines you are introducing
- [x] If publishing new data to the public (scorecards, security scan results, code quality results, live dashboards, etc.), please request review from `@jeffrey-luszcz`

### Reviewer

- [x] Label as either `fix`, `documentation`, `enhancement`, `infrastructure`, `maintenance`, or `breaking`


willcl-ark: Kindly requesting review from @jeffrey-luszcz as instructed :)

Patch:
diff --git a/README.md b/README.md
index f28834f..030ef4d 100644
--- a/README.md
+++ b/README.md
@@ -154,6 +154,7 @@ This action can be configured to authenticate with GitHub App Installation or Pe
 | `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.             |
 | `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
diff --git a/config.py b/config.py
index 5186d44..9056abb 100644
--- a/config.py
+++ b/config.py
@@ -62,6 +62,7 @@ class EnvVars:
         max_comments_eval: str,
         heavily_involved_cutoff: str,
         search_query: str,
+        non_mentioning_links: bool,
     ):
         self.gh_app_id = gh_app_id
         self.gh_app_installation_id = gh_app_installation_id
@@ -81,6 +82,7 @@ class EnvVars:
         self.max_comments_eval = max_comments_eval
         self.heavily_involved_cutoff = heavily_involved_cutoff
         self.search_query = search_query
+        self.non_mentioning_links = non_mentioning_links
 
     def __repr__(self):
         return (
@@ -103,6 +105,7 @@ class EnvVars:
             f"{self.max_comments_eval},"
             f"{self.heavily_involved_cutoff},"
             f"{self.search_query}"
+            f"{self.non_mentioning_links}"
         )
 
 
@@ -195,6 +198,7 @@ def get_env_vars(test: bool = False) -> EnvVars:
     min_mentor_comments = os.getenv("MIN_MENTOR_COMMENTS", "10")
     max_comments_eval = os.getenv("MAX_COMMENTS_EVAL", "20")
     heavily_involved_cutoff = os.getenv("HEAVILY_INVOLVED_CUTOFF", "3")
+    non_mentioning_links = get_bool_env_var("NON_MENTIONING_LINKS", False)
 
     return EnvVars(
         gh_app_id,
@@ -215,4 +219,5 @@ def get_env_vars(test: bool = False) -> EnvVars:
         max_comments_eval,
         heavily_involved_cutoff,
         search_query,
+        non_mentioning_links,
     )
diff --git a/issue_metrics.py b/issue_metrics.py
index 3d62d30..88c827f 100644
--- a/issue_metrics.py
+++ b/issue_metrics.py
@@ -306,6 +306,7 @@ def main():
     token = env_vars.gh_token
     ignore_users = env_vars.ignore_users
     hide_items_closed_count = env_vars.hide_items_closed_count
+    non_mentioning_links = env_vars.non_mentioning_links
 
     gh_app_id = env_vars.gh_app_id
     gh_app_installation_id = env_vars.gh_app_installation_id
@@ -414,6 +415,7 @@ def main():
         labels,
         search_query,
         hide_items_closed_count,
+        non_mentioning_links,
     )
 
     max_char_count = 65535
diff --git a/markdown_writer.py b/markdown_writer.py
index 5e3e300..d2cde39 100644
--- a/markdown_writer.py
+++ b/markdown_writer.py
@@ -85,6 +85,7 @@ def write_to_markdown(
     search_query=None,
     hide_label_metrics=False,
     hide_items_closed_count=False,
+    non_mentioning_links=False,
 ) -> None:
     """Write the issues with metrics to a markdown file.
 
@@ -160,7 +161,13 @@ def write_to_markdown(
             # Replace any whitespace
             issue.title = issue.title.strip()
 
-            file.write(f"| " f"{issue.title} | " f"{issue.html_url} |")
+            if non_mentioning_links:
+                file.write(
+                    f"| {issue.title} | "
+                    f"{issue.html_url.replace('https://github.com', 'https://www.github.com')} |"
+                )
+            else:
+                file.write(f"| {issue.title} | " f"{issue.html_url} |")
             if "Author" in columns:
                 file.write(f" [{issue.author}](https://github.com/{issue.author}) |")
             if "Time to first response" in columns:


Test patch:
diff --git a/test_config.py b/test_config.py
index 6c2abef..e52326b 100644
--- a/test_config.py
+++ b/test_config.py
@@ -126,6 +126,7 @@ class TestGetEnvVars(unittest.TestCase):
             "20",
             "3",
             SEARCH_QUERY,
+            False,
         )
         result = get_env_vars(True)
         self.assertEqual(str(result), str(expected_result))
@@ -171,6 +172,7 @@ class TestGetEnvVars(unittest.TestCase):
             "20",
             "3",
             SEARCH_QUERY,
+            False,
         )
         result = get_env_vars(True)
         self.assertEqual(str(result), str(expected_result))
@@ -250,6 +252,7 @@ class TestGetEnvVars(unittest.TestCase):
             20,
             3,
             SEARCH_QUERY,
+            False,
         )
         result = get_env_vars(True)
         self.assertEqual(str(result), str(expected_result))
@@ -286,6 +289,7 @@ class TestGetEnvVars(unittest.TestCase):
             "20",
             "3",
             SEARCH_QUERY,
+            False,
         )
         result = get_env_vars(True)
         self.assertEqual(str(result), str(expected_result))
diff --git a/test_markdown_writer.py b/test_markdown_writer.py
index 4328f70..0eb5e80 100644
--- a/test_markdown_writer.py
+++ b/test_markdown_writer.py
@@ -254,10 +254,11 @@ class TestWriteToMarkdown(unittest.TestCase):
         "HIDE_TIME_TO_CLOSE": "True",
         "HIDE_TIME_TO_ANSWER": "True",
         "HIDE_LABEL_METRICS": "True",
+        "NON_MENTIONING_LINKS": "True",
     },
 )
 class TestWriteToMarkdownWithEnv(unittest.TestCase):
-    """Test the write_to_markdown function with the HIDE* environment variables set."""
+    """Test the write_to_markdown function with the HIDE* and NON_MENTIONING_LINKS environment variables set."""
 
     def test_writes_markdown_file_with_non_hidden_columns_only(self):
         """
@@ -314,6 +315,7 @@ class TestWriteToMarkdownWithEnv(unittest.TestCase):
             search_query="repo:user/repo is:issue",
             hide_label_metrics=True,
             hide_items_closed_count=True,
+            non_mentioning_links=True,
         )
 
         # Check that the function writes the correct markdown file
@@ -328,8 +330,8 @@ class TestWriteToMarkdownWithEnv(unittest.TestCase):
             "| Total number of items created | 2 |\n\n"
             "| Title | URL | Author |\n"
             "| --- | --- | --- |\n"
-            "| Issue 1 | https://github.com/user/repo/issues/1 | [alice](https://github.com/alice) |\n"
-            "| Issue 2 | https://github.com/user/repo/issues/2 | [bob](https://github.com/bob) |\n\n"
+            "| Issue 1 | https://www.github.com/user/repo/issues/1 | [alice](https://github.com/alice) |\n"
+            "| Issue 2 | https://www.github.com/user/repo/issues/2 | [bob](https://github.com/bob) |\n\n"
             "_This report was generated with the [Issue Metrics Action](https://github.com/github/issue-metrics)_\n"
             "Search query used to find these items: `repo:user/repo is:issue`\n"
         )