Skip to content

Commit eb183d4

Browse files
Final updates related to detecting comment body changes and stable sort of signed/missing SHAs per authors/co-authors
Signed-off-by: Lukasz Gryglicki <[email protected]> Assisted by [OpenAI](https://platform.openai.com/) Assisted by [GitHub Copilot](https://github.com/features/copilot)
1 parent c87618b commit eb183d4

File tree

3 files changed

+70
-51
lines changed

3 files changed

+70
-51
lines changed

cla-backend-go/github/github_repository.go

Lines changed: 67 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ Please update your commit message(s) by doing |git commit --amend| and then |git
6262
`
6363

6464
const (
65-
help = "https://help.github.com/en/github/committing-changes-to-your-project/why-are-my-commits-linked-to-the-wrong-user"
6665
unknown = "Unknown"
6766
failureState = "failure"
6867
successState = "success"
@@ -475,7 +474,7 @@ func (u UserCommitSummary) getUserInfo(tagUser bool) string {
475474
}
476475
}
477476

478-
return strings.Replace(sb.String(), "/ $", "", -1)
477+
return strings.TrimSuffix(sb.String(), " / ")
479478
}
480479

481480
// SearchGithubUserByEmail searches for a GitHub user by email using the GitHub search API.
@@ -1599,14 +1598,15 @@ func assembleCLAComment(ctx context.Context, installationID, pullRequestID int,
15991598
return fmt.Sprintf("%s<br >%s", badge, commentBody)
16001599
}
16011600

1601+
// getCommentBody mirrors the Python get_comment_body behavior.
16021602
func getCommentBody(repositoryType, signURL string, signed, missing []*UserCommitSummary, anyMissing bool) string {
16031603
f := logrus.Fields{
16041604
"functionName": "github.github_repository.getCommentBody",
16051605
"repositoryType": repositoryType,
16061606
"signURL": signURL,
16071607
}
16081608
failed := ":x:"
1609-
_success := ":white_check_mark:" // avoid shadowing success var elsewhere
1609+
success := ":white_check_mark:"
16101610

16111611
var committersComment strings.Builder
16121612
text := ""
@@ -1619,39 +1619,76 @@ func getCommentBody(repositoryType, signURL string, signed, missing []*UserCommi
16191619
committersComment.WriteString("<ul>")
16201620
}
16211621

1622-
// --- Signed section (group by author label; list SHAs) ---
1622+
// ---------- Signed section (group by author) ----------
16231623
if numSigned > 0 {
1624-
// Group commits by author label (no tagging for signed)
1625-
committers := getAuthorInfoCommits(signed, false) // map[string][]*UserCommitSummary
1624+
committers := make(map[string][]*UserCommitSummary, numSigned)
1625+
for _, ucs := range signed {
1626+
var authorInfo string
1627+
if ucs != nil && ucs.IsValid() {
1628+
authorInfo = ucs.getUserInfo(false)
1629+
} else {
1630+
authorInfo = unknown
1631+
}
1632+
committers[authorInfo] = append(committers[authorInfo], ucs)
1633+
}
1634+
1635+
// sort keys for stable output
1636+
keys := make([]string, 0, len(committers))
1637+
for k := range committers {
1638+
keys = append(keys, k)
1639+
}
1640+
sort.Strings(keys)
16261641

1627-
for authorInfo, summaries := range committers {
1628-
// Build list of SHAs
1642+
for _, authorInfo := range keys {
1643+
summaries := committers[authorInfo]
16291644
shas := make([]string, 0, len(summaries))
16301645
for _, s := range summaries {
1631-
shas = append(shas, s.SHA)
1646+
if s != nil {
1647+
shas = append(shas, s.SHA)
1648+
}
16321649
}
1633-
log.WithFields(f).Infof("SHAs for signed users: %v", shas)
1650+
log.WithFields(f).Debugf("SHAs for signed users: %v", shas)
16341651
committersComment.WriteString(
1635-
fmt.Sprintf("<li>%s %s (%s)</li>", _success, authorInfo, strings.Join(shas, ", ")),
1652+
fmt.Sprintf("<li>%s %s (%s)</li>", success, authorInfo, strings.Join(shas, ", ")),
16361653
)
16371654
}
16381655
}
16391656

1640-
// --- Missing section (group by author label; list SHAs; guidance) ---
1657+
// ---------- Missing section (group by author) ----------
16411658
if numMissing > 0 {
16421659
supportURL := "https://jira.linuxfoundation.org/servicedesk/customer/portal/4"
16431660
missingIDHelpURL := "https://linuxfoundation.atlassian.net/wiki/spaces/LP/pages/160923756/Missing+ID+on+Commit+but+I+have+an+agreement+on+file"
16441661
githubHelpURL := "https://help.github.com/en/github/committing-changes-to-your-project/why-are-my-commits-linked-to-the-wrong-user"
16451662

1646-
// Tag users for missing (mentions)
1647-
committers := getAuthorInfoCommits(missing, true) // map[string][]*UserCommitSummary
1663+
committers := make(map[string][]*UserCommitSummary, numMissing)
1664+
for _, ucs := range missing {
1665+
var authorInfo string
1666+
if ucs != nil && ucs.IsValid() {
1667+
authorInfo = ucs.getUserInfo(true)
1668+
if strings.TrimSpace(authorInfo) == "" {
1669+
authorInfo = unknown
1670+
}
1671+
} else {
1672+
authorInfo = unknown
1673+
}
1674+
committers[authorInfo] = append(committers[authorInfo], ucs)
1675+
}
16481676

1649-
for authorInfo, summaries := range committers {
1650-
// Unknown author branch
1677+
// sort keys for stable output
1678+
keys := make([]string, 0, len(committers))
1679+
for k := range committers {
1680+
keys = append(keys, k)
1681+
}
1682+
sort.Strings(keys)
1683+
1684+
for _, authorInfo := range keys {
1685+
summaries := committers[authorInfo]
16511686
if authorInfo == unknown {
16521687
shas := make([]string, 0, len(summaries))
16531688
for _, s := range summaries {
1654-
shas = append(shas, s.SHA)
1689+
if s != nil {
1690+
shas = append(shas, s.SHA)
1691+
}
16551692
}
16561693
committersComment.WriteString(fmt.Sprintf(
16571694
"<li> %s The email address for the commit (%s) is not linked to the GitHub account, preventing the EasyCLA check. "+
@@ -1665,39 +1702,41 @@ func getCommentBody(repositoryType, signURL string, signed, missing []*UserCommi
16651702
continue
16661703
}
16671704

1668-
// Check for users who are authorized but missing affiliation
16691705
missingAffiliations := make([]*UserCommitSummary, 0, len(summaries))
16701706
for _, s := range summaries {
1671-
if !s.Affiliated && s.Authorized {
1707+
if s != nil && !s.Affiliated && s.Authorized {
16721708
missingAffiliations = append(missingAffiliations, s)
16731709
}
16741710
}
1675-
16761711
if len(missingAffiliations) > 0 {
1677-
// SHAs only for those missing affiliation
16781712
shas := make([]string, 0, len(missingAffiliations))
16791713
for _, s := range missingAffiliations {
1680-
shas = append(shas, s.SHA)
1714+
if s != nil {
1715+
shas = append(shas, s.SHA)
1716+
}
16811717
}
1682-
log.WithFields(f).Infof("SHAs for users with missing company affiliations: %v", shas)
1718+
log.WithFields(f).Debugf("SHAs for users with missing company affiliations: %v", shas)
16831719
committersComment.WriteString(fmt.Sprintf(
16841720
`<li>%s %s (%s). This user is authorized, but they must confirm their affiliation with their company. `+
16851721
`Start the authorization process <a href='%s' target='_blank'> by clicking here</a>, `+
16861722
`click "Corporate", select the appropriate company from the list, then confirm your affiliation on the page that appears. `+
16871723
`For further assistance with EasyCLA, <a href='%s' target='_blank'>please submit a support request ticket</a>.</li>`,
1688-
failed, authorInfo, strings.Join(shas, ", "), signURL, supportURL,
1724+
failed, authorInfo, strings.Join(shas, ", "),
1725+
signURL, supportURL,
16891726
))
16901727
} else {
1691-
// Not authorized (list all SHAs)
16921728
shas := make([]string, 0, len(summaries))
16931729
for _, s := range summaries {
1694-
shas = append(shas, s.SHA)
1730+
if s != nil {
1731+
shas = append(shas, s.SHA)
1732+
}
16951733
}
16961734
committersComment.WriteString(fmt.Sprintf(
16971735
`<li><a href='%s' target='_blank'>%s</a> - %s. The commit (%s) is not authorized under a signed CLA. `+
16981736
`<a href='%s' target='_blank'>Please click here to be authorized</a>. `+
16991737
`For further assistance with EasyCLA, <a href='%s' target='_blank'>please submit a support request ticket</a>.</li>`,
1700-
signURL, failed, authorInfo, strings.Join(shas, ", "), signURL, supportURL,
1738+
signURL, failed, authorInfo, strings.Join(shas, ", "),
1739+
signURL, supportURL,
17011740
))
17021741
}
17031742
}
@@ -1708,8 +1747,7 @@ func getCommentBody(repositoryType, signURL string, signed, missing []*UserCommi
17081747
committersComment.WriteString("</ul>")
17091748
}
17101749

1711-
// LG: we don't need this as this will change the comment body every time
1712-
// committersComment.WriteString(fmt.Sprintf("<!-- Date Modified: %s -->", time.Now().Format(time.RFC3339)))
1750+
// Python has a Date Modified footer, but that causes churn; intentionally omitted.
17131751

17141752
// Success note if everyone is signed
17151753
if numSigned > 0 && numMissing == 0 {
@@ -1758,25 +1796,6 @@ func getFullSignURL(repositoryType, installationID, githubRepositoryID, pullRequ
17581796
return fmt.Sprintf("%s/v2/repository-provider/%s/sign/%s/%s/%s/#/?version=2", apiBaseURL, repositoryType, installationID, githubRepositoryID, pullRequestID)
17591797
}
17601798

1761-
func getAuthorInfoCommits(userSummary []*UserCommitSummary, tagUser bool) map[string][]*UserCommitSummary {
1762-
f := logrus.Fields{
1763-
"functioName": "github.github_repository.getAuthorInfoCommits",
1764-
}
1765-
result := make(map[string][]*UserCommitSummary)
1766-
for _, author := range userSummary {
1767-
log.WithFields(f).WithFields(f).Debugf("checking user summary for : %s", author.getUserInfo(tagUser))
1768-
if _, ok := result[author.getUserInfo(tagUser)]; !ok {
1769-
1770-
result[author.getUserInfo(tagUser)] = []*UserCommitSummary{
1771-
author,
1772-
}
1773-
} else {
1774-
result[author.getUserInfo(tagUser)] = append(result[author.getUserInfo(tagUser)], author)
1775-
}
1776-
}
1777-
return result
1778-
}
1779-
17801799
// GetRepositoryByExternalID finds github repository by github repository id
17811800
func GetRepositoryByExternalID(ctx context.Context, installationID, id int64) (*github.Repository, error) {
17821801
client, err := NewGithubAppClient(installationID)

cla-backend/cla/models/github_models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2466,7 +2466,7 @@ def has_check_previously_passed_or_failed(pull_request: PullRequest):
24662466
return False, None
24672467

24682468
def normalize_comment(s: str) -> str:
2469-
s = (s or "").replace("\r\n", "\n")
2469+
s = (s or "").replace("\r\n", "\n").replace("\r", "\n")
24702470
lines = [ln.rstrip(" \t") for ln in s.split("\n")]
24712471
while lines and lines[-1] == "":
24722472
lines.pop()

cla-backend/cla/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ def get_comment_body(repository_type, sign_url, signed: List[UserCommitSummary],
11031103
for author_info, user_commit_summaries in committers.items():
11041104
# build a quick list of just the commit hash values
11051105
commit_shas = [user_commit_summary.commit_sha for user_commit_summary in user_commit_summaries]
1106-
cla.log.info(f"{fn} SHAs for signed users: {commit_shas}")
1106+
cla.log.debug(f"{fn} SHAs for signed users: {commit_shas}")
11071107
committers_comment += f'<li>{success} {author_info} ({", ".join(commit_shas)})</li>'
11081108

11091109
if num_missing > 0:
@@ -1153,7 +1153,7 @@ def get_comment_body(repository_type, sign_url, signed: List[UserCommitSummary],
11531153
for user_commit_summary in user_commit_summaries
11541154
if not user_commit_summary.affiliated
11551155
]
1156-
cla.log.info(f"{fn} SHAs for users with missing company affiliations: {commit_shas}")
1156+
cla.log.debug(f"{fn} SHAs for users with missing company affiliations: {commit_shas}")
11571157
committers_comment += (
11581158
f'<li>{failed} {author_info} ({", ".join(commit_shas)}). '
11591159
f"This user is authorized, but they must confirm their affiliation with their company. "

0 commit comments

Comments
 (0)