From f1bcd41ad9573ed10111a11b888237da384fa1d9 Mon Sep 17 00:00:00 2001 From: Hare Date: Thu, 3 Sep 2026 15:05:30 +0900 Subject: [PATCH] fix: route embedded repository ref observation --- crates/worker-runtime/src/runtime.rs | 7 ++ crates/workspace-server/src/hosts.rs | 101 +++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/crates/worker-runtime/src/runtime.rs b/crates/worker-runtime/src/runtime.rs index d085d2ca..f9373607 100644 --- a/crates/worker-runtime/src/runtime.rs +++ b/crates/worker-runtime/src/runtime.rs @@ -404,6 +404,13 @@ impl Runtime { { self.resolve_repository_access_resource(ssh).await?; } + self.observe_repository_ref(request) + } + + pub fn observe_repository_ref( + &self, + request: RepositoryRefObservationRequest, + ) -> Result { let backend = { let state = self.lock()?; state.ensure_running()?; diff --git a/crates/workspace-server/src/hosts.rs b/crates/workspace-server/src/hosts.rs index f4419e63..ecc93702 100644 --- a/crates/workspace-server/src/hosts.rs +++ b/crates/workspace-server/src/hosts.rs @@ -2179,6 +2179,28 @@ impl WorkspaceWorkerRuntime for EmbeddedWorkerRuntime { } } + fn observe_repository_ref( + &self, + request: RepositoryRefObservationRequest, + ) -> std::result::Result { + self.runtime + .observe_repository_ref(request) + .map_err(|error| match error { + worker_runtime::error::RuntimeError::WorkingDirectory(diagnostic) => { + Error::RuntimeOperationFailed { + runtime_id: self.runtime_id.clone(), + code: diagnostic.code, + message: diagnostic.message, + } + } + error => Error::RuntimeOperationFailed { + runtime_id: self.runtime_id.clone(), + code: "repository_ref_provider_unavailable".to_string(), + message: error.to_string(), + }, + }) + } + fn list_working_directories(&self) -> RuntimeList { RuntimeList::new(Vec::new(), Vec::new()) } @@ -4838,6 +4860,85 @@ mod tests { } } + struct ObservingExecutionBackend { + response: RepositoryRefObservation, + observed: Arc>>, + } + + impl worker_runtime::execution::WorkerExecutionBackend for ObservingExecutionBackend { + fn backend_id(&self) -> &str { + "repository-observation-test-backend" + } + + fn spawn_worker( + &self, + _request: worker_runtime::execution::WorkerExecutionSpawnRequest, + ) -> worker_runtime::execution::WorkerExecutionSpawnResult { + unreachable!("Repository observation test does not spawn Workers") + } + + fn dispatch_input( + &self, + _handle: &worker_runtime::execution::WorkerExecutionHandle, + _input: EmbeddedWorkerInput, + ) -> worker_runtime::execution::WorkerExecutionResult { + unreachable!("Repository observation test does not dispatch Worker input") + } + + fn observe_repository_ref( + &self, + request: &RepositoryRefObservationRequest, + ) -> Result< + RepositoryRefObservation, + worker_runtime::working_directory::WorkingDirectoryDiagnostic, + > { + self.observed.lock().unwrap().push(request.clone()); + Ok(self.response.clone()) + } + } + + #[test] + fn embedded_runtime_forwards_repository_ref_observation_to_execution_backend() { + let observed = Arc::new(Mutex::new(Vec::new())); + let expected = RepositoryRefObservation { + repository_id: "repository-1".to_string(), + source_revision: 7, + source_fingerprint: "sha256:source".to_string(), + selector: "refs/heads/published".to_string(), + revision_ref: "0123456789012345678901234567890123456789".to_string(), + observed_at_epoch_seconds: 42, + }; + let runtime = EmbeddedWorkerRuntime::new_memory_with_execution_backend( + "workspace-test", + Arc::new(ObservingExecutionBackend { + response: expected.clone(), + observed: observed.clone(), + }), + ) + .unwrap(); + let request = RepositoryRefObservationRequest { + repository: worker_runtime::catalog::WorkingDirectoryRepository { + id: "repository-1".to_string(), + provider: "git".to_string(), + source: workspace_api::RepositorySource { + kind: workspace_api::RepositorySourceKind::LocalPath, + uri: "/provider/repository.git".to_string(), + }, + source_revision: 7, + source_fingerprint: "sha256:source".to_string(), + selector: None, + }, + selector: "refs/heads/published".to_string(), + materialization: None, + }; + + assert_eq!( + runtime.observe_repository_ref(request.clone()).unwrap(), + expected + ); + assert_eq!(observed.lock().unwrap().as_slice(), &[request]); + } + #[derive(Default)] struct AcceptingExecutionBackend { contexts: