diff --git a/cmd/roborev/ghaction.go b/cmd/roborev/ghaction.go index 4a365bc3..92a3fa3c 100644 --- a/cmd/roborev/ghaction.go +++ b/cmd/roborev/ghaction.go @@ -65,10 +65,19 @@ After generating the workflow, add repository secrets ` + // List required secrets per agent infos := ghaction.AgentSecrets(cfg.Agents) for i, info := range infos { - fmt.Printf( - " %d. Add a repository secret "+ - "named %q (%s API key)\n", - i+1, info.SecretName, info.Name) + if info.Name == "opencode" { + fmt.Printf( + " %d. Add a repository secret "+ + "named %q (default for "+ + "opencode; change if using "+ + "a different provider)\n", + i+1, info.SecretName) + } else { + fmt.Printf( + " %d. Add a repository secret "+ + "named %q (%s API key)\n", + i+1, info.SecretName, info.Name) + } fmt.Printf( " gh secret set %s\n", info.SecretName) diff --git a/internal/ghaction/ghaction.go b/internal/ghaction/ghaction.go index 59e3b28f..b875291e 100644 --- a/internal/ghaction/ghaction.go +++ b/internal/ghaction/ghaction.go @@ -85,6 +85,8 @@ func AgentEnvVar(agentName string) string { switch agentName { case "claude-code": return "ANTHROPIC_API_KEY" + case "opencode": + return "ANTHROPIC_API_KEY" case "gemini": return "GOOGLE_API_KEY" case "copilot": @@ -253,8 +255,14 @@ var workflowTemplate = `# roborev CI Review # # Required setup: {{- range .EnvEntries }} +{{- if eq .Name "opencode" }} +# - Add a repository secret named "{{ .SecretName }}" (default for opencode). +# If you use a different model provider, replace with the appropriate key +# (e.g., OPENAI_API_KEY, GOOGLE_API_KEY) and update the env block below. +{{- else }} # - Add a repository secret named "{{ .SecretName }}" with your {{ .Name }} API key {{- end }} +{{- end }} # # Review behavior (types, reasoning, severity) is configured in # .roborev.toml under the [ci] section. diff --git a/internal/ghaction/ghaction_test.go b/internal/ghaction/ghaction_test.go index 2d49372a..3947fe01 100644 --- a/internal/ghaction/ghaction_test.go +++ b/internal/ghaction/ghaction_test.go @@ -199,18 +199,34 @@ func TestGenerate(t *testing.T) { "@openai/codex@latest", }, }, + { + name: "opencode uses ANTHROPIC_API_KEY", + cfg: WorkflowConfig{ + Agents: []string{"opencode"}, + }, + wantStrs: []string{ + "opencode-ai/opencode@latest", + "ANTHROPIC_API_KEY", + "different model provider", + }, + envChecks: func(t *testing.T, env map[string]string) { + if _, ok := env["ANTHROPIC_API_KEY"]; !ok { + t.Error("expected ANTHROPIC_API_KEY in env") + } + }, + }, { name: "dedupes env vars", cfg: WorkflowConfig{ - Agents: []string{"codex", "opencode"}, + Agents: []string{"claude-code", "opencode"}, }, wantStrs: []string{ - "@openai/codex@latest", + "@anthropic-ai/claude-code@latest", "opencode-ai/opencode@latest", }, envChecks: func(t *testing.T, env map[string]string) { - if _, ok := env["OPENAI_API_KEY"]; !ok { - t.Error("expected OPENAI_API_KEY in env") + if _, ok := env["ANTHROPIC_API_KEY"]; !ok { + t.Error("expected ANTHROPIC_API_KEY in env") } }, }, @@ -262,12 +278,12 @@ func TestGenerate(t *testing.T) { lines := strings.Split(out, "\n") envDefCount := 0 for _, line := range lines { - if strings.HasPrefix(strings.TrimSpace(line), "OPENAI_API_KEY:") { + if strings.HasPrefix(strings.TrimSpace(line), "ANTHROPIC_API_KEY:") { envDefCount++ } } if envDefCount != 1 { - t.Errorf("expected 1 OPENAI_API_KEY: definition, got %d", envDefCount) + t.Errorf("expected 1 ANTHROPIC_API_KEY: definition, got %d", envDefCount) } } } @@ -453,7 +469,7 @@ func TestAgentEnvVar(t *testing.T) { {"claude-code", "ANTHROPIC_API_KEY"}, {"gemini", "GOOGLE_API_KEY"}, {"copilot", "GITHUB_TOKEN"}, - {"opencode", "OPENAI_API_KEY"}, + {"opencode", "ANTHROPIC_API_KEY"}, {"droid", "OPENAI_API_KEY"}, } for _, tt := range tests { @@ -482,10 +498,16 @@ func TestAgentSecrets(t *testing.T) { wantVars: []string{"OPENAI_API_KEY"}, }, { - name: "dedupes by env var", + name: "codex and opencode have separate keys", agents: []string{"codex", "opencode"}, + wantLen: 2, + wantVars: []string{"OPENAI_API_KEY", "ANTHROPIC_API_KEY"}, + }, + { + name: "dedupes by env var", + agents: []string{"claude-code", "opencode"}, wantLen: 1, - wantVars: []string{"OPENAI_API_KEY"}, + wantVars: []string{"ANTHROPIC_API_KEY"}, }, { name: "multi env var",