Skip to main content
The complexity check measures the functions a pull request changes and names the ones that cross a limit. The check itself never fails a pull request. To block a merge on it, set Complexity findings to Request changes, and the code review does the blocking.

What you see

A check named Peeps / static analysis appears on the pull request’s latest commit, beside your other checks. Each function that needs your attention gets one annotation, with its number before and after, the limit and the metric:
A function over both limits gets one annotation with both numbers. A new function reads new → 17. The summary has a line for each metric that’s on, with the tool and version it used, followed by any files it couldn’t analyse. A check shows up to 50 annotations, and the summary counts the rest per file.

Turn it on

You set it up one repository at a time. It’s off until you turn it on, and it doesn’t depend on the code review switch for that repository.
1

Pick the repository

Go to Settings > Code review > Review settings and choose it from the Repository menu.
2

Turn on the check

In the Static code analysis section, use the Complexity check switch.
3

Choose the metrics and limits

Each has its own switch and limit, a whole number from 5 to 50. With both off, Peeps posts no check.
4

Save

Click Save changes.
A change applies from the next push. A commit that already has its check isn’t checked again. Presets don’t change this section. If the GitHub App was reinstalled since you saved, the section says the check isn’t running. Click Save changes to turn it back on.

Who can use it

You need the Owner role. You also need code review available on your organization and the Peeps GitHub App connected.
If you don’t see the Static code analysis section, it isn’t turned on for your organization yet. Get in touch to request access.

Where the numbers come from

The check’s summary names the version it used.
  • ESLint can read one higher in one case. It counts a default inside an array assignment, such as [s = ""] = run(), and Oxlint doesn’t.
  • Biome reports only scores above 1. A function with no score reads ≤ 1.
  • Biome doesn’t score getters, setters or static blocks. They read ≤ 1 and can’t cross a limit.
  • Biome’s score stops at 255. The check shows it as 255+.
Nothing runs in your CI, and nothing from your pull request is executed. Peeps reads the changed files through the GitHub App and the tools read a copy of them as data. No AI model is involved in the check. Your config files, ignore files and suppression comments, such as eslint-disable and biome-ignore, don’t change what it reports.

Don’t make it a required check

Don’t add Peeps / static analysis to your required checks.
The check reads success or neutral, never failure, so requiring it protects nothing. In a merge queue it also stops merges: a required check waits on the queue’s commit, and this check never runs on that commit. It reads success only when every metric that’s on analysed every file it should and nothing crossed a limit. Anything else reads neutral, including:
  • A function that’s new over a limit, crossed one, or has no earlier number to compare
  • Any file that wasn’t analysed
  • Another open pull request on the same commit, which the summary names as not judged here
If the check can’t finish, it reads Couldn’t analyse, also neutral. The next push runs it again.

What it analyses

It runs on every pull request’s latest commit, including drafts and pull requests from bots and forks. Code review skips some of these, so you can see this check on a pull request with no review. It runs again when a pull request’s base branch changes. The summary reads 3 Swift files not analysed, or lists a file with its reason: A pull request with more than 100 changed files has the rest counted and not read.

In the code review

When code review is also on for the repository, the review’s main comment shows the functions that matter in a folded Complexity section:
  • Over the limit, in red: a function this pull request made new over a limit, pushed over, or made worse while over. One it lowered but is still over shows too, as progress.
  • Brought back under, in green: a function that was over a limit and this pull request brought under it.
Other changed functions, such as small changes under the limit, aren’t shown in the comment. The check’s page still lists every one.
  • The heading counts them: Complexity · 1 over the limit · 1 brought under.
  • A table of the worst ten, each row linked to its function’s line on the pull request’s Files changed tab, with each metric’s earlier score and its new one. new → 16 marks a new function, and now 21 a function with no earlier score. A function with no name reads Function at line 4.
  • A last row that links to the check’s summary and counts what the table doesn’t show, such as 3 more · All results in Peeps / static analysis.
The section is left out when no function is over a limit or brought back under. The review’s own text gives no numbers. It may say which lines drove one, which is its reading, not a measurement.

What the review does with them

In the Static code analysis section, Complexity findings sets what the review does when this pull request makes a function cross a limit: With Request changes, a function that was already over its limit and got worse, or has no earlier number to compare, is still shown but doesn’t block. The code review check reads neutral and names the issues. If Fail the check is set to Also on changes requested, it fails. To leave complexity out of the review, turn the Complexity check off. The row is unavailable while the check or both metrics are off. If the check hasn’t finished when the review posts, the functions are left out. With Request changes, the review then neither requests changes nor approves, and says the complexity check hadn’t finished. The review is headed Complexity not judged when it found nothing else, and the code review check’s title ends with “complexity check hadn’t finished”. The code review check fails, as for any review that couldn’t finish, unless Fail the check is Never. The next push gets it. Retry or /peeps review before the check finishes settles the check again and spends no review. While complexity isn’t judged, the review lifts an earlier Peeps review that requested changes only for findings. One that requested changes for complexity stays until a review that judged complexity replaces it. With Request changes, a push the review would otherwise skip, such as one that changes only ignored files, waits up to 5 minutes for the check. If a function crossed a limit, the review runs in full. A pull request whose changed files are all in Ignore paths, generated or likely secrets gets a short Nothing to review review, which doesn’t count toward your daily reviews. With Request changes, it waits up to 5 minutes for the check, and still requests changes if a function in those files crossed a limit. On a pull request Peeps opened itself, the review comments instead of requesting changes, since GitHub doesn’t let it block its own pull request. The review follows its own trigger, so a review set to When a PR opens won’t explain later pushes. The check still runs on them.
Questions about the complexity check? Get in touch.