alexsim93 / pull-request-analytics-action Goto Github PK
View Code? Open in Web Editor NEWGenerates detailed PR analytics reports within GitHub, focusing on review efficiency and team performance.
License: MIT License
Generates detailed PR analytics reports within GitHub, focusing on review efficiency and team performance.
License: MIT License
This report based on 270 last updated PRs. To learn more about the project and its configuration, please visit Pull request analytics action.
Below are the settings applied for this report:
GITHUB_OWNERS_REPOS: AlexSim93/pull-request-analytics-action
GITHUB_OWNER_FOR_ISSUE: AlexSim93
GITHUB_REPO_FOR_ISSUE: pull-request-analytics-action
ASSIGNEES: AlexSim93
LABELS: Report
SHOW_STATS_TYPES: timeline, workload, pr-quality, code-review-engagement
TOP_LIST_AMOUNT: 3
AGGREGATE_VALUE_METHODS: percentile
PERCENTILE: 80
CORE_HOURS_START: 10:00
CORE_HOURS_END: 19:00
REPORT_DATE_START: 01/09/2023
REPORT_DATE_END: 01/12/2023
PERIOD_SPLIT_UNIT: months
EXECUTION_OUTCOME: new-issue
Time to review - time from PR creation to first review.
Time to approve - time from PR creation to first approval without requested changes.
Time to merge - time from PR creation to merge.
user | Time to review | Time to approve | Time to merge | Total merged PRs |
---|---|---|---|---|
dev1 | 8 hours 3 minutes | 8 hours 7 minutes | 38 hours 57 minutes | 40 |
dev2 | 2 hours 25 minutes | 3 hours 9 minutes | 34 hours 7 minutes | 42 |
dev10 | 2 hours 31 minutes | 3 hours 23 minutes | 11 hours 5 minutes | 69 |
dev3 | 2 hours 19 minutes | 10 hours 23 minutes | 23 hours 21 minutes | 49 |
dev4 | 6 hours 34 minutes | 11 hours 23 minutes | 36 hours 32 minutes | 44 |
dev5 | 2 hours 31 minutes | 2 hours 31 minutes | 77 hours 28 minutes | 2 |
total | 3 hours 24 minutes | 7 hours 4 minutes | 28 hours 9 minutes | 246 |
gantt
title Pull requests timeline(percentile80) total / minutes
dateFormat X
axisFormat %s
section dev1
Time to review(8 hours 3 minutes) : 0, 483
Time to approve(8 hours 7 minutes) : 0, 487
Time to merge(38 hours 57 minutes) : 0, 2337
section dev2
Time to review(2 hours 25 minutes) : 0, 145
Time to approve(3 hours 9 minutes) : 0, 189
Time to merge(34 hours 7 minutes) : 0, 2047
section dev10
Time to review(2 hours 31 minutes) : 0, 151
Time to approve(3 hours 23 minutes) : 0, 203
Time to merge(11 hours 5 minutes) : 0, 665
section dev3
Time to review(2 hours 19 minutes) : 0, 139
Time to approve(10 hours 23 minutes) : 0, 623
Time to merge(23 hours 21 minutes) : 0, 1401
section dev4
Time to review(6 hours 34 minutes) : 0, 394
Time to approve(11 hours 23 minutes) : 0, 683
Time to merge(36 hours 32 minutes) : 0, 2192
section dev5
Time to review(2 hours 31 minutes) : 0, 151
Time to approve(2 hours 31 minutes) : 0, 151
Time to merge(77 hours 28 minutes) : 0, 4648
section total
Time to review(3 hours 24 minutes) : 0, 204
Time to approve(7 hours 4 minutes) : 0, 424
Time to merge(28 hours 9 minutes) : 0, 1689
Reviews conducted - number of reviews conducted. 1 PR may have only single review.
PR Size - determined using the formula: additions + deletions * 0.5
. Based on this calculation: 0-50: xs, 51-200: s, 201-400: m, 401-700: l, 701+: xl
user | Total opened PRs | Total merged PRs | Additions/Deletions | PR size: xs/s/m/l/xl | Total comments | Reviews conducted |
---|---|---|---|---|---|---|
dev1 | 42 | 40 | +3461/-2066 | 28/7/4/2/1 | 35 | 61 |
dev2 | 44 | 42 | +5498/-3317 | 20/13/5/4/2 | 64 | 62 |
dev10 | 79 | 69 | +6225/-4945 | 52/16/7/2/2 | 67 | 78 |
dev3 | 55 | 49 | +9014/-5233 | 25/10/15/3/2 | 386 | 49 |
dev4 | 46 | 44 | +6340/-2421 | 23/10/6/4/3 | 162 | 31 |
dev5 | 3 | 2 | +32/-78 | 2/1/0/0/0 | 0 | 0 |
dev6 | 0 | 0 | +0/-0 | 0/0/0/0/0 | 0 | 1 |
dev7 | 1 | 0 | +8200/-53 | 0/0/0/0/1 | 5 | 0 |
dev8 | 0 | 0 | +0/-0 | 0/0/0/0/0 | 0 | 1 |
dev9 | 0 | 0 | +0/-0 | 0/0/0/0/0 | 0 | 1 |
total | 270 | 246 | +38770/-18113 | 150/57/37/15/11 | 719 | 237 |
Agreed - discussions with at least 1 reaction π.
Disagreed - discussions with at least 1 reaction π.
user | Total merged PRs | Changes requested received | Agreed / Disagreed / Total discussions received | Comments received |
---|---|---|---|---|
dev1 | 40 | 1 | 5 / 1 / 9 | 18 |
dev2 | 42 | 4 | 23 / 2 / 32 | 34 |
dev10 | 69 | 2 | 12 / 1 / 20 | 33 |
dev3 | 49 | 19 | 79 / 13 / 120 | 181 |
dev4 | 44 | 8 | 39 / 7 / 66 | 82 |
dev5 | 2 | 0 | 0 / 0 / 0 | 0 |
dev6 | 0 | 0 | 0 / 0 / 0 | 0 |
dev7 | 0 | 0 | 1 / 1 / 2 | 2 |
total | 246 | 34 | 159 / 25 / 249 | 350 |
pie
title Discussion's types dev1 total
"Overengineering(2)":2
"Task Incompletion(3)":3
"Bug(2)":2
"Formatting(2)":2
pie
title Discussion's types dev2 total
"Overengineering(5)":5
"Performance Issue(11)":11
"Task Incompletion(6)":6
"Bug(6)":6
"Formatting(4)":4
pie
title Discussion's types dev10 total
"Formatting(2)":2
"Naming convention(3)":3
"Performance Issue(6)":6
"Task Incompletion(1)":1
"Bug(6)":6
"Overengineering(2)":2
pie
title Discussion's types dev3 total
"Formatting(15)":15
"Naming convention(12)":12
"Performance Issue(25)":25
"Task Incompletion(22)":22
"Bug(37)":37
"Overengineering(9)":9
pie
title Discussion's types dev4 total
"Overengineering(6)":6
"Formatting(6)":6
"Bug(22)":22
"Performance Issue(10)":10
"Naming convention(9)":9
"Task Incompletion(13)":13
pie
title Discussion's types dev7 total
"Overengineering(1)":1
"Bug(1)":1
pie
title Discussion's types total total
"Formatting(29)":29
"Naming convention(24)":24
"Performance Issue(52)":52
"Task Incompletion(45)":45
"Bug(74)":74
"Overengineering(25)":25
PR Size - determined using the formula: additions + deletions * 0.5
. Based on this calculation: 0-50: xs, 51-200: s, 201-400: m, 401-700: l, 701+: xl
Changes requested / Comments / Approvals - number of reviews conducted by user. For a single pull request, only one review of each status will be counted for a user.
Agreed - discussions with at least 1 reaction π.
Disagreed - discussions with at least 1 reaction π.
user | Total merged PRs | Agreed / Disagreed / Total discussions conducted | Comments conducted | PR size: xs/s/m/l/xl | Changes requested / Commented / Approved |
---|---|---|---|---|---|
dev1 | 40 | 31 / 2 / 47 | 50 | 31/16/8/4/2 | 6 / 7 / 56 |
dev2 | 42 | 7 / 0 / 11 | 11 | 38/14/5/3/2 | 1 / 8 / 59 |
dev10 | 69 | 102 / 19 / 157 | 237 | 37/17/13/7/4 | 28 / 31 / 77 |
dev3 | 49 | 16 / 3 / 27 | 42 | 24/13/6/4/2 | 0 / 22 / 37 |
dev4 | 44 | 2 / 1 / 6 | 8 | 18/8/5/0/0 | 0 / 5 / 30 |
dev5 | 2 | 0 / 0 / 0 | 0 | 0/0/0/0/0 | 0 / 0 / 0 |
dev6 | 0 | 1 / 0 / 1 | 2 | 0/0/1/0/0 | 0 / 1 / 1 |
dev8 | 0 | 0 / 0 / 0 | 0 | 1/0/0/0/0 | 0 / 0 / 0 |
dev9 | 0 | 0 / 0 / 0 | 0 | 0/1/0/0/0 | 0 / 0 / 1 |
total | 246 | 159 / 25 / 249 | 350 | 150/57/37/15/11 | 34 / 81 / 233 |
Hi, thanks for this great tool!
I have encountered the following error while running this action.
Run AlexSim93/[email protected]
Initiating data request.
RATE LIMIT REMAINING BEFORE REQUESTS: 5000
RATE LIMIT REMAINING BEFORE REQUESTS: 5000
Batch request #1 out of 2
Batch request #1 out of 4
Batch request #2 out of 2
Batch request #2 out of 4
RATE LIMIT REMAINING AFTER REQUESTS: 4713
Batch request #3 out of 4
Batch request #4 out of 4
RATE LIMIT REMAINING AFTER REQUESTS: 4563
Data successfully retrieved. Starting report calculations.
/home/runner/work/_actions/AlexSim93/pull-request-analytics-action/v1.3.1/build/index.js:411
const reviewComments = comments[index]?.filter((comment) => pullRequestLogin !== comment.user.login);
^
TypeError: Cannot read properties of null (reading 'login')
at /home/runner/work/_actions/AlexSim93/pull-request-analytics-action/v1.3.1/build/index.js:411:99
at Array.filter (<anonymous>)
at prepareDiscussions (/home/runner/work/_actions/AlexSim93/pull-request-analytics-action/v1.3.1/build/index.js:411:45)
at /home/runner/work/_actions/AlexSim93/pull-request-analytics-action/v1.3.1/build/index.js:51:40
at Array.forEach (<anonymous>)
at collectData (/home/runner/work/_actions/AlexSim93/pull-request-analytics-action/v1.3.1/build/index.js:32:26)
at main (/home/runner/work/_actions/AlexSim93/pull-request-analytics-action/v1.3.1/build/index.js:[18](https://github.com/dotmoneyjp/meta/actions/runs/7203965954/job/19624664464#step:3:19)74:49)
Node.js v[20](https://github.com/yshrsmz/meta/actions/runs/7203965954/job/19624664464#step:3:21).8.1
It seems like that comment.user
becomes null if that user is deleted.
The deleted user looks like this in GitHub UI
I think we should check if user
exists everywhere, even though the type definition says it is non-null.
This is an idea that was discussed in the development team I am a part of.
Wouldn't it be good to know the next value in the period for each worker so we know if his/her workload is high?
If someone can't get started on a review, they are probably too busy with other tasks.
We can check in on the Daily Sync event and forward reviews to others.
Thanks for a great tool!
Reports works fine, but for now I got error:
Data successfully retrieved. Starting report calculations.
/home/runner/work/_actions/AlexSim93/pull-request-analytics-action/master/build/index.js:1345
collection[userLogin][key].commentsConducted =
^
TypeError: Cannot read properties of undefined (reading 'total')
at /home/runner/work/_actions/AlexSim93/pull-request-analytics-action/master/build/index.js:1345:38
at Array.forEach (<anonymous>)
at /home/runner/work/_actions/AlexSim93/pull-request-analytics-action/master/build/index.js:1342:26
at Array.forEach (<anonymous>)
at prepareDiscussions (/home/runner/work/_actions/AlexSim93/pull-request-analytics-action/master/build/index.js:1286:24)
at /home/runner/work/_actions/AlexSim93/pull-request-analytics-action/master/build/index.js:738:40
at Array.forEach (<anonymous>)
at collectData (/home/runner/work/_actions/AlexSim93/pull-request-analytics-action/master/build/index.js:713:26)
at main (/home/runner/work/_actions/AlexSim93/pull-request-analytics-action/master/build/index.js:18[30](...):55)
Example of config:
name: "PR Analytics"
on:
workflow_dispatch:
inputs:
report_date_start:
description: "Report date start(d/MM/yyyy)"
required: false
report_date_end:
description: "Report date end(d/MM/yyyy)"
required: false
jobs:
create-report:
name: "Create report"
runs-on: ubuntu-latest
steps:
- name: "Run script for analytics"
uses: AlexSim93/pull-request-analytics-action@master
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
LABELS: "Report"
GITHUB_REPO_FOR_ISSUE: "owner"
GITHUB_OWNER_FOR_ISSUE: "owner"
GITHUB_OWNERS_REPOS: "owner/owner"
CORE_HOURS_START: "9:00"
CORE_HOURS_END: "18:00"
TIMEZONE: "Europe/Kiev"
REPORT_DATE_START: ${{ inputs.report_date_start }}
REPORT_DATE_END: ${{ inputs.report_date_end }}
Describe the bug
I tried to fetch all PRs in the repo to generate the report, then it returned errors like below. Not sure which PR made this error, a guess is that the deleted user (ghost) created PR may be the culprit like in #5.
Expected behavior
A clear and concise description of what you expected to happen.
Configuration
name: PR Analytics
on:
workflow_dispatch:
inputs:
report_date_start:
description: "Report date start(d/MM/yyyy)"
required: false
report_date_end:
description: "Report date end(d/MM/yyyy)"
required: false
jobs:
create-report:
name: "Create report"
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: write
steps:
- name: "Run script for analytics"
uses: AlexSim93/pull-request-analytics-action@v2
with:
GITHUB_TOKEN: ${{ secrets.TOKEN }}
GITHUB_REPO_FOR_ISSUE: "***"
GITHUB_OWNER_FOR_ISSUE: "***"
GITHUB_OWNERS_REPOS: "***/***"
CORE_HOURS_START: "9:00"
CORE_HOURS_END: "18:00"
TIMEZONE: "Asia/Shanghai"
REPORT_DATE_START: ${{ inputs.report_date_start }}
REPORT_DATE_END: ${{ inputs.report_date_end }}
I'm facing the github error (limit 65536 characters).
When using this in for my real repo with multiple contributors, I get this error:
RequestError [HttpError]: Validation Failed: {"resource":"Issue","code":"custom","field":"body","message":"body is too long"}, {"resource":"Issue","code":"custom","field":"body","message":"body is too long (maximum is 65536 characters)"}
What's a good workaround I can use? I can see that the report was generated, only the posting failed. Is there anywhere else I could download the MD file from?
Hello, I have a question regarding the implementation of getApproveTime
.
In the implementation of getApproveTime
, it looks like this:
https://github.com/AlexSim93/pull-request-analytics-action/blob/master/src/converters/utils/calculations/getApproveTime.ts
import { makeComplexRequest } from "../../../requests";
export const getApproveTime = (
reviews: Awaited<ReturnType<typeof makeComplexRequest>>["reviews"][number]
) => {
const reviewChangesRequested = reviews?.reduce((acc, review) => {
if (review.state === "CHANGES_REQUESTED") {
const login = review.user?.login || "invalid";
return { ...acc, [login]: true };
}
return acc;
}, {}) as Record<string, boolean> | undefined;
const reviewApproved = reviews?.reduce((acc, review) => {
if (review.state === "APPROVED") {
const login = review.user?.login || "invalid";
return { ...acc, [login]: review.submitted_at };
}
return acc;
}, {}) as Record<string, string> | undefined;
const usersRequestedChanges = reviewChangesRequested
? Object.keys(reviewChangesRequested)
: [];
if (usersRequestedChanges.length === 0) {
return reviews?.find((review) => review.state === "APPROVED")?.submitted_at;
}
const approveEntry = Object.entries(reviewApproved || {}).find(([user]) => {
if (reviewChangesRequested?.[user]) {
reviewChangesRequested[user] = false;
return !Object.values(reviewChangesRequested).some(
(value) => value === true
);
}
return false;
});
return approveEntry?.[1];
};
In the current implementation, there is no comparison before and after CHANGES_REQUESTED
and APPROVED
.
Therefore, even if CHANGES_REQUESTED
is performed after APPROVED
, the value of approveEntry can still be obtained.
The data I want to obtain should ideally be in the state where all reviews are APPROVED,
but this implementation does not achieve that.
Was this implementation intentional?
Your feedback would be appreciated.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.