missions: fix repo checkout for retries + tokenize git.redclaw.dev clones
- mission_orchestrator: run ensure_checkout BEFORE the team_id short-circuit. Previously, a re-launched or retried mission bailed out at the team_id=already-bound guard and skipped repo checkout entirely, so agents ran against an empty workspace. - mission_workspace: inject GITEA_TOKEN into git.redclaw.dev URLs so clone auth works from the server container. Redact any token echoed back on failure. - refresh buttons on MissionCanvas + MissionsList now spin the icon while loading so clicks are visibly acknowledged. - refresh-spinner keyframe added to motion.css. Requires operator on gw-04: sudo chown 65532:65532 /var/lib/clawmates-missions (applied 2026-07-21 pre-commit).
This commit is contained in:
@@ -39,6 +39,7 @@ pub async fn on_launch(
|
||||
mission_id: Uuid,
|
||||
node_hub: Option<std::sync::Arc<crate::fleet::NodeHub>>,
|
||||
) -> Result<Option<Uuid>, String> {
|
||||
eprintln!("mission_orchestrator::on_launch fired mission_id={mission_id}");
|
||||
let Some(mission) = cm_db::repo::missions::get(pool, mission_id, workspace_id.as_uuid())
|
||||
.await
|
||||
.map_err(|e| format!("load mission: {e}"))?
|
||||
@@ -46,8 +47,29 @@ pub async fn on_launch(
|
||||
return Err("mission not found".into());
|
||||
};
|
||||
|
||||
// Skip if already bound.
|
||||
// ensure_checkout is idempotent (fetch+reset on existing clones,
|
||||
// clone on missing dirs) so we run it BEFORE the team_id short-
|
||||
// circuit: a re-launched or retried mission still needs a fresh
|
||||
// repo checkout even though its team was minted on the first
|
||||
// launch. Non-fatal — logs and continues on failure.
|
||||
match crate::mission_workspace::ensure_checkout(pool, workspace_id, mission_id).await {
|
||||
Ok(Some(path)) => eprintln!(
|
||||
"mission_orchestrator: repo checked out at {} for mission {mission_id}",
|
||||
path.display()
|
||||
),
|
||||
Ok(None) => eprintln!(
|
||||
"mission_orchestrator: mission {mission_id} has no repo bound, skipping checkout"
|
||||
),
|
||||
Err(e) => eprintln!(
|
||||
"mission_orchestrator: repo checkout for {mission_id} failed (continuing): {e}"
|
||||
),
|
||||
}
|
||||
|
||||
// Skip team materialization if already bound.
|
||||
if mission.team_id.is_some() {
|
||||
eprintln!(
|
||||
"mission_orchestrator::on_launch team_id already bound for mission_id={mission_id} — skipping team materialization"
|
||||
);
|
||||
return Ok(mission.team_id);
|
||||
}
|
||||
|
||||
@@ -139,24 +161,6 @@ pub async fn on_launch(
|
||||
.await
|
||||
.map_err(|e| format!("bind team on mission: {e}"))?;
|
||||
|
||||
// Ensure the mission's repo is checked out at
|
||||
// $CLAWMATES_MISSIONS_ROOT/{mission_id}/repo — where
|
||||
// security_scan + benchmark_runner exec against. Non-fatal:
|
||||
// missions without a repo (research_only, custom) skip cleanly,
|
||||
// and clone failures log without blocking launch (the operator
|
||||
// sees the error on the canvas via the run's failed status when
|
||||
// a repo-dependent phase tries to fire).
|
||||
match crate::mission_workspace::ensure_checkout(pool, workspace_id, mission_id).await {
|
||||
Ok(Some(path)) => eprintln!(
|
||||
"mission_orchestrator: repo checked out at {}",
|
||||
path.display()
|
||||
),
|
||||
Ok(None) => {}
|
||||
Err(e) => eprintln!(
|
||||
"mission_orchestrator: repo checkout for {mission_id} failed (continuing): {e}"
|
||||
),
|
||||
}
|
||||
|
||||
// Herdr second-runtime: if runtime_kind='local_herdr', spawn a
|
||||
// pane on target_node running the first available local CLI.
|
||||
// Non-fatal on failure — the operator sees the error in server
|
||||
|
||||
Reference in New Issue
Block a user