Pull Request Re-Review Gap Ledger avatar

Pull Request Re-Review Gap Ledger

Pricing

from $10.00 / 1,000 run starteds

Go to Apify Store
Pull Request Re-Review Gap Ledger

Pull Request Re-Review Gap Ledger

Finds each open GitHub pull request where a reviewer already reviewed, the author then pushed new commits, and nobody requested a new review. One dataset record for each pull request and reviewer pair, plus one summary for each reviewer. HTTP only, no bro

Pricing

from $10.00 / 1,000 run starteds

Rating

0.0

(0)

Developer

kingii98

kingii98

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

Find each open GitHub pull request where a reviewer already reviewed, the author then pushed new commits, and nobody requested a new review.

GitHub removes a reviewer from the review request list when the reviewer submits a review. When the author then pushes a fix and does not request a new review, the pull request is in no "review requested" view, but the reviewer must still act. This Actor finds these pull requests and tells you how long each one waits.

How it works

  1. The Actor reads the open pull requests of each repository, the most recently updated first.
  2. It skips each pull request with no activity for more than staleDays days.
  3. For each other pull request, it reads the reviews, the commits and the open review requests.
  4. For each reviewer, it takes the last submitted review. It then compares that time with the commits that came after it.
  5. It writes one record for each pull request and reviewer pair, one summary for each reviewer, and one run summary.

The Actor keeps no state. Each run reads the full history again and computes each verdict again.

Verdicts

VerdictMeaning
awaiting-re-reviewThe author pushed commits after the last review of the reviewer, and nobody requested a new review. This is the gap.
requestedThe reviewer is on the review request list again. The pull request shows in the normal "review requested" view.
up-to-dateNo commit came after the last review of the reviewer.
stale-skippedThe pull request had no activity for more than staleDays days. The Actor did not read its reviews.

Rules:

  • A pending (draft) review does not count. A review that the author of the pull request wrote does not count.
  • A commit by the reviewer does not need a re-review, so the Actor ignores it.
  • An approval followed by new commits is awaiting-re-review, because the approval is for old code.
  • A review request to a team does not name a user. It does not set reReviewRequested.
  • Bot reviews are ignored unless includeBots is true.

Input

FieldDefaultDescription
repositories["pallets/click"]1 to 20 repositories as owner/name.
githubTokennoneA fine-grained token that you own, with read access to pull requests and metadata only. Secret.
reviewers[]Optional GitHub logins. An empty list reports all reviewers.
staleDays90Skip a pull request with no activity for more days than this value.
maxPullRequestsPerRepository200Read at most this number of open pull requests from each repository (1 to 200).
includeBotsfalseAlso report reviews that bot accounts wrote.
timeoutSeconds20Timeout for one GitHub API call.
maxResponseBytes4000000Hard cap on the bytes of one GitHub API answer.

With a token and without a token

  • With githubToken: the Actor uses the GitHub GraphQL API. One call reads 10 pull requests with their last 100 reviews, their last 100 commits and their review requests. One call costs about 1 point of the hourly budget of 5,000 points. The Actor stops while 100 points are still free and reports a partial result. The Actor can read private repositories that the token can read.
  • Without githubToken: GraphQL is not available, so the Actor uses the anonymous REST API on public repositories only. It sends one call for each page of 100 pull requests, then two calls (reviews and commits) for each pull request that is not stale. The anonymous limit is 60 calls for each hour, and on the Apify platform other users can share it. The Actor stops before it spends that budget and reports a partial result.

The Actor sends the token only to api.github.com, in the Authorization header. It never writes the token to the log or to the dataset. It never changes anything on GitHub.

Output

The dataset holds three types of record. Use recordType to select them.

pull-request-reviewer (one for each pull request and reviewer pair)

FieldDescription
repositoryowner/name.
numberPull request number.
titlePull request title.
urlLink to the pull request.
authorLogin of the pull request author.
isDraftTrue for a draft pull request.
reviewerLogin of the reviewer. It is null on a stale-skipped record.
lastReviewStateState of the last review of the reviewer: APPROVED, CHANGES_REQUESTED, COMMENTED or DISMISSED.
lastReviewAtTime of that review.
lastCommitAfterReviewAtTime of the last commit after that review.
commitsAfterReviewNumber of commits after that review.
reReviewRequestedTrue when the reviewer is on the review request list now.
hoursWaitingHours since the first commit after the last review.
verdictawaiting-re-review, requested, up-to-date or stale-skipped.
prUpdatedAtLast activity on the pull request.
noteThe reason for a stale-skipped verdict.
checkedAtTime of the run.

reviewer-summary (one for each reviewer)

reviewer, awaitingReReview (count of awaiting-re-review pull requests), requested, upToDate, longestWaitHours, awaitingPullRequests (for example acme/web#12, the longest wait first) and checkedAt. The reviewers with the most gaps come first. Send this record to a chat channel with an Apify integration.

run-summary (one for each run)

runStatus (complete or partial), stopReason (charge-limit, rate-budget, token-rejected or null), mode (graphql or rest-anonymous), the counts pullRequestsListed, pullRequestsEvaluated, staleSkipped, pairs, awaitingReReview, reviewersWithGaps, longestWaitHours, apiRequestsSent, one status record for each repository, a note and checkedAt.

A repository that cannot be read (for example 404) gets a status in the run summary, and the other repositories continue. A gap, an unreadable repository, a refused token and a spent rate budget are results. They never make the run fail.

Pricing (pay per event)

EventPriceWhen the Actor charges it
run-startedUSD 0.01Once for each run, after the input is valid.
pull-request-evaluatedUSD 0.002Once for each open pull request that the Actor read and evaluated for all its reviewers.
  • The Actor charges for each pull request, not for each reviewer pair. A large review team does not pay more for one pull request.
  • A stale-skipped pull request and a pull request that could not be read are not charged.
  • Before it reads the repositories, the Actor calculates how many pull requests your maximum total charge allows. At that number it stops and reports a partial result with stopReason charge-limit. The default cap of USD 2 covers about 995 pull requests.
  • GitHub API calls use your own token and cost you nothing inside its hourly budget.

Schedule

Run the Actor on a weekday morning schedule, for example at 08:00 in the time zone of your team. Send the reviewer summaries to a chat channel with an Apify integration. Open pull requests change each day, so the list is new each morning.

Limits

  • 20 repositories and 200 open pull requests for each repository in one run.
  • The Actor reads the last 100 reviews and the last 100 commits of each pull request (GraphQL), or the first and the last page of 100 (REST). A reviewer whose last review is older than that is not seen.
  • A commit time is the committer date. A rebase changes that date, so a rebased pull request shows as new commits.
  • The Actor does not follow redirects. A renamed repository gives an error. Use the new name.

Local development

uv sync
uv run pytest
uv run ruff check .