Skip to content

Commit d4d834e

Browse files
authored
Merge branch 'main' into fix/611-linear-setup-webhook-secret
2 parents dc1e987 + 9549473 commit d4d834e

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
@@ -5,7 +5,6 @@
55
import asyncio
66
import hashlib
77
import os
8-
import subprocess
98
import sys
109
import time
1110
from typing import TYPE_CHECKING
@@ -822,19 +821,17 @@ def _on_trace_truncated(max_bytes: int, first_dropped: int) -> None:
822821
system_prompt_overrides=system_prompt_overrides,
823822
)
824823

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

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)