perf(forge): pr list and test requests ask git.magicbean.dev for less: PRs listed as issues, authors' permissions kept an hour #877

Merged
HumanBean merged 1 commit from HumanBean/Longshot:perf/forge-cheaper-api into main 2026-11-15 18:49:42 +00:00
Owner

Type: perf · Risk: low · Tested on: Linux (CachyOS), against git.magicbean.dev · Needs: none

Why

git.magicbean.dev has been slow (pages at 3-4 s), and part of its load is our own tools asking it for more than they need. forge.py pr list walked every page of the pull request list, and each PR on it makes Forgejo load that PR's branches and repositories; --mine then threw most of it away. test_requests.py fetched each PR through the same expensive endpoint, and asked for its author's permission again for every PR on every run (about 210 times in 3 hours, always the same author).

What changed

The two scripts ask Forgejo for the same information through its cheaper issues endpoint, and the test requests keep an author's permission for an hour.

  • scripts/forge.py, pr list: reads /issues?type=pulls (it has the number, state, author, title and pull_request.merged that the list prints). --mine asks for created_by=<you> instead of fetching every page to filter.
  • scripts/test_requests.py: pr_info() reads /issues/N (state, labels, author, pull_request.merged and draft), and refuses a number that isn't a PR. author_permission() keeps each author's permission for PERMISSION_TTL (an hour) in forge_permissions.json in the sign-in's folder; where that can't be written (a sandbox), it's kept for the run only.

Measurements

Verdict: one page of the PR list takes 0.6 s instead of 8.9 s, and pr list --mine takes 0.6 s in all.

Hardware: git.magicbean.dev (Forgejo 17); client on Linux
Method: the same page fetched through each endpoint, back to back, signed in; then the changed commands run
How to reproduce: python -I scripts/forge.py pr list --mine --state open

Before: main @ 7bacf846 After: this PR @ c00be61d
One page of 50 PRs 8.90 s (/pulls) 0.57 s (/issues?type=pulls), the same 50 PRs in the same order
pr list --mine --state open every page of the PR list 0.59 s

Flags and settings

None

Testing

Tested: On Linux against git.magicbean.dev: pr list --mine --state open (my 5 open PRs, as before), pr list --state closed (merged ones show as merged), and test_requests.py list (states and approvals shown; forge_permissions.json written). py_compile of both files. I didn't run tests/run_all.py (this PC runs no test suites, and the CI runner for the Python checks is off for now). tests/test_test_requests.py stands in for pr_info as a whole, so it isn't affected.

Not tested: Windows (the cache file is written with write_private, as the sign-in is).

Must be tested:

  • None

Risks

What could break: a maintainer giving an author write access shows in test requests within the hour, not at once (the testing wanted label still works at once).

Turning it off: revert the commit.

Compatibility: a new file, forge_permissions.json, in the sign-in's folder; nothing else changes.

Checklist

Everyone

  • One topic.
  • The title is a Conventional Commit (type(scope): description) of the status line's type.
  • Why gives the reason plainly and links the issues that fit (the tracker searched).
  • Measurements has a verdict, or one line saying why there is nothing to measure.
  • Testing names what was tested, what wasn't, and what must still be tested, where and how.
  • Rebased on current main.
  • python -I -B tests/run_all.py passes (any failure that also fails on main is named). (not run: no test suites on this PC, and no runner for the Python checks right now)
  • No game files, dumps, build output or generated files.
  • third_party/ untouched (a new folder with a PROVENANCE.md instead).
  • The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled.

When it applies

  • AI assistance recorded with Assisted-by: / Co-Authored-By: trailers.

🤖 Generated with Claude Code

**Type:** perf · **Risk:** low · **Tested on:** Linux (CachyOS), against git.magicbean.dev · **Needs:** none ## Why git.magicbean.dev has been slow (pages at 3-4 s), and part of its load is our own tools asking it for more than they need. `forge.py pr list` walked every page of the pull request list, and each PR on it makes Forgejo load that PR's branches and repositories; `--mine` then threw most of it away. `test_requests.py` fetched each PR through the same expensive endpoint, and asked for its author's permission again for every PR on every run (about 210 times in 3 hours, always the same author). ## What changed The two scripts ask Forgejo for the same information through its cheaper issues endpoint, and the test requests keep an author's permission for an hour. - `scripts/forge.py`, `pr list`: reads `/issues?type=pulls` (it has the number, state, author, title and `pull_request.merged` that the list prints). `--mine` asks for `created_by=<you>` instead of fetching every page to filter. - `scripts/test_requests.py`: `pr_info()` reads `/issues/N` (state, labels, author, `pull_request.merged` and `draft`), and refuses a number that isn't a PR. `author_permission()` keeps each author's permission for `PERMISSION_TTL` (an hour) in `forge_permissions.json` in the sign-in's folder; where that can't be written (a sandbox), it's kept for the run only. ## Measurements **Verdict:** one page of the PR list takes 0.6 s instead of 8.9 s, and `pr list --mine` takes 0.6 s in all. Hardware: git.magicbean.dev (Forgejo 17); client on Linux Method: the same page fetched through each endpoint, back to back, signed in; then the changed commands run How to reproduce: `python -I scripts/forge.py pr list --mine --state open` | | Before: main @ 7bacf846 | After: this PR @ c00be61d | |---|---|---| | One page of 50 PRs | 8.90 s (`/pulls`) | 0.57 s (`/issues?type=pulls`), the same 50 PRs in the same order | | `pr list --mine --state open` | every page of the PR list | 0.59 s | ### Flags and settings None ## Testing **Tested:** On Linux against git.magicbean.dev: `pr list --mine --state open` (my 5 open PRs, as before), `pr list --state closed` (merged ones show as merged), and `test_requests.py list` (states and approvals shown; `forge_permissions.json` written). `py_compile` of both files. I didn't run `tests/run_all.py` (this PC runs no test suites, and the CI runner for the Python checks is off for now). `tests/test_test_requests.py` stands in for `pr_info` as a whole, so it isn't affected. **Not tested:** Windows (the cache file is written with `write_private`, as the sign-in is). **Must be tested:** - None ## Risks **What could break:** a maintainer giving an author write access shows in test requests within the hour, not at once (the `testing wanted` label still works at once). **Turning it off:** revert the commit. **Compatibility:** a new file, `forge_permissions.json`, in the sign-in's folder; nothing else changes. ## Checklist ### Everyone - [x] One topic. - [x] The title is a Conventional Commit (`type(scope): description`) of the status line's type. - [x] Why gives the reason plainly and links the issues that fit (the tracker searched). - [x] Measurements has a verdict, or one line saying why there is nothing to measure. - [x] Testing names what was tested, what wasn't, and what must still be tested, where and how. - [x] Rebased on current `main`. - [ ] `python -I -B tests/run_all.py` passes (any failure that also fails on `main` is named). (not run: no test suites on this PC, and no runner for the Python checks right now) - [x] No game files, dumps, build output or generated files. - [x] `third_party/` untouched (a new folder with a `PROVENANCE.md` instead). - [x] The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled. ### When it applies - [x] AI assistance recorded with `Assisted-by:` / `Co-Authored-By:` trailers. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
perf(forge): pr list and test requests ask git.magicbean.dev for less: PRs listed as issues, authors' permissions kept an hour
Some checks failed
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been skipped
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been skipped
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been skipped
Website / Website on Cloudflare (pull_request_target) Has been skipped
Third-party parts / The same as upstream (pull_request) Has been skipped
CI / Conventional Commit title (pull_request) Successful in 4s
CI / Workflow lint (actionlint) (pull_request) Successful in 5s
Guide screenshots / Guide images and local UI source review (pull_request) Failing after 4s
Third-party parts / As their notes say (pull_request) Successful in 9s
PR description / Description follows the template (pull_request_target) Failing after 3s
c00be61dbc
pr list reads the issues list (type=pulls), which has every field it prints, instead
of the pulls list, which loads each PR's branches and repositories: 0.6 s a page
against 8.9 s on 2026-11-15. --mine asks for the user's PRs only (created_by) rather
than every page to filter. test_requests.py's pr_info reads /issues/N for the same
reason, and keeps each author's permission an hour (forge_permissions.json in the
sign-in's folder) instead of asking it for every PR on every list.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
HumanBean changed title from WIP: perf(forge): pr list and test requests ask git.magicbean.dev for less: PRs listed as issues, authors' permissions kept an hour to perf(forge): pr list and test requests ask git.magicbean.dev for less: PRs listed as issues, authors' permissions kept an hour 2026-11-15 18:49:38 +00:00
HumanBean deleted branch perf/forge-cheaper-api 2026-11-15 18:49:42 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MagicBeanDev/Longshot!877
No description provided.