Parse Co-authored-by trailers in commit messages#243
Draft
kraftbj wants to merge 4 commits into
Draft
Conversation
Scans PR commit messages for `Co-authored-by: Name <email>` trailers and attempts to resolve each email to a GitHub account via a user search. Resolved co-authors flow through the existing committers path, so they appear in the SVN props line and the Git co-authored-by block with the usual dedupe. Unresolved trailers (private emails, mostly) surface as a new "Co-authors from commit trailers" section in the PR comment so committers can credit them manually. Fixes WordPress#86
The previous implementation only escaped double quotes, so an email containing a backslash could terminate the GraphQL string literal early and inject query syntax. Use JSON.stringify for the whole query value, which correctly handles backslashes, quotes, and control characters per GraphQL/JSON string-literal rules. Flagged by CodeQL as "Incomplete string escaping or encoding".
- Escape GitHub Flavored Markdown specials when interpolating trailer name/email into the "Co-authors from commit trailers" section so attacker-controlled commit messages cannot inject links, images, or @-mentions into a bot-authored PR comment. - Raise getUsersByEmails error log from info to warning so a transient GraphQL failure (which silently demotes all trailers to the unlinked list) is visible in CI logs.
The noreply email format encodes the login directly (and, post-2017, the numeric user ID). Parse it locally and add the contributor straight to the committer list instead of round-tripping through a user-search query. Falls back to getUsersByEmails() for anything else.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
Parses
Co-authored-by:trailers from PR commit messages so co-authors show up in the props output.Fixes #86
Why?
Today the action only credits the direct commit author; any
Co-authored-by:trailers in the commit message are ignored. That silently drops contributors from both the SVN props line and the Git co-authored-by block — especially painful when the PR is committed to SVN, where the full list is the authoritative record.Per desrosj's comment on #86, parsing trailers and including them (SVN in particular) is the sensible first step, with the Git-side nuance handled by the existing squash-merge trailer behavior plus dedupe.
How?
src/utils.js— newparseCoAuthorTrailers(message)helper. Case-insensitive regex scan of the whole message returning{ name, email }pairs. Emails lowercased for dedupe. Also adds a smallescapeMarkdown(text)helper for safely interpolating attacker-controllable trailer text into the bot comment.src/github.js::getContributorData— addsmessageto the GraphQL commit query.src/github.js::getUsersByEmails— new method. Batch-resolves emails to GitHub users via a single GraphQL query with aliasedsearch(type: USER, query: "in:email …")calls. The query value is built withJSON.stringifyso backslashes, quotes, and control chars in trailer emails can't break out of the GraphQL string literal. On API failure the error is logged viacore.warningand every email falls through as unresolved.src/contribution-collector.js— after the normal commits loop, extracts trailers, dedupes against committer emails (so a PR author self-crediting doesn't double-count), and resolves viagetUsersByEmails. Resolved trailer authors flow through the existing committer path (WPORG lookup, standard dedupe, SVN + Git formatting). Unresolved trailers land in a newunlinkedCoAuthorslist on the output.src/github.js::commentProps— renders unresolved trailers in a new "Co-authors from commit trailers" section (shown just after "Unlinked Accounts") so committers can credit them manually. Name and email are passed throughescapeMarkdownso crafted trailers can't inject links, images, or@-mentions into a bot-authored comment. Unresolved entries do not enter the Git co-authored-by block, avoiding double-counting when the trailer is already in the squash-merge commit.dist/index.js— rebuilt viancc.Testing Instructions
…@users.noreply.github.comwhere the GitHub user has no public email) → should appear in the new "Co-authors from commit trailers" section of the props-bot comment.Co-authored-by: [click me](https://evil.test) @octocat <foo@example.com>wherefoo@example.comisn't public) → the unresolved entry in the bot comment should render the bracketed text and@octocatliterally, not as a link or mention.