Working as a developer within an extended team of about 20 devs developing an app from scratch, in a fast-paced environment where releases have to be quick, an important issue arose. We noticed that the number of open Pull Requests had increased considerably, and as a result, there was a lot of context switching and slower releases of new features. The context switching further delayed the release of new features, and the increasingly high demand for new features, as well as reprioritization, further increased the number of open Pull Requests.

To tackle this issue, I tried to better define it. Why exactly are there open Pull Requests? How do they increase in number?

How do we end up with more open Pull Requests?

The number of open Pull Requests increases when developers start working on a new feature before the previous one is finished.

Why do developers start working on a new feature before the previous one is finished?

The developer is blocked, awaiting feedback from a colleague.


So far, so good. Is there a way to help the devs make a decision that would decrease the number of open Pull Requests?


Based on the above, I formulated the specs for the tool. Ultimately, it should help the developer quickly decide which Pull Request to work on next or whether to start working on a new feature with the goal being to keep the number of open Pull Requests as low as possible, without any idle time for the devs. This will ensure quick releases of new features and will minimize context switching.


For this purpose, I created a CLI tool named PrOverviewTool (pot). It allows the user to decide which Pull Request to work on next, whether to start working on a new feature, or to help out a colleague who might have ended up with a lot of open Pull Requests, effectively reducing context switching for said colleague and unblocking another, instead of starting a new feature and making the problem worse.

Usage

$ pot --users=john,jane,doe

+------+----------+-----------+-------+---------------+-------------+-------------------+-----------+
| User | Authored | Reviewing | Total |  Total + / -  | Actionables | Actionable  + / - | Untouched |
+------+----------+-----------+-------+---------------+-------------+-------------------+-----------+
| doe  | 3        | 0         | 3     | 146 / 82      | 1           | 40 / 37           | 0         |
| jane | 1        | 2         | 3     | 270 / 254     | 2           | 200 / 187         | 0         |
| john | 2        | 1         | 3     | 34 / 48       | 3           | 34 / 48           | 0         |
+------+----------+-----------+-------+---------------+-------------+-------------------+-----------+

Note: By default, pot only counts open PRs.

Authored

Number of PRs authored by the user

Reviewing

Number of PRs currently reviewing, meaning that said user has not approved, or rejected the PR. If user is a requested reviewer, or if user has placed comments but has not approved or rejected the PR yet, they are considered active reviewers, and said PR counts as one they are currently reviewing.

Total

Authored + Reviewing

Total + / -

Additions/Deletions for all active PRs of user

Actionables

A PR is considered actionable for a user, when said user can perform any action in said PR, and is probably blocking another user. For example, if john is the author of a PR, and jane places some comments, that PR becomes actionable for john, and non actionable for jane. When john responds to jane's comments and re-requests review from her, PR becomes non actionable for john and actionable for jane.

Actionable + / -

Additions/Deletions for all actionable PRs of user

Untouched

When a user is requested to review a PR, and until the moment they place their first comment, that PR is considered untouched for said user. This is useful when workload ends up unevenly distributed amongst devs, and a dev who has an easier time, tries to decide whose PR they are going to review to even the load.

Note:

The above rows are sorted. First by Total, then by Actionable, and finally by Untouched (asc). This way, the most likely candidate to whom a new PR will be assigned, will be closer to the top, and the most likely candidate who might need some help with their PRs, will be closer to the bottom.

Details about a specific user’s PRs

The above example only shows the accumulated counts for each user. Usually, one will want more details about a specific user’s PRs. In that case the --user=<user> option can be used.

$ pot --user=doe

+------+----------+-----------+-------+---------------+-------------+-------------------+-----------+
| User | Authored | Reviewing | Total |  Total + / -  | Actionables | Actionable  + / - | Untouched |
+------+----------+-----------+-------+---------------+-------------+-------------------+-----------+
| doe  | 2        | 3         | 5     | 5287 / 2095   | 3           | 5270 / 2035       | 1         |
| john | 3        | 2         | 5     | 5287 / 2095   | 1           | 5270 / 2035       | 1         |
+------+----------+-----------+-------+---------------+-------------+-------------------+-----------+

+------------+-----------+-------------+---------------------------+
|                         Authored                                 |
+------------+-----------+-------------+---------------------------+
| Actionable | Approvals | +/-         | PR                        |
+------------+-----------+-------------+---------------------------+
| Yes        | 2 / 2     | 4729 / 1561 | Add feature cool (PR_url) |
| No         | 1 / 3     | 12 / 58     | Fix bug wah(PR_url)       |
+------------+-----------+-------------+---------------------------+

+------------+-----------+---------------------+-----------+-----------+--------------------------+
|                                      Reviewing                                                  |
+------------+-----------+---------------------+-----------+-----------+--------------------------+
| Actionable | Untouched | Author: Actionables | Approvals | +/-       | PR                       |
+------------+-----------+---------------------+-----------+-----------+--------------------------+
| Yes        | Yes       | john: 1             | 1 / 2     | 304 / 39  | Add feature wow (PR_url) |
| Yes        | No        | john: 1             | 0 / 2     | 237 / 435 | Fix bug dang (PR_url)    |
| No         | No        | jane: 1             | 3 / 3     | 5 / 2     | Improve styles (PR_url)  |
+------------+-----------+---------------------+-----------+-----------+--------------------------+

Note: Both --users=<user, names> and --user='user' can be used:

$ pot --users=john,jane --user=doe

And both the accumulative and the specific output will be shown

In the above example, the accumulative data is shown for user doe, as well as some details about each of the PRs they are involved in. This can be used by doe to figure out which PR needs their attention first, or by another user who happened to have some idle time and wants to help out. Information about john appear as well, since john is the author of all the PRs that doe is reviewing, and is also reviewing all PRs that doe has authored. This allows one to simply pass the --user argument and get information on the status of all users with which they share any PRs, without explicitly passing a --users argument.

Approvals

The ratio of users who have approved the PR, to all users ever involved in the PR.

+/-

Additions / Deletions in lines of code

Source Code

All the code for the tool can be found in the pot repository.