refactor(hive-c0re): port forge module + knowledge hooks to forgejo-api
This commit is contained in:
parent
4468e86e2d
commit
b8a3927c43
5 changed files with 651 additions and 426 deletions
|
|
@ -11,7 +11,10 @@
|
|||
//! webhook is auto-created by [`ensure_webhook`] at startup. A
|
||||
//! periodic pull in `main.rs` provides a fallback cadence.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use forgejo_api::structs::{CreateHookOption, CreateHookOptionConfig, CreateHookOptionType};
|
||||
|
||||
pub const ORG: &str = "internal";
|
||||
pub const REPO: &str = "knowledge";
|
||||
|
|
@ -146,65 +149,49 @@ async fn seed_readme(core_token: &str) -> Result<()> {
|
|||
/// core token is absent (forge not yet provisioned).
|
||||
pub async fn ensure_webhook(core_token: &str, dashboard_port: u16) -> Result<()> {
|
||||
let target_url = format!("http://127.0.0.1:{dashboard_port}/webhook/knowledge");
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(std::time::Duration::from_secs(10))
|
||||
.build()
|
||||
.context("build reqwest client for webhook setup")?;
|
||||
let client = crate::forge::api(core_token)?;
|
||||
|
||||
// List existing hooks — skip creation if ours is already there.
|
||||
let list_url = format!(
|
||||
"{}/api/v1/repos/{ORG}/{REPO}/hooks",
|
||||
crate::forge::FORGE_HTTP
|
||||
);
|
||||
let resp = client
|
||||
.get(&list_url)
|
||||
.header("Authorization", format!("token {core_token}"))
|
||||
.send()
|
||||
.await
|
||||
.with_context(|| format!("GET {list_url}"))?;
|
||||
if resp.status().is_success() {
|
||||
let hooks: Vec<serde_json::Value> = resp.json().await.unwrap_or_default();
|
||||
let already_exists = hooks.iter().any(|h| {
|
||||
h.get("config")
|
||||
.and_then(|c| c.get("url"))
|
||||
.and_then(|u| u.as_str())
|
||||
== Some(&target_url)
|
||||
});
|
||||
if already_exists {
|
||||
tracing::debug!(%target_url, "knowledge: push webhook already configured");
|
||||
return Ok(());
|
||||
// Best-effort like the raw-HTTP predecessor: a listing failure
|
||||
// falls through to the create attempt.
|
||||
match client.repo_list_hooks(ORG, REPO).all().await {
|
||||
Ok(hooks) => {
|
||||
let already_exists = hooks.iter().any(|h| {
|
||||
h.config
|
||||
.as_ref()
|
||||
.and_then(|c| c.get("url"))
|
||||
.map(String::as_str)
|
||||
== Some(target_url.as_str())
|
||||
});
|
||||
if already_exists {
|
||||
tracing::debug!(%target_url, "knowledge: push webhook already configured");
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::debug!(error = %e, "knowledge: listing hooks failed; attempting create");
|
||||
}
|
||||
}
|
||||
|
||||
// Create the webhook.
|
||||
let create_url = format!(
|
||||
"{}/api/v1/repos/{ORG}/{REPO}/hooks",
|
||||
crate::forge::FORGE_HTTP
|
||||
);
|
||||
let body = serde_json::json!({
|
||||
"type": "forgejo",
|
||||
"config": {
|
||||
"url": target_url,
|
||||
"content_type": "json"
|
||||
let hook = CreateHookOption {
|
||||
active: Some(true),
|
||||
authorization_header: None,
|
||||
branch_filter: None,
|
||||
config: CreateHookOptionConfig {
|
||||
content_type: "json".to_owned(),
|
||||
url: url::Url::parse(&target_url).context("parse webhook target url")?,
|
||||
additional: BTreeMap::new(),
|
||||
},
|
||||
"events": ["push"],
|
||||
"active": true
|
||||
});
|
||||
let resp = client
|
||||
.post(&create_url)
|
||||
.header("Authorization", format!("token {core_token}"))
|
||||
.json(&body)
|
||||
.send()
|
||||
events: Some(vec!["push".to_owned()]),
|
||||
r#type: CreateHookOptionType::Forgejo,
|
||||
};
|
||||
client
|
||||
.repo_create_hook(ORG, REPO, hook)
|
||||
.await
|
||||
.with_context(|| format!("POST {create_url}"))?;
|
||||
let status = resp.status();
|
||||
if status.is_success() {
|
||||
tracing::info!(%target_url, "knowledge: push webhook created");
|
||||
Ok(())
|
||||
} else {
|
||||
let body = resp.text().await.unwrap_or_default();
|
||||
anyhow::bail!("create webhook for {ORG}/{REPO} failed ({status}): {body}")
|
||||
}
|
||||
.with_context(|| format!("create webhook for {ORG}/{REPO}"))?;
|
||||
tracing::info!(%target_url, "knowledge: push webhook created");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Pull the latest changes in the local clone. Called from the webhook
|
||||
|
|
|
|||
Loading…
Reference in a new issue