Skip to content

Commit f5e4bba

Browse files
authored
Merge branch 'main' into pr/ecs-substrate-hardening
2 parents 88e0ac8 + 9549473 commit f5e4bba

2 files changed

Lines changed: 84 additions & 14 deletions

File tree

agent/src/pipeline.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import hashlib
77
import inspect
88
import os
9-
import subprocess
109
import sys
1110
import time
1211
from typing import TYPE_CHECKING
@@ -823,19 +822,17 @@ def _on_trace_truncated(max_bytes: int, first_dropped: int) -> None:
823822
system_prompt_overrides=system_prompt_overrides,
824823
)
825824

826-
# Configure git and gh auth before setup_repo() uses them
827-
subprocess.run(
828-
["git", "config", "--global", "user.name", "bgagent"],
829-
check=True,
830-
capture_output=True,
831-
timeout=60,
832-
)
833-
subprocess.run(
834-
["git", "config", "--global", "user.email", "bgagent@noreply.github.com"],
835-
check=True,
836-
capture_output=True,
837-
timeout=60,
838-
)
825+
# Configure git identity and gh auth before setup_repo() uses them.
826+
# Use GIT_AUTHOR_*/GIT_COMMITTER_* env vars rather than
827+
# `git config --global`: git honors these for every commit (inherited
828+
# by Claude Code and the safety-net commit in post_hooks) WITHOUT
829+
# writing to any on-disk config. `--global` would clobber the real
830+
# ~/.gitconfig — harmless in the ephemeral container, but destructive
831+
# when this pipeline runs on a developer workstation (#622).
832+
os.environ["GIT_AUTHOR_NAME"] = "bgagent"
833+
os.environ["GIT_AUTHOR_EMAIL"] = "bgagent@noreply.github.com"
834+
os.environ["GIT_COMMITTER_NAME"] = "bgagent"
835+
os.environ["GIT_COMMITTER_EMAIL"] = "bgagent@noreply.github.com"
839836
os.environ["GITHUB_TOKEN"] = config.github_token
840837
os.environ["GH_TOKEN"] = config.github_token
841838

agent/tests/test_pipeline.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Unit tests for pipeline.py — cedar_policies injection and pure helpers."""
22

3+
import os
34
from unittest.mock import MagicMock, patch
45

56
import pytest
@@ -142,6 +143,78 @@ async def fake_run_agent(_prompt, _system_prompt, config, cwd=None, trajectory=N
142143
assert captured_config is not None
143144
assert captured_config.cedar_policies == []
144145

146+
@patch("runner.run_agent")
147+
@patch("pipeline.build_system_prompt")
148+
@patch("pipeline.discover_project_config")
149+
@patch("repo.setup_repo")
150+
@patch("pipeline.task_span")
151+
@patch("pipeline.task_state")
152+
def test_git_identity_uses_env_vars_not_global_config(
153+
self,
154+
_mock_task_state,
155+
mock_task_span,
156+
mock_setup_repo,
157+
_mock_discover,
158+
_mock_build_prompt,
159+
mock_run_agent,
160+
monkeypatch,
161+
):
162+
"""Git identity is set via GIT_AUTHOR/COMMITTER env vars, never
163+
`git config --global`, so a developer's ~/.gitconfig is never
164+
clobbered when the pipeline runs on a workstation (#622)."""
165+
monkeypatch.setenv("GITHUB_TOKEN", "ghp_test")
166+
monkeypatch.setenv("AWS_REGION", "us-east-1")
167+
# Ensure a clean slate so the assertion proves the pipeline set them.
168+
for var in (
169+
"GIT_AUTHOR_NAME",
170+
"GIT_AUTHOR_EMAIL",
171+
"GIT_COMMITTER_NAME",
172+
"GIT_COMMITTER_EMAIL",
173+
):
174+
monkeypatch.delenv(var, raising=False)
175+
176+
mock_setup_repo.return_value = RepoSetup(
177+
repo_dir="/workspace/repo",
178+
branch="bgagent/test/branch",
179+
build_before=True,
180+
)
181+
182+
async def fake_run_agent(_prompt, _system_prompt, config, cwd=None, trajectory=None):
183+
return AgentResult(status="success", turns=1, cost_usd=0.01, num_turns=1)
184+
185+
mock_run_agent.side_effect = fake_run_agent
186+
187+
mock_span = MagicMock()
188+
mock_span.__enter__ = MagicMock(return_value=mock_span)
189+
mock_span.__exit__ = MagicMock(return_value=False)
190+
mock_task_span.return_value = mock_span
191+
192+
with (
193+
patch("pipeline.ensure_committed", return_value=False),
194+
patch("pipeline.verify_build", return_value=True),
195+
patch("pipeline.verify_lint", return_value=True),
196+
patch(
197+
"pipeline.ensure_pr",
198+
return_value="https://github.com/org/repo/pull/1",
199+
),
200+
patch("pipeline.get_disk_usage", return_value=0),
201+
patch("pipeline.print_metrics"),
202+
):
203+
from pipeline import run_task
204+
205+
run_task(
206+
repo_url="owner/repo",
207+
task_description="fix bug",
208+
github_token="ghp_test",
209+
aws_region="us-east-1",
210+
task_id="test-id",
211+
)
212+
213+
assert os.environ["GIT_AUTHOR_NAME"] == "bgagent"
214+
assert os.environ["GIT_AUTHOR_EMAIL"] == "bgagent@noreply.github.com"
215+
assert os.environ["GIT_COMMITTER_NAME"] == "bgagent"
216+
assert os.environ["GIT_COMMITTER_EMAIL"] == "bgagent@noreply.github.com"
217+
145218

146219
class TestRepoLessPipeline:
147220
"""#248 Phase 3: a repo-less workflow runs the agent with no clone/build/PR."""

0 commit comments

Comments
 (0)