diff --git a/README.md b/README.md
index 46b9cb3..63f44ad 100644
--- a/README.md
+++ b/README.md
@@ -93,6 +93,7 @@ This action can be configured to authenticate with GitHub App Installation or Pe
| `END_DATE` | False | Current Date | The date at which you want to stop gathering contributor information. Must be later than the `START_DATE`. ie. Aug 2nd, 2023 would be `2023-08-02` |
| `SPONSOR_INFO` | False | False | If you want to include sponsor information in the output. This will include the sponsor count and the sponsor URL. This will impact action performance. ie. SPONSOR_INFO = "False" or SPONSOR_INFO = "True" |
| `LINK_TO_PROFILE` | False | True | If you want to link usernames to their GitHub profiles in the output. ie. LINK_TO_PROFILE = "True" or LINK_TO_PROFILE = "False" |
+| `SHOW_AVATAR` | False | False | If you want to show profile images in the markdown output. ie. SHOW_AVATAR = "True" or SHOW_AVATAR = "False" |
**Note**: If `start_date` and `end_date` are specified then the action will determine if the contributor is new. A new contributor is one that has contributed in the date range specified but not before the start date.
diff --git a/contributors.py b/contributors.py
index 96cdd86..659e76e 100644
--- a/contributors.py
+++ b/contributors.py
@@ -27,6 +27,7 @@ def main():
end_date,
sponsor_info,
link_to_profile,
+ show_avatar,
) = env.get_env_vars()
# Auth to GitHub.com
@@ -83,6 +84,7 @@ def main():
sponsor_info,
link_to_profile,
ghe,
+ show_avatar,
)
json_writer.write_to_json(
filename="contributors.json",
diff --git a/env.py b/env.py
index b160dc2..bcdceb7 100644
--- a/env.py
+++ b/env.py
@@ -85,6 +85,7 @@ def get_env_vars(
str,
bool,
bool,
+ bool,
]:
"""
Get the environment variables for use in the action.
@@ -105,6 +106,7 @@ def get_env_vars(
end_date (str): The end date to get contributor information to.
sponsor_info (str): Whether to get sponsor information on the contributor
link_to_profile (str): Whether to link username to Github profile in markdown output
+ show_avatar (str): Whether to show contributor avatars in markdown output
"""
if not test:
@@ -145,6 +147,7 @@ def get_env_vars(
sponsor_info = get_bool_env_var("SPONSOR_INFO", False)
link_to_profile = get_bool_env_var("LINK_TO_PROFILE", False)
+ show_avatar = get_bool_env_var("SHOW_AVATAR", False)
# Separate repositories_str into a list based on the comma separator
repositories_list = []
@@ -166,4 +169,5 @@ def get_env_vars(
end_date,
sponsor_info,
link_to_profile,
+ show_avatar,
)
diff --git a/markdown.py b/markdown.py
index ab3d852..60da39f 100644
--- a/markdown.py
+++ b/markdown.py
@@ -4,6 +4,12 @@
import os
+def _is_truthy(value) -> bool:
+ if isinstance(value, str):
+ return value.strip().lower() == "true"
+ return value is True
+
+
def write_to_markdown(
collaborators,
filename,
@@ -14,6 +20,7 @@ def write_to_markdown(
sponsor_info,
link_to_profile,
ghe,
+ show_avatar=False,
):
"""
This function writes a list of collaborators to a markdown file in table format
@@ -40,6 +47,8 @@ def write_to_markdown(
link_to_profile (str): True if the user wants the username linked to
Github profile in the report
ghe (str): The GitHub Enterprise instance URL, if applicable.
+ show_avatar (str): True if the user wants to show profile images in
+ the report
Returns:
None
@@ -55,6 +64,7 @@ def write_to_markdown(
sponsor_info,
link_to_profile,
ghe,
+ show_avatar,
)
# Put together the summary table including # of new contributions,
@@ -196,6 +206,7 @@ def get_contributor_table(
sponsor_info,
link_to_profile,
ghe,
+ show_avatar=False,
):
"""
This function returns a string containing a markdown table of the contributors and the total contribution count.
@@ -209,16 +220,22 @@ def get_contributor_table(
repository (str): The repository for which the contributors are being listed.
sponsor_info (str): True if the user wants the sponsor_url shown in the report
link_to_profile (str): True if the user wants the username linked to Github profile in the report
+ show_avatar (str): True if the user wants to show profile images in the report
Returns:
table (str): A string containing a markdown table of the contributors and the total contribution count.
total_contributions (int): The total number of contributions made by all of the contributors.
"""
+ sponsor_info = _is_truthy(sponsor_info)
+ show_avatar = _is_truthy(show_avatar)
+ link_to_profile = _is_truthy(link_to_profile)
columns = ["Username", "All Time Contribution Count"]
+ if show_avatar:
+ columns.insert(0, "Avatar")
if start_date and end_date:
columns += ["New Contributor"]
- if sponsor_info == "true":
+ if sponsor_info:
columns += ["Sponsor URL"]
if start_date and end_date:
columns += [f"Commits between {start_date} and {end_date}"]
@@ -250,8 +267,16 @@ def get_contributor_table(
commit_urls += f"{url}, "
new_contributor = collaborator.new_contributor
- row = (
- f"| {'' if not link_to_profile else '@'}{username} | {contribution_count} |"
+ row = "| "
+ if show_avatar:
+ avatar_cell = (
+ f'
'
+ if collaborator.avatar_url
+ else ""
+ )
+ row += f"{avatar_cell} | "
+ row += (
+ f"{'' if not link_to_profile else '@'}{username} | {contribution_count} |"
)
if "New Contributor" in columns:
row += f" {new_contributor} |"
diff --git a/test_env.py b/test_env.py
index 638e6e5..0746502 100644
--- a/test_env.py
+++ b/test_env.py
@@ -25,6 +25,7 @@ def setUp(self):
"ORGANIZATION",
"REPOSITORY",
"START_DATE",
+ "SHOW_AVATAR",
]
for key in env_keys:
if key in os.environ:
@@ -44,6 +45,7 @@ def setUp(self):
"END_DATE": "2022-12-31",
"SPONSOR_INFO": "False",
"LINK_TO_PROFILE": "True",
+ "SHOW_AVATAR": "False",
},
clear=True,
)
@@ -65,6 +67,7 @@ def test_get_env_vars(self):
end_date,
sponsor_info,
link_to_profile,
+ show_avatar,
) = env.get_env_vars()
self.assertEqual(organization, "org")
@@ -79,6 +82,7 @@ def test_get_env_vars(self):
self.assertEqual(end_date, "2022-12-31")
self.assertFalse(sponsor_info)
self.assertTrue(link_to_profile)
+ self.assertFalse(show_avatar)
@patch.dict(
os.environ,
@@ -94,6 +98,7 @@ def test_get_env_vars(self):
"END_DATE": "2022-12-31",
"SPONSOR_INFO": "False",
"LINK_TO_PROFILE": "True",
+ "SHOW_AVATAR": "False",
},
clear=True,
)
@@ -122,6 +127,7 @@ def test_get_env_vars_missing_values(self):
"END_DATE": "2022-12-31",
"SPONSOR_INFO": "False",
"LINK_TO_PROFILE": "True",
+ "SHOW_AVATAR": "False",
},
clear=True,
)
@@ -153,6 +159,7 @@ def test_get_env_vars_invalid_start_date(self):
"END_DATE": "",
"SPONSOR_INFO": "False",
"LINK_TO_PROFILE": "True",
+ "SHOW_AVATAR": "False",
},
clear=True,
)
@@ -175,6 +182,7 @@ def test_get_env_vars_no_dates(self):
end_date,
sponsor_info,
link_to_profile,
+ show_avatar,
) = env.get_env_vars()
self.assertEqual(organization, "org")
@@ -189,6 +197,7 @@ def test_get_env_vars_no_dates(self):
self.assertEqual(end_date, "")
self.assertFalse(sponsor_info)
self.assertTrue(link_to_profile)
+ self.assertFalse(show_avatar)
@patch.dict(os.environ, {})
def test_get_env_vars_missing_org_or_repo(self):
diff --git a/test_markdown.py b/test_markdown.py
index 98c5e1a..8d5e24c 100644
--- a/test_markdown.py
+++ b/test_markdown.py
@@ -38,7 +38,7 @@ def test_write_to_markdown(
"commit url2",
"sponsor_url_2",
)
- # Set person2 as a new contributor since this cannot be set on initiatization of the object
+ # Set person2 as a new contributor since this cannot be set on initialization of the object
person2.new_contributor = True
collaborators = [
person1,
@@ -104,7 +104,7 @@ def test_write_to_markdown_with_sponsors(
"commit url2",
"",
)
- # Set person2 as a new contributor since this cannot be set on initiatization of the object
+ # Set person2 as a new contributor since this cannot be set on initialization of the object
person2.new_contributor = True
collaborators = [
person1,
@@ -144,6 +144,75 @@ def test_write_to_markdown_with_sponsors(
)
mock_file().write.assert_called_once_with(expected_content)
+ @patch(
+ "markdown.os.environ.get", return_value=None
+ ) # Mock GITHUB_STEP_SUMMARY to None
+ @patch("builtins.open", new_callable=mock_open)
+ def test_write_to_markdown_with_avatars(
+ self, mock_file, mock_env_get
+ ): # pylint: disable=unused-argument
+ """
+ Test the write_to_markdown function with avatar images turned on.
+ """
+ person1 = contributor_stats.ContributorStats(
+ "user1",
+ False,
+ "https://avatars.example.com/user1.png",
+ 100,
+ "commit url",
+ "sponsor_url_1",
+ )
+ person2 = contributor_stats.ContributorStats(
+ "user2",
+ False,
+ "https://avatars.example.com/user2.png",
+ 200,
+ "commit url2",
+ "sponsor_url_2",
+ )
+ # Set person2 as a new contributor since this cannot be set on initialization of the object
+ person2.new_contributor = True
+ collaborators = [
+ person1,
+ person2,
+ ]
+ ghe = ""
+
+ write_to_markdown(
+ collaborators,
+ "filename",
+ "2023-01-01",
+ "2023-01-02",
+ None,
+ "org/repo",
+ "false",
+ True,
+ ghe,
+ show_avatar=True,
+ )
+
+ mock_file.assert_called_once_with("filename", "w", encoding="utf-8")
+ # With the new implementation, content is written as a single string
+ expected_content = (
+ "# Contributors\n\n"
+ "- Date range for contributor list: 2023-01-01 to 2023-01-02\n"
+ "- Repository: org/repo\n\n"
+ "| Total Contributors | Total Contributions | % New Contributors |\n"
+ "| --- | --- | --- |\n"
+ "| 2 | 300 | 50.0% |\n\n"
+ "| Avatar | Username | All Time Contribution Count | New Contributor | "
+ "Commits between 2023-01-01 and 2023-01-02 |\n"
+ "| --- | --- | --- | --- | --- |\n"
+ '|
| '
+ "@user1 | 100 | False | commit url |\n"
+ '|
| '
+ "@user2 | 200 | True | commit url2 |\n"
+ "\n _this file was generated by the "
+ "[Contributors GitHub Action]"
+ "(https://github.com/github/contributors)_\n"
+ )
+ mock_file().write.assert_called_once_with(expected_content)
+
@patch(
"markdown.os.environ.get", return_value=None
) # Mock GITHUB_STEP_SUMMARY to None
@@ -170,7 +239,7 @@ def test_write_to_markdown_without_link_to_profile(
"commit url2",
"sponsor_url_2",
)
- # Set person2 as a new contributor since this cannot be set on initiatization of the object
+ # Set person2 as a new contributor since this cannot be set on initialization of the object
person2.new_contributor = True
collaborators = [
person1,
@@ -235,7 +304,7 @@ def test_write_to_github_summary(
"commit url2",
"sponsor_url_2",
)
- # Set person2 as a new contributor since this cannot be set on initiatization of the object
+ # Set person2 as a new contributor since this cannot be set on initialization of the object
person2.new_contributor = True
collaborators = [
person1,
@@ -296,7 +365,7 @@ def test_write_to_markdown_with_organization(
"https://github.com/org3/repo3/commits?author=user2",
"sponsor_url_2",
)
- # Set person2 as a new contributor since this cannot be set on initiatization of the object
+ # Set person2 as a new contributor since this cannot be set on initialization of the object
person2.new_contributor = True
collaborators = [
person1,