Skip to content

Commit 56be136

Browse files
committed
feat: add multi-host netrc auth
1 parent e30f122 commit 56be136

File tree

6 files changed

+53
-84
lines changed

6 files changed

+53
-84
lines changed

.agents/codebase-insights.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
- Tests must call `VCSRepo.new(repo).checkout_branch('feat')` after `run_agent_task()` calls
1111

1212
## Token Usage
13-
- Uses GITHUB_TOKEN (not GITHUB_ACCESS_TOKEN) consistently across the codebase
13+
- Authentication for GitHub, GitLab and BitBucket is handled via `~/.netrc` which
14+
is configured during `codex-setup` if the respective `*_TOKEN` environment
15+
variables are present. The token is no longer injected in remote URLs.
1416

1517
## EXTRAS Framework
1618
- Ruby-based component installation system via `bin/install-extras`
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
In several places, we support only GitHub. (Do a case insensitive grep for GitHub).
2+
3+
Try to extend the logic to add support for GitLab and BitBucket.
4+
5+
Instead of using http auth directly supplied in the URL, let’s set up a netrc file during the codex-setup phase which would allow us to authenticate in front of these services with regular URLs

codex-setup

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,22 @@ else
1313
GET_TASK_CMD="get-task"
1414
fi
1515

16-
# TODO: Support GitLab and BitBucket
16+
# Configure ~/.netrc for Git hosting services
17+
NETRC_CONTENT=""
18+
if [ -n "${GITHUB_TOKEN}" ]; then
19+
NETRC_CONTENT+=$'machine github.com\n login x-access-token\n password '${GITHUB_TOKEN}$'\n'
20+
fi
21+
if [ -n "${GITLAB_TOKEN}" ]; then
22+
NETRC_CONTENT+=$'machine gitlab.com\n login oauth2\n password '${GITLAB_TOKEN}$'\n'
23+
fi
24+
if [ -n "${BITBUCKET_TOKEN}" ]; then
25+
NETRC_CONTENT+=$'machine bitbucket.org\n login x-token-auth\n password '${BITBUCKET_TOKEN}$'\n'
26+
fi
27+
if [ -n "$NETRC_CONTENT" ]; then
28+
echo "Configuring ~/.netrc for git authentication"
29+
printf "%s" "$NETRC_CONTENT" > "$HOME/.netrc"
30+
chmod 600 "$HOME/.netrc"
31+
fi
1732

1833
cat > ../AGENTS.md << EOF
1934
When you a given a task description or developer instructions that

docs/devcontainer-setup.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ export OPENAI_API_KEY="your-openai-api-key"
1010
export OPENAI_ORG_ID="your-org-id" # Optional
1111
```
1212

13-
### GitHub Integration
13+
### Git Hosting Integration
14+
Set tokens for any providers you intend to push to. The setup script will create
15+
a `~/.netrc` file from these values.
1416
```bash
15-
export GITHUB_TOKEN="your-github-token"
17+
export GITHUB_TOKEN="your-github-token" # Optional
18+
export GITLAB_TOKEN="your-gitlab-token" # Optional
19+
export BITBUCKET_TOKEN="your-bitbucket-token" # Optional
1620
```
1721

1822
## Setting Environment Variables
@@ -22,13 +26,17 @@ Add to your `~/.bashrc`, `~/.zshrc`, or equivalent:
2226
```bash
2327
export OPENAI_API_KEY="sk-..."
2428
export GITHUB_TOKEN="ghp_..."
29+
export GITLAB_TOKEN="glpat-..."
30+
export BITBUCKET_TOKEN="bbt_..."
2531
```
2632

2733
### Windows
2834
Using PowerShell:
2935
```powershell
3036
$env:OPENAI_API_KEY = "sk-..."
3137
$env:GITHUB_TOKEN = "ghp_..."
38+
$env:GITLAB_TOKEN = "glpat-..."
39+
$env:BITBUCKET_TOKEN = "bbt_..."
3240
```
3341

3442
Or set permanently via System Properties > Environment Variables.

lib/agent_tasks.rb

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,7 @@ def git_details
6565
target_branch = branch_match[1].strip
6666
raise StandardError, 'Error: Start-Agent-Branch is empty in commit message' if target_branch.empty?
6767

68-
if target_remote.start_with?('https://github.com/')
69-
github_token = ENV.fetch('GITHUB_TOKEN', nil)
70-
unless github_token
71-
raise StandardError,
72-
'Error: The Codex environment must be configured with a GITHUB_TOKEN, specified as a secret'
73-
end
74-
75-
remote_url = target_remote.sub('https://github.com/', "https://x-access-token:#{github_token}@github.com/")
76-
else
77-
remote_url = target_remote
78-
end
79-
80-
{ remote_url: remote_url, push_branch: target_branch }
68+
{ remote_url: target_remote, push_branch: target_branch }
8169
end
8270

8371
def prepare_work_environment

test/test_commit_message_format.rb

Lines changed: 18 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -80,31 +80,17 @@ def test_agent_tasks_extraction_with_remote_and_branch
8080
vcs_repo.checkout_branch('extract-test')
8181
agent_tasks = AgentTasks.new(repo)
8282

83-
# Save original token and set test token
84-
original_token = ENV.fetch('GITHUB_TOKEN', nil)
85-
86-
begin
87-
ENV['GITHUB_TOKEN'] = 'test_token_123'
88-
# Test autopush message generation
89-
message = agent_tasks.agent_prompt(autopush: true)
90-
91-
assert_includes message, 'extraction test task'
92-
assert_includes message, 'git remote add target_remote "https://x-access-token:[email protected]/testuser/test-repo.git"'
93-
assert_includes message, 'git push target_remote HEAD:extract-test'
94-
ensure
95-
# Restore original token
96-
if original_token
97-
ENV['GITHUB_TOKEN'] = original_token
98-
else
99-
ENV.delete('GITHUB_TOKEN')
100-
end
101-
end
83+
# Autopush message generation should not embed credentials
84+
message = agent_tasks.agent_prompt(autopush: true)
85+
assert_includes message, 'extraction test task'
86+
assert_includes message, 'git remote add target_remote "https://github.com/testuser/test-repo.git"'
87+
assert_includes message, 'git push target_remote HEAD:extract-test'
10288
ensure
10389
FileUtils.remove_entry(repo) if repo && File.exist?(repo)
10490
FileUtils.remove_entry(remote) if remote && File.exist?(remote)
10591
end
10692

107-
def test_agent_tasks_autopush_requires_github_token
93+
def test_agent_tasks_autopush_without_token
10894
repo, remote = setup_repo(:git)
10995

11096
# Set up HTTPS remote
@@ -119,34 +105,12 @@ def test_agent_tasks_autopush_requires_github_token
119105
vcs_repo.checkout_branch('token-test')
120106
agent_tasks = AgentTasks.new(repo)
121107

122-
# Save original token
123-
original_token = ENV.fetch('GITHUB_TOKEN', nil)
124-
125-
begin
126-
# Test with missing token
127-
ENV.delete('GITHUB_TOKEN')
128-
error = assert_raises(StandardError) do
129-
agent_tasks.agent_prompt(autopush: true)
130-
end
131-
assert_includes error.message,
132-
'The Codex environment must be configured with a GITHUB_TOKEN, ' \
133-
'specified as a secret'
134-
135-
# Test with token present
136-
ENV['GITHUB_TOKEN'] = 'test_token_123'
137-
message = agent_tasks.agent_prompt(autopush: true)
138-
assert_includes message, 'git remote add target_remote "https://x-access-token:[email protected]/testuser/test-repo.git"'
139-
assert_includes message, 'git push target_remote HEAD:token-test'
140-
ensure
141-
# Restore original token
142-
if original_token
143-
ENV['GITHUB_TOKEN'] = original_token
144-
else
145-
ENV.delete('GITHUB_TOKEN')
146-
end
147-
FileUtils.remove_entry(repo) if repo && File.exist?(repo)
148-
FileUtils.remove_entry(remote) if remote && File.exist?(remote)
149-
end
108+
message = agent_tasks.agent_prompt(autopush: true)
109+
assert_includes message, 'git remote add target_remote "https://github.com/testuser/test-repo.git"'
110+
assert_includes message, 'git push target_remote HEAD:token-test'
111+
ensure
112+
FileUtils.remove_entry(repo) if repo && File.exist?(repo)
113+
FileUtils.remove_entry(remote) if remote && File.exist?(remote)
150114
end
151115

152116
def test_agent_tasks_autopush_errors_on_missing_commit_data
@@ -163,25 +127,12 @@ def test_agent_tasks_autopush_errors_on_missing_commit_data
163127

164128
agent_tasks = AgentTasks.new(repo)
165129

166-
# Save original token and set test token
167-
original_token = ENV.fetch('GITHUB_TOKEN', nil)
168-
ENV['GITHUB_TOKEN'] = 'test_token_123'
169-
170-
begin
171-
# Should raise error because commit doesn't have Target-Remote
172-
error = assert_raises(StandardError) do
173-
agent_tasks.agent_prompt(autopush: true)
174-
end
175-
assert_includes error.message, 'You are not currently on a agent task branch'
176-
ensure
177-
# Restore original token
178-
if original_token
179-
ENV['GITHUB_TOKEN'] = original_token
180-
else
181-
ENV.delete('GITHUB_TOKEN')
182-
end
183-
FileUtils.remove_entry(repo) if repo && File.exist?(repo)
184-
FileUtils.remove_entry(remote) if remote && File.exist?(remote)
130+
error = assert_raises(StandardError) do
131+
agent_tasks.agent_prompt(autopush: true)
185132
end
133+
assert_includes error.message, 'You are not currently on a agent task branch'
134+
ensure
135+
FileUtils.remove_entry(repo) if repo && File.exist?(repo)
136+
FileUtils.remove_entry(remote) if remote && File.exist?(remote)
186137
end
187138
end

0 commit comments

Comments
 (0)