swarm-controller: post the review classifier's verdict on a review request
Requesting the forge account `review-classifier` as a reviewer now runs the repo's rules against the PR and posts the result as that account's review, on the head commit the run read. A push starts no run; only a fresh review request does. - An instance-wide `pull_request_review_request` system hook delivers to `/webhook/forge/review-request`. A request for any other reviewer, or a removed request, does nothing. - The controller reads the PR, loads the rules with the same reader as `GET /api/review-classifier/rules`, sends one request on the try-out subject, and posts APPROVED or REQUEST_CHANGES with the table as the body. - With no clean verdict (PR or rules don't load, the run fails, or any classification has no answer) it posts a COMMENT saying why, never an approval. The event is one function, `no_clean_verdict_event`. - Table cells are flattened, markup-escaped, and every `@` gets a zero-width space, so a model's reason can't break the table or mention anyone. - At most two requested reviews run at once; the rest wait in memory. - The account is minted the way hive accounts are: a five-minute pass queues a `MintClassifierForgeToken` node when the token at `swarm/services/review-classifier/forge/token` is missing or stale. The token is `write:repository`. The controller's bao policy gains that leaf (create/read/update), pinned in module-eval bao-grants. The classifier never sees the token. The account gets no repo access automatically; a repo admin adds it by hand. A re-request retires the account's earlier review: Forgejo clears `official` on a reviewer's earlier reviews when it is requested again (models/issues/review.go AddReviewRequest, v16.0.5), and approvals and rejection blocks count official reviews only. Refs #5137
This commit is contained in:
parent
ad47664e01
commit
a669cd96b6
17 changed files with 1156 additions and 50 deletions
|
|
@ -221,6 +221,10 @@ pub(super) enum DeliveryKind {
|
|||
/// `repo_create_hook`) — different scope, same event name.
|
||||
#[strum(serialize = "vcs-activity")]
|
||||
VcsActivity,
|
||||
/// `pull_request_review_request` events on every repo in the instance,
|
||||
/// for the review classifier's account (`crate::review_classifier::review`).
|
||||
#[strum(serialize = "review-request")]
|
||||
ReviewRequest,
|
||||
}
|
||||
|
||||
/// The route prefix a registered `target_url` must point at.
|
||||
|
|
@ -236,7 +240,12 @@ impl DeliveryKind {
|
|||
/// Every kind, for the registration sweep. An array rather than a
|
||||
/// hand-written list at the call site, so adding a kind cannot leave one
|
||||
/// hook unregistered.
|
||||
pub(super) const ALL: [Self; 3] = [Self::Knowledge, Self::ConfigPr, Self::VcsActivity];
|
||||
pub(super) const ALL: [Self; 4] = [
|
||||
Self::Knowledge,
|
||||
Self::ConfigPr,
|
||||
Self::VcsActivity,
|
||||
Self::ReviewRequest,
|
||||
];
|
||||
|
||||
/// The `target_url` to register with Forgejo for this kind, given the
|
||||
/// swarm's public base URL.
|
||||
|
|
@ -341,7 +350,9 @@ pub(super) fn verify(
|
|||
/// [`announce_knowledge_change`]); a `ConfigPr` delivery updates
|
||||
/// `crate::config_pr::ConfigPrCache` immediately (see that module's doc
|
||||
/// comment for why both this and a periodic poll write the same cache), and a
|
||||
/// merge queues a deploy of the merged commit on the agent's hive.
|
||||
/// merge queues a deploy of the merged commit on the agent's hive. A
|
||||
/// `ReviewRequest` delivery naming the review classifier's account starts a
|
||||
/// review run in the background.
|
||||
///
|
||||
/// Returns 200 on an accepted delivery so Forgejo does not retry. A refused
|
||||
/// one answers 401 (bad signature) or 503 (this daemon has no secret), and
|
||||
|
|
@ -351,7 +362,8 @@ pub(super) fn verify(
|
|||
path = "/webhook/forge/{kind}",
|
||||
params(
|
||||
("kind" = String, Path, description = "which swarm-wide hook this delivery arrived on: \
|
||||
`knowledge` or `config-pr`")
|
||||
`knowledge`, `config-pr`, `vcs-activity` or \
|
||||
`review-request`")
|
||||
),
|
||||
request_body(
|
||||
content = String,
|
||||
|
|
@ -414,6 +426,7 @@ pub(super) async fn post_webhook_forge(
|
|||
tracing::warn!("webhook: vcs-activity delivery did not parse as a push payload");
|
||||
}
|
||||
}
|
||||
DeliveryKind::ReviewRequest => crate::review_classifier::review::on_delivery(&state, &body),
|
||||
}
|
||||
|
||||
(StatusCode::OK, "ok").into_response()
|
||||
|
|
|
|||
Loading…
Reference in a new issue