From 0bfe47458cef81a3d3a9b1613142a09af2652502 Mon Sep 17 00:00:00 2001 From: damocles Date: Tue, 14 Jul 2026 18:38:42 +0200 Subject: [PATCH] fix(#2401): mirror config-pr deploy tag to forge via push_config --- hive-c0re/src/actions.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/hive-c0re/src/actions.rs b/hive-c0re/src/actions.rs index d95e588a..5a6bcc45 100644 --- a/hive-c0re/src/actions.rs +++ b/hive-c0re/src/actions.rs @@ -184,10 +184,12 @@ pub async fn run_approval_apply_commit( /// the PR-based config flow's counterpart to `run_approval_apply_commit`. /// Re-fetches the approval row, runs the merge pipeline, and fires /// `ApprovalResolved` + the `Rebuilt` lifecycle event via `finish_approval`. -/// Unlike the apply-commit path it does NOT call `push_config` afterwards: -/// `run_merge_config_pr` already fast-forwarded the forge repo's `main` to -/// the reviewed head (that IS the merge), so a mirror push would be a no-op. -/// A `MergeConfigPr` is never a first spawn (the agent already exists). +/// `run_merge_config_pr` already fast-forwarded the forge repo's `main` to the +/// reviewed head (that IS the merge), so `push_config`'s `main` refspec is a +/// no-op — but it still mirrors the `deployed/` / `failed/` tag the +/// deploy tail plants onto the merged sha, giving the merged commit a +/// forge-visible deploy marker. A `MergeConfigPr` is never a first spawn (the +/// agent already exists). pub async fn run_approval_merge_config_pr( coord: &Arc, queue_entry_id: Option, @@ -199,6 +201,15 @@ pub async fn run_approval_merge_config_pr( coord.set_queue_step(queue_entry_id, "merge config pr"); let (result, terminal_tag) = run_merge_config_pr(coord, &approval, &agent_dir, &applied_dir, queue_entry_id).await; + // Mirror the deploy bookkeeping tag (`deployed/` or `failed/`) the + // deploy tail planted onto the merged sha to the forge config repo, so the + // merged commit carries a forge-visible deploy marker. `main` is already + // ff'd by the merge, so only the tag refspec actually lands; best-effort, + // never fails the approval. + coord.set_queue_step(queue_entry_id, "forge push"); + if let Err(e) = crate::forge::push_config(&approval.agent).await { + tracing::warn!(agent = %approval.agent, error = ?e, "forge: push_config after merge failed"); + } finish_approval(coord, &approval, result, terminal_tag, false) }