Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 3, 2025

Pull Request

This pull request introduces support for acknowledging co-authors from commit messages as contributors, controlled by a new ACKNOWLEDGE_COAUTHORS configuration option. It updates the main contributor-gathering logic, environment variable handling, documentation, and tests to support this feature. The changes ensure that users listed as co-authors via Co-authored-by: trailers in commit messages are included in the contributor list, with special handling for converting email addresses into usernames, GitHub noreply and other email formats.

Detailed breakdown of changes:

Feature: Acknowledge Co-authors as Contributors

  • Added a new environment variable ACKNOWLEDGE_COAUTHORS (default True) to .env-example and included documentation in README.md describing its purpose and usage. [1] [2]
  • Updated env.py to read the ACKNOWLEDGE_COAUTHORS environment variable and pass it through the codebase. [1] [2] [3] [4]

Implementation: Co-author Extraction and Integration

  • Implemented get_coauthors_from_message to parse commit messages for Co-authored-by: trailers, extracting GitHub usernames or email addresses as contributor identifiers.
  • Added get_coauthor_contributors to aggregate co-authors from commit messages and create ContributorStats objects for them. Integrated this logic into the main contributor-gathering workflow via get_contributors and get_all_contributors. [1] [2] [3] [4] [5] [6] [7] [8]

Testing: Unit Test Updates

  • Updated and extended unit tests in test_contributors.py to cover the new co-author acknowledgment logic and ensure correct integration with existing contributor gathering. [1] [2] [3] [4]

Readiness Checklist

Author/Contributor

  • If documentation is needed for this change, has that been included in this pull request
  • run make lint and fix any issues that you have introduced
  • run make test and ensure you have test coverage for the lines you are introducing
  • If publishing new data to the public (scorecards, security scan results, code quality results, live dashboards, etc.), please request review from @jeffrey-luszcz

Reviewer

  • Label as either bug, documentation, enhancement, infrastructure, maintenance or breaking
Original prompt

This section details on the original issue you should resolve

<issue_title>Commits might be created by multiple authors. GitHub supports Co-authored-by: for this.</issue_title>
<issue_description>Commits might be created by multiple authors. GitHub supports Co-authored-by: for this.

The action should also report users with Co-authored-by.


Sometimes, one can get the user information by crawling the commits of the PR. I did that in https://github.com/koppor/github-contributors-list. Would be nice if this action supported this as well.

Originally posted by @koppor in #371</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits December 3, 2025 23:01
Co-authored-by: zkoppert <6935431+zkoppert@users.noreply.github.com>
Co-authored-by: zkoppert <6935431+zkoppert@users.noreply.github.com>
Copilot AI changed the title [WIP] Add support for commits by multiple authors feat: add support for Co-authored-by commit trailers Dec 3, 2025
Copilot AI requested a review from zkoppert December 3, 2025 23:05
@zkoppert zkoppert added enhancement New feature or request and removed feature labels Dec 8, 2025
@zkoppert
Copy link
Member

zkoppert commented Dec 8, 2025

@copilot instead of having ACKNOWLEDGE_COAUTHORS default to False, lets change it to defaulting to true. I think that users will want that to work out of the box. Make sure to update that in the code and documentation as well.

Co-authored-by: zkoppert <6935431+zkoppert@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 8, 2025

@copilot instead of having ACKNOWLEDGE_COAUTHORS default to False, lets change it to defaulting to true. I think that users will want that to work out of the box. Make sure to update that in the code ...

Changed default to True in commit 9798816. Updated:

  • env.py: Default parameter changed to True
  • README.md: Default value in table changed to True
  • .env-example: Example value changed to "True"
  • test_env.py: Test assertions updated to expect True

@zkoppert
Copy link
Member

@copilot instead of only allowing specific email domains for coauthors, please change the code and documentation to allow any email domain to be recognized as a coauthor. For example: right now john@example.com is not counted as a coauthor but id like that functionality changed so it is included.

Co-authored-by: zkoppert <6935431+zkoppert@users.noreply.github.com>
Co-authored-by: zkoppert <6935431+zkoppert@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 13, 2025

@copilot instead of only allowing specific email domains for coauthors, please change the code and documentation to allow any email domain to be recognized as a coauthor. For example: right now john@e...

Changed in commit 211543e. Now any email domain is recognized as a co-author:

  • GitHub noreply emails (e.g., username@users.noreply.github.com) extract the username
  • Other emails (e.g., john@example.com) use the full email address as the identifier
  • Updated tests and documentation to reflect this change

@zkoppert
Copy link
Member

Testing locally today

@zkoppert
Copy link
Member

Notes from testing:

  • Copilot starts to show up as a contributor but the link to commit history shows up blank because none of the commits are authored by copilot only coauthored.
  • Coauthors show up as email addresses which may present as a duplicate of an existing user in the table. for example if I had 5 commits authored and 3 coauthored commits, then it would show 2 rows in the table, one for each type of authorship. Not ideal.
  • Since coauthor identities are considered separate from author identities, numbers reflecting the number of new contributors or total contributors are inaccurate.

@zkoppert
Copy link
Member

@copilot Can you figure out how to make sure that the email specified as the co-author is correlated with its github username and added to the stats in the table for that user?

Copy link
Contributor Author

Copilot AI commented Dec 30, 2025

@copilot Can you figure out how to make sure that the email specified as the co-author is correlated with its github username and added to the stats in the table for that user?

Implemented in commit ee109e5. The solution:

  1. Email to username mapping: Builds a mapping from email addresses to GitHub usernames by scanning commit author data
  2. Smart correlation: When processing co-authors, attempts to match their email to a known GitHub username from the mapping
  3. Merge instead of duplicate: If a co-author matches an existing contributor, their co-authored commits are added to that contributor's count instead of creating a separate entry
  4. Fallback behavior: If an email can't be matched to a username, it's used as-is (mainly for external contributors)

This addresses all three issues from testing:

  • Co-authors with matching GitHub accounts are properly merged with their regular contributions
  • No duplicate rows in the table for the same person
  • Accurate contributor counts since co-author and author contributions are combined

Copilot AI changed the title feat: add support for Co-authored-by commit trailers feat: add support for Co-authored-by commit trailers with username correlation Dec 30, 2025
- Add support for extracting usernames from @github.com email addresses
- Integrate GitHub Search Users API to resolve arbitrary emails to usernames
- Add fallback behavior when API calls fail or return no results
- Thread github_connection parameter through co-author parsing functions
- Remove unused existing_usernames parameter from get_coauthor_contributors
- Update all function signatures and test cases with new parameters
- Improve co-author identification from noreply, GitHub, and external emails

This significantly improves co-author recognition by automatically resolving
multiple email formats to GitHub usernames, providing more accurate contributor
attribution and better coverage of collaborative contributions.

Signed-off-by: Zack Koppert <zkoppert@github.com>
@zkoppert zkoppert force-pushed the copilot/support-co-authored-by branch from ee109e5 to 1fabe84 Compare December 31, 2025 17:56
@zkoppert zkoppert marked this pull request as ready for review December 31, 2025 18:28
@zkoppert zkoppert requested a review from a team as a code owner December 31, 2025 18:28
Copilot AI review requested due to automatic review settings December 31, 2025 18:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds support for acknowledging co-authors from commit messages as contributors via a new ACKNOWLEDGE_COAUTHORS configuration option (default: True). The implementation parses Co-authored-by: trailers from commit messages and includes those users in the contributor list, with intelligent handling for GitHub noreply emails, @github.com emails, and a fallback to the GitHub Search Users API for other email addresses.

Key Changes

  • Added ACKNOWLEDGE_COAUTHORS environment variable with default value of True
  • Implemented get_coauthors_from_message() to parse co-author trailers and extract usernames from various email formats
  • Added get_coauthor_contributors() to aggregate co-authors across commits and create contributor stats
  • Updated all relevant functions to pass the new configuration option through the call chain

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
.env-example Added ACKNOWLEDGE_COAUTHORS configuration option with default value
env.py Added environment variable reading for ACKNOWLEDGE_COAUTHORS with default True and updated return tuple
contributors.py Implemented core co-author extraction and integration logic including regex parsing, email-to-username conversion, and GitHub API lookup fallback
test_env.py Updated tests to handle the new acknowledge_coauthors parameter in return tuples
test_contributors.py Added comprehensive test suite for co-author functions covering various email formats, edge cases, and integration scenarios
README.md Added documentation for the new ACKNOWLEDGE_COAUTHORS option and co-author behavior including performance implications

all_repo_contributors = repo.contributors()
contributors = []
# Track usernames already added as contributors
contributor_usernames = set()
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contributor_usernames set is created and populated at line 280 but never actually used. If the intention was to prevent duplicate contributors when a user is both a regular contributor and a co-author in the same repository, the set should be used to filter co-authors. Otherwise, this variable should be removed as it serves no purpose.

Copilot uses AI. Check for mistakes.
ghe,
github_connection,
)
contributors.extend(coauthor_contributors)
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When acknowledge_coauthors is True and a user is both a regular contributor and a co-author on some commits in the same repository, they will appear twice in the results list. While the merge_contributors function will later merge these duplicates, this creates unnecessary processing. Consider checking if a username already exists in contributor_usernames before adding co-authors to avoid creating duplicates within a single repository.

Suggested change
contributors.extend(coauthor_contributors)
# Avoid adding duplicate contributors for the same username within this repository
filtered_coauthors = []
for coauthor in coauthor_contributors:
username = getattr(coauthor, "username", None) or getattr(
coauthor, "login", None
)
if username and username not in contributor_usernames:
filtered_coauthors.append(coauthor)
contributor_usernames.add(username)
contributors.extend(filtered_coauthors)

Copilot uses AI. Check for mistakes.
Comment on lines +200 to +213
# For other emails, try to find GitHub username using Search Users API
if github_connection:
try:
# Search for users by email
search_result = github_connection.search_users(f"email:{email}")
if search_result.totalCount > 0:
# Use the first matching user's login
identifiers.append(search_result[0].login)
else:
# If no user found, fall back to email address
identifiers.append(email)
except Exception:
# If API call fails, fall back to email address
identifiers.append(email)
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GitHub Users Search API call at line 204 may experience rate limiting when processing repositories with many co-authors using non-GitHub email addresses. Each unique email requires an API call, which could significantly impact performance and potentially exhaust API rate limits. Consider adding rate limit handling or caching of email-to-username mappings to mitigate this issue.

Copilot uses AI. Check for mistakes.
Comment on lines +195 to +198
elif email.endswith("@github.com"):
# For @github.com emails, extract the username (part before @)
username = email.split("@")[0]
identifiers.append(username)
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test coverage is missing for the @github.com email handling path. Add a test case that verifies co-authors with @github.com email addresses are correctly parsed to extract the username before the @ symbol.

Copilot uses AI. Check for mistakes.
Comment on lines +200 to +213
# For other emails, try to find GitHub username using Search Users API
if github_connection:
try:
# Search for users by email
search_result = github_connection.search_users(f"email:{email}")
if search_result.totalCount > 0:
# Use the first matching user's login
identifiers.append(search_result[0].login)
else:
# If no user found, fall back to email address
identifiers.append(email)
except Exception:
# If API call fails, fall back to email address
identifiers.append(email)
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test coverage is missing for the GitHub Search Users API fallback path (lines 200-213). Add test cases that verify: 1) successful username lookup via the search API when a matching user is found, 2) fallback to email address when no user is found (totalCount = 0), and 3) fallback to email address when the API call raises an exception.

Copilot uses AI. Check for mistakes.
Comment on lines +96 to +102
| `ACKNOWLEDGE_COAUTHORS` | False | True | If you want to include co-authors from commit messages as contributors. Co-authors are identified via the `Co-authored-by:` trailer in commit messages. The action will extract GitHub usernames from GitHub noreply emails (e.g., `username@users.noreply.github.com`) or use the full email address for other email domains. This will impact action performance as it requires scanning all commits. ie. ACKNOWLEDGE_COAUTHORS = "True" or ACKNOWLEDGE_COAUTHORS = "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.

**Performance Note:** Using start and end dates will reduce speed of the action by approximately 63X. ie without dates if the action takes 1.7 seconds, it will take 1 minute and 47 seconds.

**Co-authors Note:** When `ACKNOWLEDGE_COAUTHORS` is enabled, the action will scan commit messages for `Co-authored-by:` trailers and include those users as contributors. For GitHub noreply email addresses (e.g., `username@users.noreply.github.com`), the username will be extracted. For other email addresses (e.g., `john@example.com`), the full email address will be used as the contributor identifier. See [GitHub's documentation on creating commits with multiple authors](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors).
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation is incomplete. It mentions that GitHub noreply emails extract the username and other emails use the full email address, but it doesn't document that @github.com email addresses also extract the username (part before @), or that the action attempts to use the GitHub Search Users API to find usernames for other email addresses before falling back to the email address.

Suggested change
| `ACKNOWLEDGE_COAUTHORS` | False | True | If you want to include co-authors from commit messages as contributors. Co-authors are identified via the `Co-authored-by:` trailer in commit messages. The action will extract GitHub usernames from GitHub noreply emails (e.g., `username@users.noreply.github.com`) or use the full email address for other email domains. This will impact action performance as it requires scanning all commits. ie. ACKNOWLEDGE_COAUTHORS = "True" or ACKNOWLEDGE_COAUTHORS = "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.
**Performance Note:** Using start and end dates will reduce speed of the action by approximately 63X. ie without dates if the action takes 1.7 seconds, it will take 1 minute and 47 seconds.
**Co-authors Note:** When `ACKNOWLEDGE_COAUTHORS` is enabled, the action will scan commit messages for `Co-authored-by:` trailers and include those users as contributors. For GitHub noreply email addresses (e.g., `username@users.noreply.github.com`), the username will be extracted. For other email addresses (e.g., `john@example.com`), the full email address will be used as the contributor identifier. See [GitHub's documentation on creating commits with multiple authors](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors).
| `ACKNOWLEDGE_COAUTHORS` | False | True | If you want to include co-authors from commit messages as contributors. Co-authors are identified via the `Co-authored-by:` trailer in commit messages. The action will extract GitHub usernames from GitHub noreply emails (e.g., `username@users.noreply.github.com`) and from `@github.com` email addresses (using the part before `@`), and for other email domains it will first attempt to resolve the email to a GitHub username via the GitHub Search Users API before falling back to using the full email address. This will impact action performance as it requires scanning all commits. ie. ACKNOWLEDGE_COAUTHORS = "True" or ACKNOWLEDGE_COAUTHORS = "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.
**Performance Note:** Using start and end dates will reduce speed of the action by approximately 63X. ie without dates if the action takes 1.7 seconds, it will take 1 minute and 47 seconds.
**Co-authors Note:** When `ACKNOWLEDGE_COAUTHORS` is enabled, the action will scan commit messages for `Co-authored-by:` trailers and include those users as contributors. For GitHub noreply email addresses (e.g., `username@users.noreply.github.com`), the username will be extracted. For `@github.com` email addresses (e.g., `username@github.com`), the part before `@` will be treated as the GitHub username. For other email addresses (e.g., `john@example.com`), the action will first attempt to resolve the email to a GitHub username using the GitHub Search Users API and, if no matching user is found, will fall back to using the full email address as the contributor identifier. See [GitHub's documentation on creating commits with multiple authors](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors).

Copilot uses AI. Check for mistakes.

# Extract co-authors from commit message
coauthors = get_coauthors_from_message(commit_message, github_connection)
for username in coauthors:
Copy link

Copilot AI Dec 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bot accounts listed as co-authors via Co-authored-by: trailers will be included in the contributor list, while bot accounts that are regular contributors are filtered out (line 250). Consider applying the same bot filtering logic to co-authors for consistency by checking if "[bot]" is in the username before adding them to coauthor_counts.

Suggested change
for username in coauthors:
for username in coauthors:
# Skip bot accounts for consistency with regular contributor filtering
if "[bot]" in username.lower():
continue

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request feature release

Projects

None yet

2 participants