Awesome
Pull Request Stats
Github action to print relevant stats about Pull Request reviewers.
The objective of this action is to:
- Reduce the time taken to review the pull requests.
- Encourage quality on reviews.
- Help to decide which people to assign as reviewers.
Running this action will add a section at the bottom of your pull requests description:
Each reviewer has a link pointing to their historical behavior of each reviewer:
Or send the data to your favorite tools by using the integrations available:
<a href="/docs/slack.md"><img src="/assets/slack-logo.jpg" width="64"></a><br/>Slack | <a href="/docs/teams.md"><img src="/assets/teams-logo.jpg" width="64"></a><br/>MS Teams | <a href="/docs/webhook.md"><img src="/assets/webhook-logo.jpg" width="64"></a><br/>Webhooks |
---|
Privacy
- No repository data is collected, stored, or distributed by this GitHub action. This action is state-less.
- Charts data is sent over the URL and never stored or transmitted anywhere else.
- Minimal data is sent to Mixpanel in order to improve this action. However, you can opt-out using the
telemetry
option.
Usage
Just add this action to one of your workflow files:
- name: Run pull request stats
uses: flowwer-dev/pull-request-stats@main
If you are getting an empty table or an error, check the troubleshooting section.
Action inputs
The possible inputs for this action are:
Parameter | Description | Default |
---|---|---|
token | A Personal Access Token with repo permissions. Required to calculate stats for an organization or multiple repositories. | GITHUB_TOKEN |
repositories | A comma-separated list of GitHub repositories to calculate the stats, e.g. username/repo1,username/repo2 . If no repositories are specified, the action defaults to the repository where the workflow is running. When specifying other repo(s), it is mandatory to pass a Personal Access Token in the token parameter. | Current repository |
organization | If you prefer, you may specify your organization's name to calculate the stats across all of its repositories. When specifying an organization, it is mandatory to pass a Personal Access Token in the token parameter. | null |
period | The period used to calculate the stats, expressed in days. | 30 |
limit | The maximum number of rows to display in the table. A value of 0 means unlimited. | 0 |
stats | A comma-separated list of stats to calculate and display. Possible values: totalReviews , timeToReview , totalComments , commentsPerReview , openedPullRequests . For details on each stats check the Stats section. | totalReviews,timeToReview,totalComments |
charts | Whether to add a chart to the start. Possible values: true or false . | false |
disableLinks | If true , removes the links to the detailed charts. Possible values: true or false . | false |
sortBy | The column used to sort the data. Possible values: totalReviews , timeToReview , totalComments , commentsPerReview , openedPullRequests . | totalReviews |
publishAs | Where to publish the results. Possible values: COMMENT , DESCRIPTION , or NONE . | COMMENT |
exclude | A comma-separated list of usernames (case-insensitive) to be excluded from the results (e.g. username1,username2 ), or a regular expression enclosed between slashes (e.g. /^bot/i will exclude all usernames that begin with "bot"). | null |
telemetry | Indicates if the action is allowed to send monitoring data to the developer. This data is minimal and helps improve this action. This option is a premium feature reserved for sponsors. | true |
slackWebhook | A Slack webhook URL to post resulting stats. This option is a premium feature reserved for sponsors. See full documentation here. | null |
slackChannel | The Slack channel where stats will be posted. Include the # character (e.g. #mychannel ). Required when a slackWebhook is configured. | null |
teamsWebhook | A Microsoft Teams webhook URL to post resulting stats. This option is a premium feature reserved for sponsors. See full documentation here. | null |
webhook | A webhook URL to send the resulting stats as JSON (integrate with Zapier, IFTTT...). See full documentation here. | null |
Action outputs
This action outputs the following variables:
Variable | Description |
---|---|
resultsMd | The resulting stats stored as a step output variable in Markdown format. |
resultsJson | The resulting stats stored as a step output variable in JSON format. |
Examples
Minimal config
Add this to the file .github/workflows/stats.yml
in your repo:
name: Pull Request Stats
on:
pull_request:
types: [opened]
jobs:
stats:
runs-on: ubuntu-latest
steps:
- name: Run pull request stats
uses: flowwer-dev/pull-request-stats@main
This config will:
- Calculate the reviewer stats for the current repo in the lasts 30 days.
- Add links to the historical data.
- Sort results by the "total reviews" column by default.
and print a table like this:
User | Total reviews | Median time to review | Total comments | |
---|---|---|---|---|
<a href="https://github.com/jartmez"><img src="https://avatars.githubusercontent.com/u/8755542?u=5f845c5d64ccdef5da89024edd22fcbb306bad82&v=4" width="20"></a> | jartmez | 37 | 22m | 13 |
<a href="https://github.com/manuelmhtr"><img src="https://avatars.githubusercontent.com/u/1031639?u=30204017b73f7a1f08005cb8ead3f70b0410486c&v=4" width="20"></a> | manuelmhtr | 35 | 48m | 96 |
<a href="https://github.com/ernestognw"><img src="https://avatars.githubusercontent.com/u/33379285?u=c50ed2928058edc5d412af3d9b9045f6e3309970&v=4" width="20"></a> | ernestognw | 25 | 1h 27m | 63 |
<a href="https://github.com/javierbyte"><img src="https://avatars.githubusercontent.com/u/2009676?u=9aa491152ac3aba42ef8c485cb5331f48bc2fce6&v=4" width="20"></a> | javierbyte | 12 | 30m | 0 |
<a href="https://github.com/Phaze1D"><img src="https://avatars.githubusercontent.com/u/8495952?v=4" width="20"></a> | Phaze1D | 4 | 34m | 1 |
Visual config
Add this to the file .github/workflows/stats.yml
:
name: Pull Request Stats
on:
pull_request:
types: [opened]
jobs:
stats:
runs-on: ubuntu-latest
steps:
- name: Run pull request stats
uses: flowwer-dev/pull-request-stats@main
with:
token: ${{ secrets.ADD_A_PERSONAL_ACCESS_TOKEN }}
organization: 'piedpiper'
period: 7
charts: true
disableLinks: true
sortBy: 'totalComments'
stats: 'totalComments,openedPullRequests'
This config will:
- Calculate the reviewer stats for all the repos in the "piedpiper" organization in the lasts 7 days.
- Display charts for the metrics.
- Remove the links to detailed charts.
- Sort results by the "Total comments" column.
- Show the "Total comments" and "Opened pull requests" columns (in that order).
and print a table like this:
User | Total comments | Total reviews | Median time to review | |
---|---|---|---|---|
<a href="https://github.com/manuelmhtr"><img src="https://avatars2.githubusercontent.com/u/1031639" width="32"></a> | manuelmhtr<br/>🥇 | 12<br/>▀▀▀▀▀▀▀▀ | 8<br/>▀▀▀▀ | 53m<br/> |
<a href="https://github.com/CarlosCRG19"><img src="https://avatars.githubusercontent.com/u/61464973" width="32"></a> | CarlosCRG19<br/>🥈 | 3<br/>▀▀ | 4<br/>▀▀ | 58m<br/> |
<a href="https://github.com/jartmez"><img src="https://avatars0.githubusercontent.com/u/8755542" width="32"></a> | jartmez<br/>🥉 | 1<br/>▀ | 2<br/>▀ | 1d 16h 18m<br/>▀▀▀▀▀▀ |
<a href="https://github.com/Estebes10"><img src="https://avatars1.githubusercontent.com/u/22161828" width="32"></a> | Estebes10<br/> | 1<br/>▀ | 1<br/> | 19m<br/> |
<a href="https://github.com/ernestognw"><img src="https://avatars1.githubusercontent.com/u/33379285" width="32"></a> | ernestognw<br/> | 0<br/> | 2<br/>▀ | 2h 15m<br/> |
<a href="https://github.com/Phaze1D"><img src="https://avatars1.githubusercontent.com/u/8495952" width="32"></a> | Phaze1D<br/> | 0<br/> | 3<br/>▀ | 1h 28m<br/> |
<a href="https://github.com/javierbyte"><img src="https://avatars0.githubusercontent.com/u/2009676" width="32"></a> | javierbyte<br/> | 0<br/> | 1<br/> | 21h 24m<br/>▀▀▀ |
Stats
The stats are calculated as follows:
- Total reviews (
totalReviews
): The count of all Pull Requests reviewed by a person in the period. - Time to review (
timeToReview
): The median time a reviewer takes from the Pull Request publication or the last Commit push (whatever happens last) to the first time the pull request is reviewed. - Total comments (
totalComments
): The number of comments made while reviewing other users' Pull Requests during the specified period. Comments made on your own PRs or general PR discussions are excluded; only comments directly related to code are counted. - Comments per review (
commentsPerReview
): The average comments the reviewer made on the pull requests. - Opened pull requests (
openedPullRequests
): The number of pull requests opened by the user in the period.
Integrations 🔌
Check the guide for the tool you want to integrate:
Troubleshooting
<details> <summary>The action is printing an empty table.</summary>- Make sure the repositories have pull request reviews during the configured
period
. - When specifying
repositories
ororganization
parameters, a Personal Access Token is required in thetoken
parameter. - If providing a Personal Access Token, ensure it has the
repo
permission for the projects you want. - If you are not providing a Personal Access Token (thus, the action is using the default
GITHUB_TOKEN
), make sure the job has thecontents: read
andpull-requests: write
permissions While these permissions are typically provided by default, certain organizations may customize or overwrite them.
jobs:
stats:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Run pull request stats
uses: flowwer-dev/pull-request-stats@main
</details>
<details>
<summary>I get the error "Error commenting on the pull request...".</summary>
This error happens when the organization configures the action's permissions as read
. To fix it, overwrite them by adding a permissions
configuration in the workflow file. The minimum required permissions are contents: read
and pull-requests: write
:
jobs:
stats:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Run pull request stats
uses: flowwer-dev/pull-request-stats@main
</details>
<details>
<summary>I'm a sponsor but still getting the error "...is a premium feature, available to sponsors".</summary>
- Check the sponsorship comes from the account that owns the configured repos (usually an organization).
- Make sure the sponsorship is configured as
public
, otherwise, the action cannot access the sponsorship information. If you prefer to keep itprivate
, please reach me out to make it work for you that way 😉.
Premium features ✨
This action offers some premium features only for sponsors:
- Disabling telemetry.
- Slack integration.
- Microsoft Teams integration.
- Coming soon: Discord integration, web version.
The suggested sponsorship is $20 USD / month. However, if it's not possible for you or your organization, please consider supporting it with any amount you can. Even a one-time sponsorship will enable the Premium features and encourage the progress of this project.
Being a sponsor will also give you access to the premium features in all of my other projects.
Thanks for your support! 💙
Related projects 🔥
- Recap: Tired of writing pull request descriptions? Let GPT do it for you.
Used by
Used by hundreds of successful teams:
<a href="https://www.sixt.com/"><img src="https://avatars.githubusercontent.com/u/25441140?s=200&v=4" width="64"></a><br/>Sixt | <a href="https://shop.lululemon.com"><img src="https://avatars.githubusercontent.com/u/17386352?s=200&v=4" width="64"></a><br/>Lululemon | <a href="https://www.deliveryhero.com"><img src="https://avatars.githubusercontent.com/u/7225556?s=200&v=4" width="64"></a><br/>Delivery H | <a href="https://jokr.com"><img src="https://avatars.githubusercontent.com/u/84920342?s=200&v=4" width="64"></a><br/>JOKR | <a href="https://lego.com"><img src="https://avatars.githubusercontent.com/u/4530164?s=200&v=4" width="64"></a><br/>Lego | <a href="https://firework.tv/"><img src="https://avatars.githubusercontent.com/u/25275837?s=200&v=4" width="64"></a><br/>LOOP | <a href="https://www.usehatchapp.com/"><img src="https://avatars.githubusercontent.com/u/38331218?s=200&v=4" width="64"></a><br/>Hatch | <a href="https://www.zenfi.mx/"><img src="https://avatars.githubusercontent.com/u/68744962?s=200&v=4" width="64"></a><br/>Zenfi |
---|---|---|---|---|---|---|---|
<a href="https://www.intel.com"><img src="https://avatars.githubusercontent.com/u/17888862?s=200&v=4" width="64"></a><br/>Intel | <a href="https://auth0.com/"><img src="https://avatars.githubusercontent.com/u/2824157?s=200&v=4" width="64"></a><br/>Auth0 | <a href="https://www.additionwealth.com/"><img src="https://avatars.githubusercontent.com/u/86253902?s=200&v=4" width="64"></a><br/>Addition | <a href="https://fauna.com/"><img src="https://avatars.githubusercontent.com/u/1477000?s=200&v=4" width="64"></a><br/>Fauna | <a href="http://open.cdc.gov/"><img src="https://avatars.githubusercontent.com/u/12104975?s=200&v=4" width="64"></a><br/>CDC | <a href="https://www.wecasa.fr/"><img src="https://avatars.githubusercontent.com/u/56955553?s=200&v=4" width="64"></a><br/>Wecasa | <a href="https://bolt.eu/"><img src="https://avatars.githubusercontent.com/u/37693190?s=200&v=4" width="64"></a><br/>Bolt | <a href="https://republic.com/"><img src="https://avatars.githubusercontent.com/u/18252987?s=200&v=4" width="64"></a><br/>Republic |
Authors
<a href="https://github.com/manuelmhtr"><img src="https://avatars.githubusercontent.com/u/1031639?v=4" width="32"></a> | @manuelmhtr<br/>🇲🇽 Guadalajara, MX |
---|---|
<a href="https://github.com/CarlosCRG19"><img src="https://avatars.githubusercontent.com/u/61464973?v=4" width="32"></a> | @CarlosCRG19<br/>🇲🇽 Colima, MX |
Help
This project is maintained by a small team, considering supporting the project by:
NEW: Check the web version! ⚡
<img alt="Flowwer web preview" src="/assets/web-preview.png" />
Breaking News! We’ve unleashed the stand-alone version of this action!
- Filter by repositories and date range.
- Stats tracking over the time.
- Tons of new features coming soon!
<img alt="Sign up to Flowwer" height="42px" src="/assets/signup-btn.png" />
License
MIT