Skip to content

Commit

Permalink
feat(git changelog): resolve profile picture for GitHub emails, new o…
Browse files Browse the repository at this point in the history
…ption to hide no data texts (#293)

* feat(git changelog): resolve profile picture for GitHub emails
* test(git changelog): `getAvatarFromGithubNoreplyAddress`
* feat(git changelog): hide "no changes" text option
* docs(git changelog): add link to comment for context
* docs(git changelog): `hideChangelogNoChangesText` option
  • Loading branch information
giladgd authored Aug 3, 2024
1 parent 31dd251 commit b6ae060
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ export interface Options {
* Whether to hide the changelog h2 header
*/
hideChangelogHeader?: boolean
/**
* Whether to hide the changelog "No changes" text when there are no changes
*/
hideChangelogNoChangesText?: boolean
/**
* Whether to hide the contributors h2 header
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ export interface Options {
* Whether to hide the changelog h2 header
*/
hideChangelogHeader?: boolean
/**
* Whether to hide the changelog "No changes" text when there are no changes
*/
hideChangelogNoChangesText?: boolean
/**
* Whether to hide the contributors h2 header
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ onMounted(() => {
{{ t('changelog.title') }}
<a class="header-anchor" :href="`#${t('changelog.titleId') || t('changelog.title')}`" :aria-label="`Permalink to '${t('changelog.title')}'`" />
</h2>
<div v-if="!commits.length" :class="options.hideChangelogHeader && 'mt-6'" class="italic" opacity="70">
<div v-if="!commits.length && !options.hideChangelogNoChangesText" :class="options.hideChangelogHeader && 'mt-6'" class="italic" opacity="70">
{{ t('noLogs', { omitEmpty: true }) || t('changelog.noData') }}
</div>
<div
Expand Down
4 changes: 4 additions & 0 deletions packages/vitepress-plugin-git-changelog/src/client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ export interface Options {
* Whether to hide the changelog h2 header
*/
hideChangelogHeader?: boolean
/**
* Whether to hide the changelog "No changes" text when there are no changes
*/
hideChangelogNoChangesText?: boolean
/**
* Whether to hide the contributors h2 header
*/
Expand Down
33 changes: 33 additions & 0 deletions packages/vitepress-plugin-git-changelog/src/vite/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
findMapAuthorByEmail,
findMapAuthorByName,
findMapAuthorLink,
getAvatarFromGithubNoreplyAddress,
getCoAuthors,
mergeRawCommits,
newAvatarForAuthor,
Expand Down Expand Up @@ -535,6 +536,38 @@ describe('newAvatarForAuthor', () => {

expect(avatar).toEqual('https://gravatar.com/avatar/b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514?d=retro')
})

it('should return the commit author avatar for GitHub noreply email without user ID', async () => {
const avatar = await newAvatarForAuthor(undefined, 'user@users.noreply.github.com')

expect(avatar).toEqual('https://avatars.githubusercontent.com/user?size=80')
})

it('should return the commit author avatar for GitHub noreply email with user ID', async () => {
const avatar = await newAvatarForAuthor(undefined, '123456+user@users.noreply.github.com')

expect(avatar).toEqual('https://avatars.githubusercontent.com/u/123456?size=80')
})
})

describe('getAvatarFromGithubNoreplyAddress', () => {
it('should return undefined for email it cannot handle', async () => {
const avatar = await getAvatarFromGithubNoreplyAddress('user@example.com')

expect(avatar).toEqual(undefined)
})

it('should return the commit author avatar for GitHub noreply email without user ID', async () => {
const avatar = await getAvatarFromGithubNoreplyAddress('user@users.noreply.github.com')

expect(avatar).toEqual('https://avatars.githubusercontent.com/user?size=80')
})

it('should return the commit author avatar for GitHub noreply email with user ID', async () => {
const avatar = await getAvatarFromGithubNoreplyAddress('123456+user@users.noreply.github.com')

expect(avatar).toEqual('https://avatars.githubusercontent.com/u/123456?size=80')
})
})

describe('parseCommits', () => {
Expand Down
18 changes: 18 additions & 0 deletions packages/vitepress-plugin-git-changelog/src/vite/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,12 +455,30 @@ export function findMapAuthorI18n(mappedAuthor: Contributor): Record<string, str
return undefined
}

// based on https://github.com/nolebase/integrations/issues/277#issuecomment-2254111802
export function getAvatarFromGithubNoreplyAddress(email: string | undefined, size: number = 80): string | undefined {
if (!email)
return undefined

const match = email.match(/^(?:(?<userId>\d+)\+)?(?<userName>[a-zA-Z\d-]{1,39})@users.noreply.github.com$/)
if (!match || !match.groups)
return undefined

const { userName, userId } = match.groups
return `https://avatars.githubusercontent.com/${userId ? `u/${userId}` : userName}?size=${size}`
}

export async function newAvatarForAuthor(mappedAuthor: Contributor | undefined, email: string): Promise<string> {
if (mappedAuthor) {
if (mappedAuthor.avatar)
return mappedAuthor.avatar
if (mappedAuthor.username)
return `https://github.com/${mappedAuthor.username}.png`
}

const githubProfilePicture = getAvatarFromGithubNoreplyAddress(email)
if (githubProfilePicture != null)
return githubProfilePicture

return `https://gravatar.com/avatar/${await digestStringAsSHA256(email)}?d=retro`
}

0 comments on commit b6ae060

Please sign in to comment.