Fix GitHub bot avatar URL (#55297)
## Summary - Fix GitHub avatar URL generation for bot noreply commit authors - Fall back to the GitHub commit author API when the CDN email avatar endpoint cannot resolve bot noreply emails - Add tests covering bot noreply and regular user noreply author emails - Before <img width="305" height="117" alt="image" src="https://github.com/user-attachments/assets/01f79e6c-cae6-4c28-a3e3-3ca506898f4f" /> - After <img width="297" height="105" alt="image" src="https://github.com/user-attachments/assets/3f387b62-e34a-41f5-b377-2afe2e895bf8" /> ## Test Plan - `cargo test -p git_hosting_providers --features gpui/test-support` Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed GitHub avatar lookup for bot noreply commit authors. --------- Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
This commit is contained in:
1 parent
cfb96a48c0
commit
f30074cd1b
1 file changed
+40
-3
@@ -68,8 +68,12 @@ pub struct Github {
|
||||
base_url: Url,
|
||||
}
|
||||
|
||||
fn normalize_author_email(email: &str) -> &str {
|
||||
email.trim_start_matches('<').trim_end_matches('>')
|
||||
}
|
||||
|
||||
fn build_cdn_avatar_url(email: &str) -> Result<Url> {
|
||||
let email = email.trim_start_matches('<').trim_end_matches('>');
|
||||
let email = normalize_author_email(email);
|
||||
Url::parse(&format!(
|
||||
"https://avatars.githubusercontent.com/u/e?email={}&s=128",
|
||||
encode(email)
|
||||
@@ -77,6 +81,15 @@ fn build_cdn_avatar_url(email: &str) -> Result<Url> {
|
||||
.context("failed to construct avatar URL")
|
||||
}
|
||||
|
||||
fn build_cdn_avatar_url_for_author_email(email: &str) -> Result<Option<Url>> {
|
||||
let email = normalize_author_email(email);
|
||||
if email.ends_with("[bot]@users.noreply.github.com") {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
build_cdn_avatar_url(email).map(Some)
|
||||
}
|
||||
|
||||
impl Github {
|
||||
pub fn new(name: impl Into<String>, base_url: Url) -> Self {
|
||||
Self {
|
||||
@@ -267,8 +280,10 @@ impl GitHostingProvider for Github {
|
||||
author_email: Option<SharedString>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
) -> Result<Option<Url>> {
|
||||
if let Some(email) = author_email {
|
||||
return Ok(Some(build_cdn_avatar_url(&email)?));
|
||||
if let Some(email) = author_email
|
||||
&& let Some(avatar_url) = build_cdn_avatar_url_for_author_email(&email)?
|
||||
{
|
||||
return Ok(Some(avatar_url));
|
||||
}
|
||||
|
||||
let commit = commit.to_string();
|
||||
@@ -629,4 +644,26 @@ mod tests {
|
||||
"https://avatars.githubusercontent.com/u/e?email=user%2Btag%40example.com&s=128"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_cdn_avatar_url_for_author_email_skips_bot_noreply_emails() {
|
||||
for email in [
|
||||
"41898282+github-actions[bot]@users.noreply.github.com",
|
||||
"<41898282+github-actions[bot]@users.noreply.github.com>",
|
||||
] {
|
||||
assert_eq!(build_cdn_avatar_url_for_author_email(email).unwrap(), None);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_cdn_avatar_url_for_author_email_uses_user_noreply_emails() {
|
||||
let url = build_cdn_avatar_url_for_author_email("12345+octocat@users.noreply.github.com")
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
url.as_str(),
|
||||
"https://avatars.githubusercontent.com/u/e?email=12345%2Boctocat%40users.noreply.github.com&s=128"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user