diff --git a/source/app/mocks/api/github/rest/repos/listCommits.mjs b/source/app/mocks/api/github/rest/repos/listCommits.mjs index f28ae8c5..e3d524bf 100644 --- a/source/app/mocks/api/github/rest/repos/listCommits.mjs +++ b/source/app/mocks/api/github/rest/repos/listCommits.mjs @@ -15,6 +15,7 @@ return this.commit.author }, commit:{ + message:faker.lorem.sentence(), author:{ name:owner, login:faker.internet.userName(), diff --git a/source/plugins/contributors/README.md b/source/plugins/contributors/README.md index 7717032a..29b71ad7 100644 --- a/source/plugins/contributors/README.md +++ b/source/plugins/contributors/README.md @@ -7,6 +7,9 @@ It's especially useful to acknowledge contributors on release notes.
+
With number of contributions + +
@@ -20,6 +23,8 @@ It's especially useful to acknowledge contributors on release notes. with: # ... other options plugin_contributors: yes - plugin_contributors_base: "" # Base reference (commit, tag, branch, etc.) - plugin_contributors_head: master # Head reference (commit, tag, branch, etc.) + plugin_contributors_base: "" # Base reference (commit, tag, branch, etc.) + plugin_contributors_head: master # Head reference (commit, tag, branch, etc.) + plugin_contributors_ignored: bot # Ignore "bot" user + plugin_contributors_contributions: yes # Display number of contributions for each contributor ``` \ No newline at end of file diff --git a/source/plugins/contributors/index.mjs b/source/plugins/contributors/index.mjs index a14e8411..e076b28e 100644 --- a/source/plugins/contributors/index.mjs +++ b/source/plugins/contributors/index.mjs @@ -7,7 +7,7 @@ return null //Load inputs - let {head, base} = imports.metadata.plugins.contributors.inputs({data, account, q}) + let {head, base, ignored, contributions} = imports.metadata.plugins.contributors.inputs({data, account, q}) const repo = {owner:data.repo.owner.login, repo:data.repo.name} //Retrieve head and base commits @@ -20,7 +20,7 @@ //Get commit activity console.debug(`metrics/compute/${login}/plugins > contributors > querying api for commits between [${ref.base?.abbreviatedOid ?? null}] and [${ref.head?.abbreviatedOid ?? null}]`) const commits = [] - for (let page = 0; ; page++) { + for (let page = 1; ; page++) { console.debug(`metrics/compute/${login}/plugins > contributors > loading page ${page}`) try { const {data:loaded} = await rest.repos.listCommits({...repo, per_page:100, page}) @@ -49,18 +49,26 @@ //Compute contributors and contributions let contributors = {} - for (const {author:{login, avatar_url:avatar}} of commits) { - if (!login) + for (const {author:{login, avatar_url:avatar}, commit:{message = ""}} of commits) { + if ((!login)||(ignored.includes(login))) { + console.debug(`metrics/compute/${login}/plugins > contributors > ignored contributor "${login}"`) continue + } if (!(login in contributors)) - contributors[login] = {avatar:avatar ? await imports.imgb64(avatar) : "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==", contributions:0} - else + contributors[login] = {avatar:avatar ? await imports.imgb64(avatar) : "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==", contributions:1, pr:[]} + else { contributors[login].contributions++ + contributors[login].pr.push(...(message.match(/(?<=[(])#\d+(?=[)])/g) ?? [])) + } } - contributors = Object.fromEntries(Object.entries(contributors).sort((a, b) => b.contributions - a.contributions)) + contributors = Object.fromEntries(Object.entries(contributors).sort(([_an, a], [_bn, b]) => b.contributions - a.contributions)) + + //Filter pull requests + for (const contributor of Object.values(contributors)) + contributor.pr = [...new Set(contributor.pr)] //Results - return {head, base, ref, list:contributors} + return {head, base, ref, list:contributors, contributions} } //Handle errors catch (error) { diff --git a/source/plugins/contributors/metadata.yml b/source/plugins/contributors/metadata.yml index 177b61ea..d33e4f4d 100644 --- a/source/plugins/contributors/metadata.yml +++ b/source/plugins/contributors/metadata.yml @@ -21,4 +21,17 @@ inputs: plugin_contributors_head: description: Head reference type: string - default: master \ No newline at end of file + default: master + + # Ignored contributors (useful to ignore bots users) + plugin_contributors_ignored: + description: Contributors to ignore + type: array + format: comma-separated + default: github-actions[bot] + + # Display total contributions for each contributor + plugin_contributors_contributions: + description: Display contributions + type: boolean + default: no diff --git a/source/plugins/contributors/tests.yml b/source/plugins/contributors/tests.yml index 771015d5..c66b5751 100644 --- a/source/plugins/contributors/tests.yml +++ b/source/plugins/contributors/tests.yml @@ -4,10 +4,12 @@ token: MOCKED_TOKEN plugin_contributors: yes -- name: Contributors plugin (default) +- name: Contributors plugin (complete) uses: lowlighter/metrics@latest with: token: MOCKED_TOKEN plugin_contributors: yes + plugin_contributors_ignored: github-actions[bot] + plugin_contributors_contributions: yes plugin_contributors_head: MOCKED_SHA plugin_contributors_base: MOCKED_SHA diff --git a/source/plugins/habits/index.mjs b/source/plugins/habits/index.mjs index 0df81872..3751e3f7 100644 --- a/source/plugins/habits/index.mjs +++ b/source/plugins/habits/index.mjs @@ -18,7 +18,7 @@ console.debug(`metrics/compute/${login}/plugins > habits > querying api`) const events = [] try { - for (let page = 0; page < pages; page++) { + for (let page = 1; page < pages; page++) { console.debug(`metrics/compute/${login}/plugins > habits > loading page ${page}`) events.push(...(await rest.activity.listEventsForAuthenticatedUser({username:login, per_page:100, page})).data) } diff --git a/source/templates/classic/style.css b/source/templates/classic/style.css index 1b10a9ce..f594cdc6 100644 --- a/source/templates/classic/style.css +++ b/source/templates/classic/style.css @@ -700,6 +700,23 @@ .contributors .label img { margin-left: 0; } + .contributors .contributions { + display: flex; + align-items: center; + font-size: .7rem; + margin-left: 6px; + margin-right: -10px; + background-color: #DDEEFF; + padding: 0 7px; + border-top-right-radius: 32px; + border-bottom-right-radius: 32px; + } + .contributors .contributions svg { + fill: #0366D6; + margin-left: 4px; + width: .8rem; + height: .8rem; + } /* Introduction */ .introduction { diff --git a/source/templates/repository/partials/contributors.ejs b/source/templates/repository/partials/contributors.ejs index 42f0f968..94aabc9b 100644 --- a/source/templates/repository/partials/contributors.ejs +++ b/source/templates/repository/partials/contributors.ejs @@ -17,10 +17,13 @@ <%= plugins.contributors.error.message %> <% } else { %> - <% for (const [login, {avatar}] of Object.entries(plugins.contributors.list)) { %> + <% for (const [login, {avatar, contributions}] of Object.entries(plugins.contributors.list)) { %>
<%= login %> + <% if (plugins.contributors.contributions) { %> +
<%= contributions %>
+ <% } %>
<% } %> <% } %> diff --git a/source/templates/repository/template.mjs b/source/templates/repository/template.mjs index 06eaed28..68641aaf 100644 --- a/source/templates/repository/template.mjs +++ b/source/templates/repository/template.mjs @@ -22,7 +22,7 @@ //Get commit activity console.debug(`metrics/compute/${login}/${repo} > querying api for commits`) const commits = [] - for (let page = 0; page < 100; page++) { + for (let page = 1; page < 100; page++) { console.debug(`metrics/compute/${login}/${repo} > loading page ${page}`) try { const {data} = await rest.repos.listCommits({owner:login, repo, per_page:100, page})