From f6b480912e63f236356e5a3a85e1162a08e34925 Mon Sep 17 00:00:00 2001 From: Dmitriy Mozgovoy Date: Sat, 7 Jan 2023 02:40:08 +0200 Subject: [PATCH] chore(ci): improved contributors list generator; (#5443) --- .github/workflows/pr.yml | 2 +- bin/contributors.js | 84 +++++++++++++++++++++++++++++--------- package.json | 5 ++- templates/contributors.hbs | 10 +++-- 4 files changed, 75 insertions(+), 26 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 201c3b5..779812c 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -37,7 +37,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TYPE_ARG: ${{ fromJSON('{"auto":"", "patch":"--patch", "minor":"--minor", "major":"--major"}')[github.event.inputs.type] }} BETA_ARG: ${{ github.event.inputs.beta == 'true' && '--preRelease=beta' || '' }} - run: npm run release -- --ci --verbose $TYPE_ARG $BETA_ARG + run: npm run release -- --ci --no-git --verbose $TYPE_ARG $BETA_ARG - name: get-npm-version id: package-version uses: martinbeentjes/npm-get-version-action@main diff --git a/bin/contributors.js b/bin/contributors.js index daaa9c8..7c4f270 100644 --- a/bin/contributors.js +++ b/bin/contributors.js @@ -14,25 +14,65 @@ const cleanTemplate = template => template .replace(/\n\n\n+/g, '\n\n') .replace(/\n\n$/, '\n'); -const getUserInfo = ((userCache) => async (email) => { - if (userCache[email] !== undefined) { - return userCache[email]; - } +const getUserFromCommit = ((commitCache) => async (sha) => { try { - const tag = email.replace(/@users\.noreply\.github\.com/, ''); + if(commitCache[sha] !== undefined) { + return commitCache[sha]; + } - const {data: {items: [user]}} = await axios.get(`https://api.github.com/search/users?q=${tag}`); + const {data} = await axios.get(`https://api.github.com/repos/axios/axios/commits/${sha}`); - return (userCache[email] = user ? { - ...user, - avatar_url_sm: user.avatar_url + '&s=16' - } : null); + return commitCache[sha] = { + ...data.commit.author, + ...data.author, + avatar_url_sm: data.author.avatar_url ? data.author.avatar_url + '&s=16' : '', + }; } catch (err) { - console.warn(err); - return {}; + return commitCache[sha] = null; } })({}); +const getUserInfo = ((userCache) => async (userEntry) => { + const {email, commits} = userEntry; + + if (userCache[email] !== undefined) { + return userCache[email]; + } + + return userCache[email] = { + ...userEntry, + ...await getUserFromCommit(commits[0]) + } +})({}); + +const deduplicate = (authors) => { + const loginsMap = {}; + const combined= {}; + + const assign = (a, b) => { + const {insertions, deletions, points, ...rest} = b; + + Object.assign(a, rest); + + a.insertions += insertions; + a.deletions += insertions; + a.insertions += insertions; + } + + for(const [email, user] of Object.entries(authors)) { + const {login} = user; + let entry; + + if(login && (entry = loginsMap[login])) { + assign(entry, user); + } else { + login && (loginsMap[login] = user); + combined[email] = user; + } + } + + return combined; +} const getReleaseInfo = async (version, useGithub) => { version = 'v' + version.replace(/^v/, ''); @@ -52,15 +92,16 @@ const getReleaseInfo = async (version, useGithub) => { ...release.merges.map(fix => fix.commit) ].filter(Boolean); - for(const {author, email, insertions, deletions} of commits) { - const user = Object.assign({ - email - }, useGithub ? await getUserInfo(email) : null); - + for(const {hash, author, email, insertions, deletions} of commits) { const entry = authors[email] = (authors[email] || { - insertions: 0, deletions: 0, ...user + name: author, + email, + commits: [], + insertions: 0, deletions: 0 }); + entry.commits.push(hash); + entry.displayName = entry.name || author || entry.login; entry.github = entry.login ? `https://github.com/${encodeURIComponent(entry.login)}` : ''; @@ -68,9 +109,14 @@ const getReleaseInfo = async (version, useGithub) => { entry.insertions += insertions; entry.deletions += deletions; entry.points = entry.insertions + entry.deletions; + entry.isBot = entry.type === "Bot" } - release.authors = Object.values(authors).sort((a, b) => b.points - a.points); + for(const [email, author] of Object.entries(authors)) { + authors[email] = await getUserInfo(author); + } + + release.authors = Object.values(deduplicate(authors)).sort((a, b) => b.points - a.points); release.allCommits = commits; } diff --git a/package.json b/package.json index 04ea4b3..a2bb0f3 100644 --- a/package.json +++ b/package.json @@ -161,8 +161,9 @@ "release-it": { "git": { "commitMessage": "chore(release): v${version}", - "push": false, - "commit": false + "push": true, + "commit": true, + "tag": true }, "github": { "release": false diff --git a/templates/contributors.hbs b/templates/contributors.hbs index 796493f..d000445 100644 --- a/templates/contributors.hbs +++ b/templates/contributors.hbs @@ -1,13 +1,15 @@ {{#if authors}} - ### Contributors 🤵 + ### Contributors to this release {{#each authors}} - {{#if github}} - - {{#if avatar_url}}![avatar]({{avatar_url_sm}}){{/if}} [{{displayName}}]({{github}}) ({{insertions}}++ / {{deletions}}--) + {{#unless isBot}} + {{#if login}} + - {{#if avatar_url}}![avatar]({{avatar_url_sm}}){{/if}} [{{displayName}}]({{html_url}}) {{else}} - - {{displayName}} ({{insertions}}++ / {{deletions}}--) + - {{displayName}} {{/if}} + {{/unless}} {{/each}} {{/if}}