diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 95f65f452..1195b0308 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -82,8 +82,16 @@ jobs: - name: cargo clippy run: cargo clippy --target ${{ matrix.target }} --all-features -- -D warnings + # Build mock-acp-agent to a known location for E2E tests + - name: Build mock-acp-agent + run: | + mkdir -p target/mock-acp-out + cargo +nightly build -p mock-acp-agent --profile ci-test --target ${{ matrix.target }} --artifact-dir target/mock-acp-out -Z unstable-options + - name: cargo test # continue-on-error: true # TODO: Fix pre-existing test failures in codex-app-server + env: + MOCK_ACP_AGENT_BIN: ${{ github.workspace }}/codex-rs/target/mock-acp-out/mock_acp_agent run: cargo test --profile ci-test --target ${{ matrix.target }} --all-features # Save cargo home cache diff --git a/codex-rs/acp/src/registry.rs b/codex-rs/acp/src/registry.rs index 32ed71421..e197ec825 100644 --- a/codex-rs/acp/src/registry.rs +++ b/codex-rs/acp/src/registry.rs @@ -65,24 +65,40 @@ pub fn get_agent_config(model_name: &str) -> Result { match normalized.as_str() { "mock-model" => { - // Use full path to mock_acp_agent binary from target directory - // This handles both debug and release builds - let exe_path = match std::env::current_exe() { - Ok(p) => { - let mock_path = p - .parent() - .map(|parent| parent.join("mock_acp_agent")) - .unwrap_or_else(|| std::path::PathBuf::from("mock_acp_agent")); - tracing::debug!("Mock ACP agent path resolved to: {}", mock_path.display()); - mock_path - } - Err(e) => { - tracing::warn!( - "Failed to get current_exe for mock-model: {}, falling back to 'mock_acp_agent'", - e - ); - std::path::PathBuf::from("mock_acp_agent") - } + // Resolve path to mock_acp_agent binary. + // + // Priority: + // 1. MOCK_ACP_AGENT_BIN environment variable (set by CI) + // 2. Relative to current executable (for local development) + let exe_path = if let Ok(env_path) = std::env::var("MOCK_ACP_AGENT_BIN") { + tracing::debug!("Mock ACP agent path from MOCK_ACP_AGENT_BIN: {}", env_path); + std::path::PathBuf::from(env_path) + } else { + // Fall back to resolving relative to current executable. + // This handles both: + // - Running as `codex` binary: target/{profile}/codex -> target/{profile}/ + // - Running as test binary: target/{profile}/deps/test -> target/{profile}/ + let mock_path = std::env::current_exe() + .ok() + .and_then(|p| { + p.parent().map(|parent| { + // Check if we're in a "deps" directory (test binary context) + let in_deps_dir = parent + .file_name() + .map(|name| name == "deps") + .unwrap_or(false); + + if in_deps_dir { + parent.parent().map(|p| p.join("mock_acp_agent")) + } else { + Some(parent.join("mock_acp_agent")) + } + }) + }) + .flatten() + .unwrap_or_else(|| std::path::PathBuf::from("mock_acp_agent")); + tracing::debug!("Mock ACP agent path resolved to: {}", mock_path.display()); + mock_path }; Ok(AcpAgentConfig {