feat(#1838): run_merge_config_pr handler (verify pr head, ff forge main, deploy)

This commit is contained in:
damocles 2026-06-23 11:20:38 +02:00
commit 0b86295776
3 changed files with 207 additions and 1 deletions

View file

@ -1225,6 +1225,43 @@ pub async fn pr_head_sha(repo: &str, pr: u64) -> Result<String, ForgeMergeError>
Ok(sha.to_string())
}
/// Full `owner/name` path of an agent's config repo on the forge — the
/// `agent-configs` org mirror that the PR-merge flow reads + fast-forwards.
pub fn config_repo(agent: &str) -> String {
format!("{CONFIG_ORG}/{agent}")
}
/// Fetch PR #`pr`'s head into the agent's applied repo via
/// `refs/pull/<pr>/head` (which Forgejo always serves — a bare-sha fetch can
/// be refused by uploadpack policy). This makes the reviewed head an object
/// in the applied repo so the ancestor check in [`ff_push_to_main`], the
/// `git_update_ref(main, …)` in the deploy tail, and the eval-verify all
/// resolve it locally before the irreversible push.
///
/// # Errors
/// `Other` on transport failure or a non-zero git exit.
pub async fn fetch_pr_head_into_applied(repo: &str, pr: u64) -> Result<(), ForgeMergeError> {
let token = core_token()
.ok_or_else(|| ForgeMergeError::Other(anyhow::anyhow!("forge core token absent")))?;
let url = tokenised_repo_url(repo, &token);
let applied = Coordinator::agent_applied_dir(repo_agent_name(repo));
let refspec = format!("refs/pull/{pr}/head");
let out = crate::lifecycle::git_command()
.current_dir(&applied)
.args(["fetch", "--no-tags", &url, &refspec])
.output()
.await
.context("git fetch PR head into applied")?;
if !out.status.success() {
return Err(ForgeMergeError::Other(anyhow::anyhow!(
"git fetch {repo} {refspec} into applied failed ({}): {}",
out.status,
String::from_utf8_lossy(&out.stderr).trim()
)));
}
Ok(())
}
/// Fast-forward the forge repo's `main` to `sha` — THE merge in the PR flow.
/// Reads `main`'s current sha (`git ls-remote … refs/heads/main`), verifies it
/// is a strict ancestor of `sha` (`git merge-base --is-ancestor`, run in the