config PRs: remove the hive's config-PR webhook, poll and core merge
An operator's merge on the forge deploys a config PR through
swarm-controller's DeployRequest{rev}. The hive-side path that queued a
MergeConfigPr approval and merged the PR as `core` goes:
- the `/webhook/config-pr` receiver, its HMAC secret, the WebhookRegister
boot node and the org-hook registration; the hive vhost's `/webhook/`
location
- the 5-minute config-PR poll
- ApprovalKind::MergeConfigPr, its dashboard card, and the deploy DAG it
drove (DeployWindow, MergeVerify, DeployApply, FinalizeDeploy,
DeployTail), with verify_commit, the two-phase meta deploy, rollback
refs, the PR-failure comment and forge/pr_merge.rs
- `fetched_sha`, `sha_short`/`pr_number` on approval events, and
`sha`/`tag` on HelperEvent::ApprovalResolved: only the merge path set
them
`config_repo`, `merged_pr_for_commit` and `post_pr_comment` move to
forge/pr_comment.rs for the merged-rev deploy's refusal comment.
Approvals v5 drops stored `merge_config_pr` rows; a test reopens a v4
database holding them.
Closes #4850
This commit is contained in:
parent
a5ea015bc6
commit
efbfec6d01
39 changed files with 286 additions and 3199 deletions
|
|
@ -40,7 +40,6 @@ mod swarm_queue;
|
|||
mod swarm_status;
|
||||
#[cfg(test)]
|
||||
mod test_env;
|
||||
mod webhook_secret;
|
||||
mod workers;
|
||||
|
||||
pub(crate) use agent_config::{capabilities, limits, resource_limits, tool_groups, topology};
|
||||
|
|
@ -296,54 +295,6 @@ async fn cmd_serve(
|
|||
// `workers::auto_update::submit_startup_sweep_nodes`), submitted
|
||||
// unconditionally on every boot — moved off a bare `tokio::spawn` so it
|
||||
// shows as real work on the dashboard.
|
||||
// Webhook HMAC secret: load from state dir or generate on first run.
|
||||
// Used by both the webhook handlers (verification) and the Forgejo
|
||||
// hook registrations (so Forgejo signs deliveries with the same key).
|
||||
let webhook_secret: Option<String> = match crate::webhook_secret::load_or_generate() {
|
||||
Ok(s) => Some(s),
|
||||
Err(e) => {
|
||||
tracing::error!(
|
||||
error = ?e,
|
||||
"webhook secret load/generate failed; /webhook/* endpoints disabled and hooks not registered"
|
||||
);
|
||||
None
|
||||
}
|
||||
};
|
||||
// Webhook setup: now a `NodeKind::WebhookRegister` DAG node (see
|
||||
// `workers::auto_update::submit_startup_sweep_nodes`), registering both
|
||||
// `internal/knowledge` (push → git pull) and the `agent-configs` org
|
||||
// (pull_request → queue MergeConfigPr approval) hooks. Its executor
|
||||
// re-derives the core token / hive domain / HMAC secret itself, mirroring
|
||||
// the guard chain that used to live here — see `job_queue::exec::
|
||||
// run_webhook_register`.
|
||||
// Config-PR polling fallback: scan agent-configs org every 5 minutes
|
||||
// for open PRs that have no pending MergeConfigPr approval. Catches
|
||||
// anything the webhook missed (c0re was down when PR opened, delivery
|
||||
// failed, etc.). First sweep fires immediately on startup.
|
||||
let poll_coord = coord.clone();
|
||||
let mut poll_shutdown = coord.shutdown_rx();
|
||||
tokio::spawn(async move {
|
||||
let interval = std::time::Duration::from_mins(5);
|
||||
loop {
|
||||
if let Some(token) = forge::core_token() {
|
||||
let result = Box::pin(forge::config_pr_poll::poll_open_config_prs(
|
||||
&token,
|
||||
&poll_coord,
|
||||
))
|
||||
.await;
|
||||
if let Err(e) = result {
|
||||
tracing::debug!(error = ?e, "config-pr poll: sweep failed (forge may be absent)");
|
||||
}
|
||||
}
|
||||
tokio::select! {
|
||||
() = tokio::time::sleep(interval) => {}
|
||||
_ = poll_shutdown.changed() => {
|
||||
tracing::info!("config-pr poll: shutdown signal received");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// Knowledge periodic pull: hourly fallback in case a knowledge event from
|
||||
// the swarm is missed (e.g. hive-c0re was down when it was sent). Sleeps
|
||||
// before its first pull: the boot `NodeKind::KnowledgePull` DAG node
|
||||
|
|
@ -506,9 +457,8 @@ async fn cmd_serve(
|
|||
// channel (used by `recv_blocking_batch`) stays untouched.
|
||||
spawn_broker_to_dashboard_forwarder(coord.clone());
|
||||
let dash_coord = coord.clone();
|
||||
let dash_secret = webhook_secret.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = dashboard::serve(dashboard_port, dash_coord, dash_secret).await {
|
||||
if let Err(e) = dashboard::serve(dashboard_port, dash_coord).await {
|
||||
tracing::error!(error = ?e, "dashboard failed");
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue