revive: reseed applied from forge main, no proposed fallback
This commit is contained in:
parent
5d396b143e
commit
07d3d3060e
3 changed files with 96 additions and 8 deletions
|
|
@ -18,7 +18,8 @@ pub use pr_merge::{
|
|||
pub use reconcile::{reconcile_config_apply, reconcile_config_status};
|
||||
pub use repos::{
|
||||
create_agent_repo, ensure_config_repo, ensure_knowledge_repo, ensure_meta_remote, ensure_repo,
|
||||
ensure_shared_docs_repo, meta_read_access, push_config, push_meta, shared_docs_access,
|
||||
ensure_shared_docs_repo, fetch_config_main_into_applied, meta_read_access, push_config,
|
||||
push_meta, shared_docs_access,
|
||||
};
|
||||
pub use users::{core_token, ensure_user_for, provision_user_token};
|
||||
|
||||
|
|
|
|||
|
|
@ -519,6 +519,80 @@ pub async fn push_config(name: &str) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Reseed a revived agent's `applied` repo — missing its `.git` entirely,
|
||||
/// e.g. after `destroy --purge` — by fetching `agent-configs/<name>`'s
|
||||
/// `main` from the forge, [`push_config`]'s mirror target. Unlike
|
||||
/// `proposed` (seeded once at first spawn and never touched again — see
|
||||
/// `lifecycle::setup_proposed`'s own doc comment), the forge mirror is
|
||||
/// kept current after every deploy, so this reflects the agent's actual
|
||||
/// last-deployed state rather than a stale creation-time snapshot.
|
||||
///
|
||||
/// Best-effort, mirroring [`push_config`]'s own shape: returns `false`
|
||||
/// (not an error) rather than bailing when the forge is absent, the core
|
||||
/// token isn't minted yet, `applied` already has a `.git` (nothing to
|
||||
/// do), or any git step fails — callers fall back to a less-current
|
||||
/// source or the original hard error. Only `true` once `applied` is
|
||||
/// actually seeded and tagged `deployed/0`, mirroring first-spawn's own
|
||||
/// `setup_applied` seed shape exactly.
|
||||
pub async fn fetch_config_main_into_applied(name: &str) -> bool {
|
||||
if !is_present().await {
|
||||
return false;
|
||||
}
|
||||
let Some(token) = core_token() else {
|
||||
return false;
|
||||
};
|
||||
let applied = crate::paths::applied_dir(name);
|
||||
if applied.join(".git").exists() {
|
||||
return false;
|
||||
}
|
||||
if let Err(e) = std::fs::create_dir_all(&applied) {
|
||||
tracing::warn!(%name, error = ?e, "forge: applied reseed mkdir failed");
|
||||
return false;
|
||||
}
|
||||
if let Err(e) = crate::lifecycle::git(&applied, &["init", "--initial-branch=main"]).await {
|
||||
tracing::warn!(%name, error = ?e, "forge: applied reseed init failed");
|
||||
return false;
|
||||
}
|
||||
let url = forge_git_url(&format!("{CONFIG_ORG}/{name}"));
|
||||
let auth = core_auth_header(&token);
|
||||
let out = crate::lifecycle::git_command_authed(&auth)
|
||||
.current_dir(&applied)
|
||||
.args([
|
||||
"fetch",
|
||||
"--no-tags",
|
||||
"--update-head-ok",
|
||||
&url,
|
||||
"refs/heads/main:refs/heads/main",
|
||||
])
|
||||
.output()
|
||||
.await;
|
||||
match out {
|
||||
Ok(o) if o.status.success() => {}
|
||||
Ok(o) => {
|
||||
tracing::warn!(
|
||||
%name,
|
||||
stderr = %String::from_utf8_lossy(&o.stderr).trim(),
|
||||
"forge: applied reseed fetch failed"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::warn!(%name, error = ?e, "forge: applied reseed fetch failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if let Err(e) = crate::lifecycle::git_read_tree_reset(&applied, "refs/heads/main").await {
|
||||
tracing::warn!(%name, error = ?e, "forge: applied reseed read-tree failed");
|
||||
return false;
|
||||
}
|
||||
if let Err(e) = crate::lifecycle::git_tag(&applied, "deployed/0", "refs/heads/main").await {
|
||||
tracing::warn!(%name, error = ?e, "forge: applied reseed tag failed");
|
||||
return false;
|
||||
}
|
||||
tracing::info!(%name, "forge: reseeded applied repo from agent-configs main");
|
||||
true
|
||||
}
|
||||
|
||||
/// Run a single `git push <url> <refspec>` in the applied repo `dir` and
|
||||
/// return the raw output for the caller to classify. Split out so
|
||||
/// [`push_config`] can push tags and `main` as independent pushes.
|
||||
|
|
|
|||
Loading…
Reference in a new issue