From 71abf2471e6cd3e5bc8f6f62f42b3f6018d1a9b1 Mon Sep 17 00:00:00 2001 From: damocles Date: Fri, 29 May 2026 16:39:50 +0200 Subject: [PATCH] forge: replace removed forgejo admin user edit CLI with PATCH /api/v1/admin/users/{name} (closes #574) --- hive-c0re/src/forge.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/hive-c0re/src/forge.rs b/hive-c0re/src/forge.rs index 96760b87..a8ff9976 100644 --- a/hive-c0re/src/forge.rs +++ b/hive-c0re/src/forge.rs @@ -227,11 +227,30 @@ async fn ensure_user_exists(name: &str, admin: bool) -> Result<()> { /// Existing agents were created with `{name}@hive.local`; this corrects /// that so git commits (which use `{name}@hyperhive`) link to profiles. /// Best-effort: failures are warned, not propagated. +/// +/// Uses the admin REST API (`PATCH /api/v1/admin/users/{name}`) rather +/// than `forgejo admin user edit` because the CLI dropped the `edit` +/// subcommand somewhere between forgejo 8 and current — see #574 for +/// the "flag provided but not defined: -username" error this fix +/// replaces. Body sets `source_id = 0` (local auth, the default for +/// users hive-c0re creates) which forgejo's PATCH validator requires +/// even when the only thing changing is the email. async fn ensure_user_email(name: &str) { + let Some(token) = core_token() else { + tracing::debug!(%name, "forge: skipping ensure_user_email — no core token yet"); + return; + }; let email = agent_email(name); - match forge_admin(&["user", "edit", "--username", name, "--email", &email]).await { - Ok(_) => tracing::debug!(%name, %email, "forge: user email aligned"), - Err(e) => tracing::warn!(%name, error = %e, "forge: could not align user email"), + let body = format!(r#"{{"email":"{email}","source_id":0}}"#); + let url = format!("{FORGE_HTTP}/api/v1/admin/users/{name}"); + match forge_http(reqwest::Method::PATCH, &url, &token, &body).await { + Ok(status) if status.is_success() => { + tracing::debug!(%name, %email, "forge: user email aligned"); + } + Ok(status) => { + tracing::warn!(%name, %email, %status, "forge: PATCH user email returned non-success"); + } + Err(e) => tracing::warn!(%name, error = %e, "forge: PATCH user email transport error"), } }