fix(forge): review fixes for the forgejo-api port
This commit is contained in:
parent
5cfb33eeed
commit
261f02439b
6 changed files with 57 additions and 22 deletions
|
|
@ -117,6 +117,18 @@ fn is_conflict(e: &ForgejoError) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Whether an error is Forgejo saying 404 — the resource is absent,
|
||||
/// as opposed to a transport / auth / server failure.
|
||||
fn is_not_found(e: &ForgejoError) -> bool {
|
||||
match e {
|
||||
ForgejoError::ApiError(api) => {
|
||||
matches!(api.error_kind(), ApiErrorKind::NotFound { .. })
|
||||
}
|
||||
ForgejoError::UnexpectedStatusCode(s) => *s == StatusCode::NOT_FOUND,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Fold a repo-creation result's "already exists" (409 / 422) into
|
||||
/// success. `label` is `<owner>/<name>` — purely for log + error
|
||||
/// context.
|
||||
|
|
@ -474,23 +486,33 @@ async fn ensure_mirror_repo(
|
|||
admin_token: &str,
|
||||
) -> Result<()> {
|
||||
let client = api(admin_token)?;
|
||||
if client.repo_get(owner, repo).await.is_ok() {
|
||||
// Mirror already present. Patch interval so mirrors seeded before
|
||||
// this field was introduced (or with a different value) converge.
|
||||
let mut edit = sparse_edit_repo_option();
|
||||
edit.mirror_interval = Some(MIRROR_INTERVAL.to_owned());
|
||||
match client.repo_edit(owner, repo, edit).await {
|
||||
Ok(_) => {
|
||||
tracing::debug!(%owner, %repo, interval = MIRROR_INTERVAL, "forge: pull-mirror interval updated");
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!(
|
||||
%owner, %repo, error = %e,
|
||||
"forge: failed to set mirror_interval on existing pull-mirror"
|
||||
);
|
||||
match client.repo_get(owner, repo).await {
|
||||
Ok(_) => {
|
||||
// Mirror already present. Patch interval so mirrors seeded before
|
||||
// this field was introduced (or with a different value) converge.
|
||||
let mut edit = sparse_edit_repo_option();
|
||||
edit.mirror_interval = Some(MIRROR_INTERVAL.to_owned());
|
||||
match client.repo_edit(owner, repo, edit).await {
|
||||
Ok(_) => {
|
||||
tracing::debug!(%owner, %repo, interval = MIRROR_INTERVAL, "forge: pull-mirror interval updated");
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!(
|
||||
%owner, %repo, error = %e,
|
||||
"forge: failed to set mirror_interval on existing pull-mirror"
|
||||
);
|
||||
}
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
// Absent — fall through to migrate.
|
||||
Err(e) if is_not_found(&e) => {}
|
||||
// Anything else (transport, auth, 5xx) leaves the repo's existence
|
||||
// unknown: migrating anyway would fold a 409 into success and skip
|
||||
// the interval patch this pass. Surface it instead.
|
||||
Err(e) => {
|
||||
return Err(e).with_context(|| format!("get pull-mirror {owner}/{repo}"));
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
let opts = MigrateRepoOptions {
|
||||
auth_password: None,
|
||||
|
|
|
|||
|
|
@ -148,13 +148,23 @@ async fn seed_readme(core_token: &str) -> Result<()> {
|
|||
/// Called at startup alongside [`ensure_local_clone`]. No-op when the
|
||||
/// core token is absent (forge not yet provisioned).
|
||||
pub async fn ensure_webhook(core_token: &str, dashboard_port: u16) -> Result<()> {
|
||||
// The typed client carries no per-request timeout, so each call is
|
||||
// wrapped in one: this runs as a detached startup task, and a forge
|
||||
// that accepts connections but never answers would otherwise hang
|
||||
// it forever (and the hourly pull fallback masks the missing hook).
|
||||
const HTTP_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
|
||||
|
||||
let target_url = format!("http://127.0.0.1:{dashboard_port}/webhook/knowledge");
|
||||
let client = crate::forge::api(core_token)?;
|
||||
|
||||
// List existing hooks — skip creation if ours is already there.
|
||||
// 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 {
|
||||
let listed = tokio::time::timeout(HTTP_TIMEOUT, client.repo_list_hooks(ORG, REPO).all())
|
||||
.await
|
||||
.map_err(anyhow::Error::from)
|
||||
.and_then(|r| r.map_err(anyhow::Error::from));
|
||||
match listed {
|
||||
Ok(hooks) => {
|
||||
let already_exists = hooks.iter().any(|h| {
|
||||
h.config
|
||||
|
|
@ -186,9 +196,10 @@ pub async fn ensure_webhook(core_token: &str, dashboard_port: u16) -> Result<()>
|
|||
events: Some(vec!["push".to_owned()]),
|
||||
r#type: CreateHookOptionType::Forgejo,
|
||||
};
|
||||
client
|
||||
.repo_create_hook(ORG, REPO, hook)
|
||||
tokio::time::timeout(HTTP_TIMEOUT, client.repo_create_hook(ORG, REPO, hook))
|
||||
.await
|
||||
.map_err(anyhow::Error::from)
|
||||
.and_then(|r| r.map_err(anyhow::Error::from))
|
||||
.with_context(|| format!("create webhook for {ORG}/{REPO}"))?;
|
||||
tracing::info!(%target_url, "knowledge: push webhook created");
|
||||
Ok(())
|
||||
|
|
|
|||
Loading…
Reference in a new issue