wip(#1838): add MergeConfigPr approvalkind + match-site arms
This commit is contained in:
parent
4e4e9f8a60
commit
449e3fcb7b
4 changed files with 66 additions and 3 deletions
|
|
@ -128,6 +128,28 @@ pub async fn approve(coord: Arc<Coordinator>, id: i64) -> Result<()> {
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
ApprovalKind::MergeConfigPr => {
|
||||||
|
// Like ApplyCommit, the work ends in a container rebuild, so
|
||||||
|
// route it through the rebuild queue. The queue worker
|
||||||
|
// dispatches MergeConfigPr approvals to `run_merge_config_pr`
|
||||||
|
// (verify the reviewed PR head, ff the forge config repo's
|
||||||
|
// main to it, mark merged, then the shared deploy tail).
|
||||||
|
coord
|
||||||
|
.rebuild_queue
|
||||||
|
.enqueue_full(crate::rebuild_queue::FullEnqueue {
|
||||||
|
kind: crate::rebuild_queue::QueueKind::Rebuild,
|
||||||
|
agent: approval.agent.clone(),
|
||||||
|
source: crate::rebuild_queue::QueueSource::Approval,
|
||||||
|
reason: format!("approval #{id} merge config pr"),
|
||||||
|
parent_id: None,
|
||||||
|
inputs: Vec::new(),
|
||||||
|
approval_id: Some(id),
|
||||||
|
perm_payload: None,
|
||||||
|
depends_on: Vec::new(),
|
||||||
|
});
|
||||||
|
coord.emit_rebuild_queue_snapshot();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -381,6 +403,7 @@ fn finish_approval(
|
||||||
ApprovalKind::InitConfig => "init_config",
|
ApprovalKind::InitConfig => "init_config",
|
||||||
ApprovalKind::UpdateMetaInputs => "update_meta_inputs",
|
ApprovalKind::UpdateMetaInputs => "update_meta_inputs",
|
||||||
ApprovalKind::SchedulePrompt => "schedule_prompt",
|
ApprovalKind::SchedulePrompt => "schedule_prompt",
|
||||||
|
ApprovalKind::MergeConfigPr => "merge_config_pr",
|
||||||
};
|
};
|
||||||
let sha_short = approval
|
let sha_short = approval
|
||||||
.fetched_sha
|
.fetched_sha
|
||||||
|
|
@ -430,6 +453,15 @@ fn finish_approval(
|
||||||
sha: approval.fetched_sha.clone(),
|
sha: approval.fetched_sha.clone(),
|
||||||
tag: terminal_tag,
|
tag: terminal_tag,
|
||||||
}),
|
}),
|
||||||
|
// MergeConfigPr ends in a container rebuild like ApplyCommit, so
|
||||||
|
// surface the same Rebuilt lifecycle event.
|
||||||
|
ApprovalKind::MergeConfigPr => coord.notify_manager(&HelperEvent::Rebuilt {
|
||||||
|
agent: approval.agent.clone(),
|
||||||
|
ok,
|
||||||
|
note,
|
||||||
|
sha: approval.fetched_sha.clone(),
|
||||||
|
tag: terminal_tag,
|
||||||
|
}),
|
||||||
// UpdateMetaInputs / SchedulePrompt: ApprovalResolved already
|
// UpdateMetaInputs / SchedulePrompt: ApprovalResolved already
|
||||||
// carries the result. No separate lifecycle event needed.
|
// carries the result. No separate lifecycle event needed.
|
||||||
ApprovalKind::UpdateMetaInputs | ApprovalKind::SchedulePrompt => {}
|
ApprovalKind::UpdateMetaInputs | ApprovalKind::SchedulePrompt => {}
|
||||||
|
|
@ -809,6 +841,7 @@ pub async fn deny(coord: &Coordinator, id: i64, note: Option<&str>) -> Result<()
|
||||||
ApprovalKind::InitConfig => "init_config",
|
ApprovalKind::InitConfig => "init_config",
|
||||||
ApprovalKind::UpdateMetaInputs => "update_meta_inputs",
|
ApprovalKind::UpdateMetaInputs => "update_meta_inputs",
|
||||||
ApprovalKind::SchedulePrompt => "schedule_prompt",
|
ApprovalKind::SchedulePrompt => "schedule_prompt",
|
||||||
|
ApprovalKind::MergeConfigPr => "merge_config_pr",
|
||||||
};
|
};
|
||||||
let sha_short = sha.as_deref().map(|s| s[..s.len().min(12)].to_owned());
|
let sha_short = sha.as_deref().map(|s| s[..s.len().min(12)].to_owned());
|
||||||
let description = a.description.clone();
|
let description = a.description.clone();
|
||||||
|
|
|
||||||
|
|
@ -335,6 +335,7 @@ fn row_to_approval(row: &rusqlite::Row<'_>) -> rusqlite::Result<Approval> {
|
||||||
"init_config" => ApprovalKind::InitConfig,
|
"init_config" => ApprovalKind::InitConfig,
|
||||||
"update_meta_inputs" => ApprovalKind::UpdateMetaInputs,
|
"update_meta_inputs" => ApprovalKind::UpdateMetaInputs,
|
||||||
"schedule_prompt" => ApprovalKind::SchedulePrompt,
|
"schedule_prompt" => ApprovalKind::SchedulePrompt,
|
||||||
|
"merge_config_pr" => ApprovalKind::MergeConfigPr,
|
||||||
other => {
|
other => {
|
||||||
return Err(rusqlite::Error::FromSqlConversionFailure(
|
return Err(rusqlite::Error::FromSqlConversionFailure(
|
||||||
2,
|
2,
|
||||||
|
|
@ -383,6 +384,7 @@ pub(crate) fn kind_to_str(kind: ApprovalKind) -> &'static str {
|
||||||
ApprovalKind::InitConfig => "init_config",
|
ApprovalKind::InitConfig => "init_config",
|
||||||
ApprovalKind::UpdateMetaInputs => "update_meta_inputs",
|
ApprovalKind::UpdateMetaInputs => "update_meta_inputs",
|
||||||
ApprovalKind::SchedulePrompt => "schedule_prompt",
|
ApprovalKind::SchedulePrompt => "schedule_prompt",
|
||||||
|
ApprovalKind::MergeConfigPr => "merge_config_pr",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -393,6 +395,7 @@ fn kind_from_str(s: &str) -> Result<ApprovalKind> {
|
||||||
"init_config" => ApprovalKind::InitConfig,
|
"init_config" => ApprovalKind::InitConfig,
|
||||||
"update_meta_inputs" => ApprovalKind::UpdateMetaInputs,
|
"update_meta_inputs" => ApprovalKind::UpdateMetaInputs,
|
||||||
"schedule_prompt" => ApprovalKind::SchedulePrompt,
|
"schedule_prompt" => ApprovalKind::SchedulePrompt,
|
||||||
|
"merge_config_pr" => ApprovalKind::MergeConfigPr,
|
||||||
other => bail!("unknown approval kind '{other}'"),
|
other => bail!("unknown approval kind '{other}'"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -870,6 +870,7 @@ fn history_view(a: Approval) -> ApprovalHistoryView {
|
||||||
hive_sh4re::ApprovalKind::InitConfig => "init_config",
|
hive_sh4re::ApprovalKind::InitConfig => "init_config",
|
||||||
hive_sh4re::ApprovalKind::UpdateMetaInputs => "update_meta_inputs",
|
hive_sh4re::ApprovalKind::UpdateMetaInputs => "update_meta_inputs",
|
||||||
hive_sh4re::ApprovalKind::SchedulePrompt => "schedule_prompt",
|
hive_sh4re::ApprovalKind::SchedulePrompt => "schedule_prompt",
|
||||||
|
hive_sh4re::ApprovalKind::MergeConfigPr => "merge_config_pr",
|
||||||
};
|
};
|
||||||
ApprovalHistoryView {
|
ApprovalHistoryView {
|
||||||
id: a.id,
|
id: a.id,
|
||||||
|
|
@ -939,6 +940,24 @@ async fn build_approval_views(approvals: Vec<Approval>) -> Vec<ApprovalView> {
|
||||||
description: a.description,
|
description: a.description,
|
||||||
requested_at: a.requested_at,
|
requested_at: a.requested_at,
|
||||||
},
|
},
|
||||||
|
hive_sh4re::ApprovalKind::MergeConfigPr => {
|
||||||
|
// commit_ref = PR number; fetched_sha = the reviewed PR
|
||||||
|
// head. Show the head sha; the forge PR diff surface is
|
||||||
|
// a later phase (#1838 P4) — None for now.
|
||||||
|
let sha = a
|
||||||
|
.fetched_sha
|
||||||
|
.as_deref()
|
||||||
|
.map(|s| s[..s.len().min(12)].to_owned());
|
||||||
|
ApprovalView {
|
||||||
|
id: a.id,
|
||||||
|
agent: a.agent,
|
||||||
|
kind: "merge_config_pr",
|
||||||
|
sha_short: sha,
|
||||||
|
diff: None,
|
||||||
|
description: a.description,
|
||||||
|
requested_at: a.requested_at,
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
out
|
out
|
||||||
|
|
|
||||||
|
|
@ -154,10 +154,12 @@ pub struct Approval {
|
||||||
/// Kind-specific payload (git sha / inputs array / schedule
|
/// Kind-specific payload (git sha / inputs array / schedule
|
||||||
/// payload / empty). See the Approval struct doc.
|
/// payload / empty). See the Approval struct doc.
|
||||||
pub commit_ref: String,
|
pub commit_ref: String,
|
||||||
/// `ApplyCommit` only: the canonical hive-c0re-vouched sha after
|
/// The canonical hive-c0re-vouched sha. For `ApplyCommit`: the sha
|
||||||
/// the proposal fetch, tagged `proposal/<id>`. Stable for the
|
/// after the proposal fetch, tagged `proposal/<id>` (stable for the
|
||||||
/// approval's lifetime — manager amends in proposed don't change
|
/// approval's lifetime — manager amends in proposed don't change
|
||||||
/// what gets built.
|
/// what gets built). For `MergeConfigPr`: the reviewed PR head
|
||||||
|
/// pinned at submit; if the PR head drifts off it before merge,
|
||||||
|
/// hive-c0re refreshes this + re-renders the card for re-review.
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
pub fetched_sha: Option<String>,
|
pub fetched_sha: Option<String>,
|
||||||
pub requested_at: i64,
|
pub requested_at: i64,
|
||||||
|
|
@ -192,6 +194,12 @@ pub enum ApprovalKind {
|
||||||
UpdateMetaInputs,
|
UpdateMetaInputs,
|
||||||
/// Add a scheduled prompt to the broker queue.
|
/// Add a scheduled prompt to the broker queue.
|
||||||
SchedulePrompt,
|
SchedulePrompt,
|
||||||
|
/// Merge an operator-reviewed config PR: hive-c0re verifies the
|
||||||
|
/// reviewed PR head, fast-forwards the forge config repo's `main`
|
||||||
|
/// to it, marks the PR merged, then runs the same deploy tail as
|
||||||
|
/// `ApplyCommit`. `commit_ref` = PR number; `fetched_sha` = the
|
||||||
|
/// reviewed PR head pinned at submit. See `docs/approvals.md`.
|
||||||
|
MergeConfigPr,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue