nisse-review: repository patterns, and the wall checked every round
At bring-up, nisse-review read no repositories: Gitea's /user/repos leaves out a public repository's Read collaborators, so dev/nisse never showed up. `repositories` now holds patterns (dev/nisse, dev/*, */*) matched against every repository the account can read, public ones included (an organization's or user's list, or the instance's search); unset, it is /user/repos as before. A configured repository it can't read is left out with an oplog line. The read-only wall (R3) is checked every round, not only at startup: an account granted push or admin while running stops (exit 3) rather than review on. nisse-core's Gitea client gains GiteaNotFound for 404s, owner_repositories and visible_repositories. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
This commit is contained in:
1 parent
52c6704b17
commit
2139ddd05c
12 files changed
+283
-44
No files matched your search
@@ -1,7 +1,7 @@
|
||||
"""nisse-review's scheduler (R1): its one duty, and its items one at a time.
|
||||
|
||||
Every round, it asks Gitea for the open PRs in every repository its account
|
||||
can read. A PR that is ready (not a draft, not marked work in progress) gets
|
||||
Every round, it works out the repositories it reviews and checks it still
|
||||
can't write to any (``access``), then asks Gitea for their open PRs. A PR that is ready (not a draft, not marked work in progress) gets
|
||||
a work item; the oldest ready item is reviewed, and its review posted. An
|
||||
item closes when its PR merges or closes. Later reviews, replies and rounds
|
||||
come with M7.5.
|
||||
@@ -19,6 +19,7 @@ from pathlib import Path
|
||||
from nisse_core.gitea import GiteaClient, GiteaError, PullRequest
|
||||
from nisse_core.oplog import OpLog
|
||||
from nisse_core.state.store import WorkItem
|
||||
from nisse_review.access import check, reviewed
|
||||
from nisse_review.reader import Repository
|
||||
from nisse_review.review import Reviewer
|
||||
from nisse_review.state import (
|
||||
@@ -54,7 +55,7 @@ class Scheduler:
|
||||
scratch: Path,
|
||||
poll_s: float = 60.0,
|
||||
attempts: int = 2,
|
||||
only: frozenset[str] | None = None,
|
||||
patterns: frozenset[str] | None = None,
|
||||
) -> None:
|
||||
self._store = store
|
||||
self._gitea = gitea
|
||||
@@ -63,7 +64,8 @@ class Scheduler:
|
||||
self._scratch = scratch
|
||||
self._poll_s = poll_s
|
||||
self._attempts = attempts
|
||||
self._only = only # the repositories reviewed; None: every readable one
|
||||
# The repositories reviewed, as patterns; None: every one it was given.
|
||||
self._patterns = patterns
|
||||
self._stop = threading.Event()
|
||||
|
||||
# -- the loop ---------------------------------------------------------------
|
||||
@@ -77,10 +79,17 @@ class Scheduler:
|
||||
self._stop.set()
|
||||
|
||||
def round(self) -> bool:
|
||||
"""Intake, then one review if one is ready; True if one ran."""
|
||||
"""The wall, intake, then one review if one is ready; True if one
|
||||
ran. An account that can write to a repository it reviews raises
|
||||
``AccessRefused``: it stops, never reviews on (R3)."""
|
||||
try:
|
||||
repos = check(
|
||||
self._gitea,
|
||||
reviewed(self._gitea, self._patterns, self._oplog),
|
||||
self._oplog,
|
||||
)
|
||||
self.recover()
|
||||
self.intake()
|
||||
self.intake(repos)
|
||||
except GiteaError as exc:
|
||||
self._oplog.emit("intake.failed", cause=str(exc)[:300])
|
||||
return False
|
||||
@@ -92,11 +101,11 @@ class Scheduler:
|
||||
|
||||
# -- intake (R1) ------------------------------------------------------------
|
||||
|
||||
def intake(self) -> None:
|
||||
def intake(self, repos: list[str] | None = None) -> None:
|
||||
if repos is None:
|
||||
repos = reviewed(self._gitea, self._patterns, self._oplog)
|
||||
open_items = {i.id: i for i in self._store.work_items("open")}
|
||||
for repo in self._gitea.readable_repositories():
|
||||
if self._only is not None and repo not in self._only:
|
||||
continue
|
||||
for repo in repos:
|
||||
seen: set[str] = set()
|
||||
for pr in self._gitea.open_pull_requests(repo):
|
||||
key = item_id(repo, pr.number)
|
||||
|
||||
Reference in new issue
Block a user