mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-09 22:31:08 +00:00
docs: Add GitHub Actions workflow documentation
- Removed workflow files due to GitHub App restrictions - Added documentation for manual workflow installation - Workflow files need to be added manually by repository maintainer
This commit is contained in:
parent
436d034d95
commit
9406c15f5d
5 changed files with 142 additions and 703 deletions
135
.github/scripts/README.md
vendored
135
.github/scripts/README.md
vendored
|
|
@ -1,135 +0,0 @@
|
|||
# RooCode Agent - GitHub Actions Bot
|
||||
|
||||
This directory contains the RooCode Agent bot that runs in GitHub Actions to automatically handle issues and pull requests.
|
||||
|
||||
## Features
|
||||
|
||||
The RooCode Agent bot supports the following commands:
|
||||
|
||||
### Issue Commands
|
||||
|
||||
- `/roo` - General command to interact with the bot
|
||||
- `/roo plan` - Create a detailed implementation plan for an issue
|
||||
- `/roo approve` - Approve a plan and start implementation
|
||||
- `/roo fix` - Directly implement a fix for an issue
|
||||
- `/roo triage` - Analyze and triage an issue (priority, labels, complexity)
|
||||
- `/roo label` - Automatically add appropriate labels to an issue
|
||||
|
||||
### Pull Request Commands
|
||||
|
||||
- `/roo review` - Perform a code review on a pull request
|
||||
- `/roo` - General interaction with the bot on PRs
|
||||
|
||||
## Setup Instructions
|
||||
|
||||
### 1. Repository Secrets
|
||||
|
||||
Configure the following secrets in your repository settings (`Settings > Secrets and variables > Actions`):
|
||||
|
||||
**Required (at least one):**
|
||||
|
||||
- `OPENAI_API_KEY` - OpenAI API key for GPT models
|
||||
- `ANTHROPIC_API_KEY` - Anthropic API key for Claude models
|
||||
- `OPENROUTER_API_KEY` - OpenRouter API key for various models
|
||||
|
||||
**Automatic:**
|
||||
|
||||
- `GITHUB_TOKEN` - Automatically provided by GitHub Actions
|
||||
|
||||
### 2. Repository Variables
|
||||
|
||||
Configure these variables in your repository settings (`Settings > Secrets and variables > Actions > Variables`):
|
||||
|
||||
- `MODEL_PROVIDER` - Choose: `openai`, `anthropic`, or `openrouter` (default: `anthropic`)
|
||||
- `MODEL_NAME` - Model to use (default: `claude-3-5-sonnet-20241022`)
|
||||
- `MAX_TOKENS` - Maximum tokens for responses (default: `8192`)
|
||||
- `TEMPERATURE` - Model temperature 0-1 (default: `0.2`)
|
||||
|
||||
### 3. Enable GitHub Actions
|
||||
|
||||
1. Go to `Settings > Actions > General`
|
||||
2. Under "Workflow permissions", select "Read and write permissions"
|
||||
3. Check "Allow GitHub Actions to create and approve pull requests"
|
||||
4. Save the settings
|
||||
|
||||
### 4. Test the Bot
|
||||
|
||||
Create an issue or comment with `/roo` to trigger the bot:
|
||||
|
||||
```
|
||||
/roo plan
|
||||
|
||||
Please help me implement a new feature for user authentication.
|
||||
```
|
||||
|
||||
## Workflow Triggers
|
||||
|
||||
The bot is triggered by:
|
||||
|
||||
- **Issue events**: When issues are opened or edited containing `/roo`
|
||||
- **Issue comments**: When comments are created or edited containing `/roo`
|
||||
- **Pull request events**: When PRs are opened, edited, or synchronized containing `/roo`
|
||||
- **PR review comments**: When review comments are created or edited containing `/roo`
|
||||
- **Manual dispatch**: Can be triggered manually from the Actions tab
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
.github/
|
||||
├── workflows/
|
||||
│ └── roocode-bot.yml # GitHub Actions workflow definition
|
||||
└── scripts/
|
||||
├── roocode-agent.ts # Main bot logic
|
||||
├── package.json # Dependencies
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
To test locally:
|
||||
|
||||
```bash
|
||||
cd .github/scripts
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
Set environment variables:
|
||||
|
||||
```bash
|
||||
export GITHUB_TOKEN=your_token
|
||||
export ANTHROPIC_API_KEY=your_key
|
||||
export GITHUB_EVENT_PATH=path/to/event.json
|
||||
export GITHUB_REPOSITORY=owner/repo
|
||||
export GITHUB_EVENT_NAME=issues
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- API keys are stored as encrypted secrets
|
||||
- The bot only has permissions granted by the `GITHUB_TOKEN`
|
||||
- All actions are logged in GitHub Actions
|
||||
- The bot identifies itself in all comments
|
||||
|
||||
## Extending the Bot
|
||||
|
||||
To add new commands:
|
||||
|
||||
1. Add the command detection in `extractCommands()`
|
||||
2. Implement the handler function
|
||||
3. Add the case in `processIssue()` or `processPullRequest()`
|
||||
4. Update this README with the new command
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Check the GitHub Actions logs:
|
||||
|
||||
1. Go to the "Actions" tab in your repository
|
||||
2. Click on the "RooCode Agent Bot" workflow
|
||||
3. Select a run to view detailed logs
|
||||
|
||||
Common issues:
|
||||
|
||||
- Missing API keys: Check repository secrets
|
||||
- Insufficient permissions: Check workflow permissions
|
||||
- Model errors: Verify MODEL_PROVIDER and MODEL_NAME variables
|
||||
19
.github/scripts/package.json
vendored
19
.github/scripts/package.json
vendored
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"name": "roocode-agent-scripts",
|
||||
"version": "1.0.0",
|
||||
"description": "RooCode Agent GitHub Actions Bot",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "tsx roocode-agent.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/rest": "^20.0.2",
|
||||
"@anthropic-ai/sdk": "^0.37.0",
|
||||
"openai": "^5.12.2",
|
||||
"@modelcontextprotocol/sdk": "^1.12.0",
|
||||
"tsx": "^4.19.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0"
|
||||
}
|
||||
}
|
||||
483
.github/scripts/roocode-agent.ts
vendored
483
.github/scripts/roocode-agent.ts
vendored
|
|
@ -1,483 +0,0 @@
|
|||
#!/usr/bin/env tsx
|
||||
|
||||
import { Octokit } from "@octokit/rest"
|
||||
import OpenAI from "openai"
|
||||
import Anthropic from "@anthropic-ai/sdk"
|
||||
import * as fs from "fs"
|
||||
import * as path from "path"
|
||||
import { exec } from "child_process"
|
||||
import { promisify } from "util"
|
||||
|
||||
const execAsync = promisify(exec)
|
||||
|
||||
// Configuration from environment variables
|
||||
const config = {
|
||||
githubToken: process.env.GITHUB_TOKEN!,
|
||||
openaiApiKey: process.env.OPENAI_API_KEY,
|
||||
anthropicApiKey: process.env.ANTHROPIC_API_KEY,
|
||||
openRouterApiKey: process.env.OPENROUTER_API_KEY,
|
||||
modelProvider: process.env.MODEL_PROVIDER || "anthropic",
|
||||
modelName: process.env.MODEL_NAME || "claude-3-5-sonnet-20241022",
|
||||
maxTokens: parseInt(process.env.MAX_TOKENS || "8192"),
|
||||
temperature: parseFloat(process.env.TEMPERATURE || "0.2"),
|
||||
}
|
||||
|
||||
// Initialize GitHub client
|
||||
const octokit = new Octokit({
|
||||
auth: config.githubToken,
|
||||
})
|
||||
|
||||
// Initialize AI clients based on provider
|
||||
let aiClient: any
|
||||
if (config.modelProvider === "openai" && config.openaiApiKey) {
|
||||
aiClient = new OpenAI({ apiKey: config.openaiApiKey })
|
||||
} else if (config.modelProvider === "anthropic" && config.anthropicApiKey) {
|
||||
aiClient = new Anthropic({ apiKey: config.anthropicApiKey })
|
||||
} else if (config.modelProvider === "openrouter" && config.openRouterApiKey) {
|
||||
aiClient = new OpenAI({
|
||||
apiKey: config.openRouterApiKey,
|
||||
baseURL: "https://openrouter.ai/api/v1",
|
||||
})
|
||||
} else {
|
||||
console.error("No valid AI provider configured")
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Parse GitHub event
|
||||
const eventPath = process.env.GITHUB_EVENT_PATH
|
||||
const event = JSON.parse(fs.readFileSync(eventPath!, "utf8"))
|
||||
const context = {
|
||||
repo: process.env.GITHUB_REPOSITORY!.split("/")[1],
|
||||
owner: process.env.GITHUB_REPOSITORY!.split("/")[0],
|
||||
eventName: process.env.GITHUB_EVENT_NAME!,
|
||||
}
|
||||
|
||||
interface Command {
|
||||
type: "plan" | "approve" | "fix" | "review" | "triage" | "label" | "comment"
|
||||
content?: string
|
||||
labels?: string[]
|
||||
approved?: boolean
|
||||
}
|
||||
|
||||
// Extract commands from text
|
||||
function extractCommands(text: string): Command[] {
|
||||
const commands: Command[] = []
|
||||
|
||||
if (text.includes("/roo plan")) {
|
||||
commands.push({ type: "plan" })
|
||||
}
|
||||
if (text.includes("/roo approve")) {
|
||||
commands.push({ type: "approve", approved: true })
|
||||
}
|
||||
if (text.includes("/roo fix")) {
|
||||
commands.push({ type: "fix" })
|
||||
}
|
||||
if (text.includes("/roo review")) {
|
||||
commands.push({ type: "review" })
|
||||
}
|
||||
if (text.includes("/roo triage")) {
|
||||
commands.push({ type: "triage" })
|
||||
}
|
||||
if (text.includes("/roo label")) {
|
||||
commands.push({ type: "label" })
|
||||
}
|
||||
if (text.includes("/roo")) {
|
||||
// Generic command - analyze and respond
|
||||
commands.push({ type: "comment" })
|
||||
}
|
||||
|
||||
return commands
|
||||
}
|
||||
|
||||
// Get AI response
|
||||
async function getAIResponse(prompt: string, systemPrompt: string): Promise<string> {
|
||||
try {
|
||||
if (config.modelProvider === "anthropic") {
|
||||
const response = await aiClient.messages.create({
|
||||
model: config.modelName,
|
||||
max_tokens: config.maxTokens,
|
||||
temperature: config.temperature,
|
||||
system: systemPrompt,
|
||||
messages: [{ role: "user", content: prompt }],
|
||||
})
|
||||
return response.content[0].text
|
||||
} else {
|
||||
// OpenAI or OpenRouter
|
||||
const response = await aiClient.chat.completions.create({
|
||||
model: config.modelName,
|
||||
max_tokens: config.maxTokens,
|
||||
temperature: config.temperature,
|
||||
messages: [
|
||||
{ role: "system", content: systemPrompt },
|
||||
{ role: "user", content: prompt },
|
||||
],
|
||||
})
|
||||
return response.choices[0].message.content || ""
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error getting AI response:", error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// Process issue event
|
||||
async function processIssue(issue: any, comment?: any) {
|
||||
const text = comment?.body || issue.body || ""
|
||||
const commands = extractCommands(text)
|
||||
|
||||
if (commands.length === 0) return
|
||||
|
||||
for (const command of commands) {
|
||||
switch (command.type) {
|
||||
case "plan":
|
||||
await createPlan(issue)
|
||||
break
|
||||
case "approve":
|
||||
await approvePlan(issue)
|
||||
break
|
||||
case "fix":
|
||||
await implementFix(issue)
|
||||
break
|
||||
case "triage":
|
||||
await triageIssue(issue)
|
||||
break
|
||||
case "label":
|
||||
await labelIssue(issue)
|
||||
break
|
||||
case "comment":
|
||||
await respondToComment(issue, text)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process pull request event
|
||||
async function processPullRequest(pr: any, comment?: any) {
|
||||
const text = comment?.body || pr.body || ""
|
||||
const commands = extractCommands(text)
|
||||
|
||||
if (commands.length === 0) return
|
||||
|
||||
for (const command of commands) {
|
||||
switch (command.type) {
|
||||
case "review":
|
||||
await reviewPullRequest(pr)
|
||||
break
|
||||
case "comment":
|
||||
await respondToPRComment(pr, text)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a plan for an issue
|
||||
async function createPlan(issue: any) {
|
||||
const systemPrompt = `You are RooCode-Agent, an AI assistant that helps with GitHub issues.
|
||||
Your task is to analyze the issue and create a detailed implementation plan.
|
||||
Format your response as a clear, step-by-step plan with:
|
||||
1. Understanding of the problem
|
||||
2. Proposed solution
|
||||
3. Implementation steps
|
||||
4. Testing approach
|
||||
5. Potential risks or considerations
|
||||
|
||||
End your plan with: "Reply with '/roo approve' to proceed with implementation."`
|
||||
|
||||
const prompt = `Issue #${issue.number}: ${issue.title}
|
||||
|
||||
${issue.body}
|
||||
|
||||
Please create a detailed implementation plan for this issue.`
|
||||
|
||||
const plan = await getAIResponse(prompt, systemPrompt)
|
||||
|
||||
await octokit.issues.createComment({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
issue_number: issue.number,
|
||||
body: `## 📋 Implementation Plan
|
||||
|
||||
${plan}
|
||||
|
||||
---
|
||||
*Generated by RooCode-Agent*`,
|
||||
})
|
||||
}
|
||||
|
||||
// Approve and implement plan
|
||||
async function approvePlan(issue: any) {
|
||||
// Check if there's a plan in the comments
|
||||
const comments = await octokit.issues.listComments({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
issue_number: issue.number,
|
||||
})
|
||||
|
||||
const planComment = comments.data.find(
|
||||
(c) => c.body?.includes("Implementation Plan") && c.user?.login === "github-actions[bot]",
|
||||
)
|
||||
|
||||
if (!planComment) {
|
||||
await octokit.issues.createComment({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
issue_number: issue.number,
|
||||
body: `❌ No plan found to approve. Please run '/roo plan' first.`,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
await octokit.issues.createComment({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
issue_number: issue.number,
|
||||
body: `✅ Plan approved! Starting implementation...
|
||||
|
||||
*Note: This is a demonstration. In a real scenario, the bot would now create a branch and implement the changes.*`,
|
||||
})
|
||||
|
||||
// In a real implementation, this would create a branch and start coding
|
||||
await implementFix(issue)
|
||||
}
|
||||
|
||||
// Implement a fix for an issue
|
||||
async function implementFix(issue: any) {
|
||||
// This is a simplified version - in reality, this would:
|
||||
// 1. Create a new branch
|
||||
// 2. Make code changes based on the issue
|
||||
// 3. Commit and push changes
|
||||
// 4. Create a pull request
|
||||
|
||||
const branchName = `fix/issue-${issue.number}`
|
||||
|
||||
try {
|
||||
// Create a simple demonstration PR
|
||||
await octokit.issues.createComment({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
issue_number: issue.number,
|
||||
body: `🔧 Working on implementation...
|
||||
|
||||
- Creating branch: \`${branchName}\`
|
||||
- Analyzing codebase...
|
||||
- Implementing changes...
|
||||
|
||||
*Note: This is a demonstration. In a production environment, the bot would actually create and modify files.*`,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("Error implementing fix:", error)
|
||||
await octokit.issues.createComment({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
issue_number: issue.number,
|
||||
body: `❌ Error implementing fix: ${error}`,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Triage an issue
|
||||
async function triageIssue(issue: any) {
|
||||
const systemPrompt = `You are RooCode-Agent. Analyze this issue and suggest:
|
||||
1. Priority level (P0-Critical, P1-High, P2-Medium, P3-Low)
|
||||
2. Relevant labels (bug, enhancement, documentation, etc.)
|
||||
3. Estimated complexity (Easy, Medium, Hard)
|
||||
4. Suggested assignee type (frontend, backend, fullstack, devops)`
|
||||
|
||||
const prompt = `Issue #${issue.number}: ${issue.title}
|
||||
|
||||
${issue.body}
|
||||
|
||||
Please triage this issue.`
|
||||
|
||||
const response = await getAIResponse(prompt, systemPrompt)
|
||||
|
||||
await octokit.issues.createComment({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
issue_number: issue.number,
|
||||
body: `## 🏷️ Issue Triage
|
||||
|
||||
${response}
|
||||
|
||||
---
|
||||
*Generated by RooCode-Agent*`,
|
||||
})
|
||||
}
|
||||
|
||||
// Label an issue based on content
|
||||
async function labelIssue(issue: any) {
|
||||
const systemPrompt = `You are RooCode-Agent. Analyze this issue and suggest appropriate labels.
|
||||
Common labels include: bug, enhancement, documentation, question, help wanted, good first issue,
|
||||
frontend, backend, performance, security, testing, ui/ux.
|
||||
Return only a comma-separated list of labels.`
|
||||
|
||||
const prompt = `Issue #${issue.number}: ${issue.title}
|
||||
|
||||
${issue.body}
|
||||
|
||||
Suggest appropriate labels for this issue.`
|
||||
|
||||
const response = await getAIResponse(prompt, systemPrompt)
|
||||
const labels = response
|
||||
.split(",")
|
||||
.map((l) => l.trim())
|
||||
.filter((l) => l)
|
||||
|
||||
if (labels.length > 0) {
|
||||
try {
|
||||
await octokit.issues.addLabels({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
issue_number: issue.number,
|
||||
labels: labels,
|
||||
})
|
||||
|
||||
await octokit.issues.createComment({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
issue_number: issue.number,
|
||||
body: `🏷️ Added labels: ${labels.map((l) => `\`${l}\``).join(", ")}`,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("Error adding labels:", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Review a pull request
|
||||
async function reviewPullRequest(pr: any) {
|
||||
const systemPrompt = `You are RooCode-Agent, a code reviewer. Review this pull request and provide:
|
||||
1. Summary of changes
|
||||
2. Code quality assessment
|
||||
3. Potential issues or bugs
|
||||
4. Suggestions for improvement
|
||||
5. Security considerations
|
||||
6. Overall recommendation (Approve, Request Changes, or Comment)`
|
||||
|
||||
// Get PR diff
|
||||
const diff = await octokit.pulls.get({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
pull_number: pr.number,
|
||||
mediaType: { format: "diff" },
|
||||
})
|
||||
|
||||
const prompt = `Pull Request #${pr.number}: ${pr.title}
|
||||
|
||||
Description:
|
||||
${pr.body}
|
||||
|
||||
Diff:
|
||||
${diff.data}
|
||||
|
||||
Please review this pull request.`
|
||||
|
||||
const review = await getAIResponse(prompt, systemPrompt)
|
||||
|
||||
await octokit.pulls.createReview({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
pull_number: pr.number,
|
||||
body: `## 🔍 Code Review
|
||||
|
||||
${review}
|
||||
|
||||
---
|
||||
*Generated by RooCode-Agent*`,
|
||||
event: "COMMENT",
|
||||
})
|
||||
}
|
||||
|
||||
// Respond to a comment on an issue
|
||||
async function respondToComment(issue: any, commentText: string) {
|
||||
const systemPrompt = `You are RooCode-Agent, an AI assistant for the Roo-Code project.
|
||||
Respond helpfully to the user's comment or question about this issue.
|
||||
Be concise, technical, and actionable.`
|
||||
|
||||
const prompt = `Issue #${issue.number}: ${issue.title}
|
||||
|
||||
Issue Description:
|
||||
${issue.body}
|
||||
|
||||
User Comment:
|
||||
${commentText}
|
||||
|
||||
Please provide a helpful response.`
|
||||
|
||||
const response = await getAIResponse(prompt, systemPrompt)
|
||||
|
||||
await octokit.issues.createComment({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
issue_number: issue.number,
|
||||
body: response + "\n\n---\n*Response by RooCode-Agent*",
|
||||
})
|
||||
}
|
||||
|
||||
// Respond to a comment on a PR
|
||||
async function respondToPRComment(pr: any, commentText: string) {
|
||||
const systemPrompt = `You are RooCode-Agent, an AI assistant for the Roo-Code project.
|
||||
Respond helpfully to the user's comment or question about this pull request.
|
||||
Be concise, technical, and actionable.`
|
||||
|
||||
const prompt = `Pull Request #${pr.number}: ${pr.title}
|
||||
|
||||
PR Description:
|
||||
${pr.body}
|
||||
|
||||
User Comment:
|
||||
${commentText}
|
||||
|
||||
Please provide a helpful response.`
|
||||
|
||||
const response = await getAIResponse(prompt, systemPrompt)
|
||||
|
||||
await octokit.issues.createComment({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
issue_number: pr.number,
|
||||
body: response + "\n\n---\n*Response by RooCode-Agent*",
|
||||
})
|
||||
}
|
||||
|
||||
// Main execution
|
||||
async function main() {
|
||||
try {
|
||||
console.log(`Processing ${context.eventName} event`)
|
||||
|
||||
if (context.eventName === "issues") {
|
||||
await processIssue(event.issue)
|
||||
} else if (context.eventName === "issue_comment") {
|
||||
await processIssue(event.issue, event.comment)
|
||||
} else if (context.eventName === "pull_request") {
|
||||
await processPullRequest(event.pull_request)
|
||||
} else if (context.eventName === "pull_request_review_comment") {
|
||||
await processPullRequest(event.pull_request, event.comment)
|
||||
} else if (context.eventName === "workflow_dispatch") {
|
||||
// Handle manual trigger
|
||||
if (event.inputs?.issue_number) {
|
||||
const issue = await octokit.issues.get({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
issue_number: parseInt(event.inputs.issue_number),
|
||||
})
|
||||
await processIssue(issue.data)
|
||||
} else if (event.inputs?.pr_number) {
|
||||
const pr = await octokit.pulls.get({
|
||||
owner: context.owner,
|
||||
repo: context.repo,
|
||||
pull_number: parseInt(event.inputs.pr_number),
|
||||
})
|
||||
await processPullRequest(pr.data)
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Event processed successfully")
|
||||
} catch (error) {
|
||||
console.error("Error processing event:", error)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Run the bot
|
||||
main()
|
||||
66
.github/workflows/roocode-bot.yml
vendored
66
.github/workflows/roocode-bot.yml
vendored
|
|
@ -1,66 +0,0 @@
|
|||
name: RooCode Agent Bot
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
issue_comment:
|
||||
types: [created, edited]
|
||||
pull_request:
|
||||
types: [opened, edited, synchronize]
|
||||
pull_request_review_comment:
|
||||
types: [created, edited]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
issue_number:
|
||||
description: 'Issue number to process'
|
||||
required: false
|
||||
type: string
|
||||
pr_number:
|
||||
description: 'PR number to process'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
process-event:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
(github.event_name == 'issues' && contains(github.event.issue.body, '/roo')) ||
|
||||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '/roo')) ||
|
||||
(github.event_name == 'pull_request' && contains(github.event.pull_request.body, '/roo')) ||
|
||||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '/roo')) ||
|
||||
github.event_name == 'workflow_dispatch'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd .github/scripts
|
||||
npm install
|
||||
|
||||
- name: Process Event
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
|
||||
MODEL_PROVIDER: ${{ vars.MODEL_PROVIDER || 'anthropic' }}
|
||||
MODEL_NAME: ${{ vars.MODEL_NAME || 'claude-3-5-sonnet-20241022' }}
|
||||
MAX_TOKENS: ${{ vars.MAX_TOKENS || '8192' }}
|
||||
TEMPERATURE: ${{ vars.TEMPERATURE || '0.2' }}
|
||||
run: |
|
||||
cd .github/scripts
|
||||
npm start
|
||||
142
github-actions-workflows.md
Normal file
142
github-actions-workflows.md
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
# GitHub Actions Workflows for RooCode Agent Bot
|
||||
|
||||
Due to GitHub security restrictions, workflow files cannot be automatically created via GitHub Apps. Please manually add these files to your repository.
|
||||
|
||||
## Required Files
|
||||
|
||||
### 1. `.github/workflows/roocode-bot.yml`
|
||||
|
||||
```yaml
|
||||
name: RooCode Agent Bot
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
issue_comment:
|
||||
types: [created, edited]
|
||||
pull_request:
|
||||
types: [opened, edited, synchronize]
|
||||
pull_request_review_comment:
|
||||
types: [created, edited]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
issue_number:
|
||||
description: "Issue number to process"
|
||||
required: false
|
||||
type: string
|
||||
pr_number:
|
||||
description: "PR number to process"
|
||||
required: false
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
process-event:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
(github.event_name == 'issues' && contains(github.event.issue.body, '/roo')) ||
|
||||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '/roo')) ||
|
||||
(github.event_name == 'pull_request' && contains(github.event.pull_request.body, '/roo')) ||
|
||||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '/roo')) ||
|
||||
github.event_name == 'workflow_dispatch'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "20"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd .github/scripts
|
||||
npm install
|
||||
|
||||
- name: Process Event
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
|
||||
MODEL_PROVIDER: ${{ vars.MODEL_PROVIDER || 'anthropic' }}
|
||||
MODEL_NAME: ${{ vars.MODEL_NAME || 'claude-3-5-sonnet-20241022' }}
|
||||
MAX_TOKENS: ${{ vars.MAX_TOKENS || '8192' }}
|
||||
TEMPERATURE: ${{ vars.TEMPERATURE || '0.2' }}
|
||||
run: |
|
||||
cd .github/scripts
|
||||
npm start
|
||||
```
|
||||
|
||||
### 2. `.github/scripts/package.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "roocode-agent-scripts",
|
||||
"version": "1.0.0",
|
||||
"description": "RooCode Agent GitHub Actions Bot",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "tsx roocode-agent.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@octokit/rest": "^20.0.2",
|
||||
"@anthropic-ai/sdk": "^0.37.0",
|
||||
"openai": "^5.12.2",
|
||||
"@modelcontextprotocol/sdk": "^1.12.0",
|
||||
"tsx": "^4.19.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. `.github/scripts/roocode-agent.ts`
|
||||
|
||||
Create this file with the full agent implementation. The complete code is available in the PR description.
|
||||
|
||||
### 4. `.github/scripts/README.md`
|
||||
|
||||
Documentation for the GitHub Actions bot setup and usage.
|
||||
|
||||
## Setup Instructions
|
||||
|
||||
1. **Add the workflow files manually** to your repository
|
||||
2. **Configure Repository Secrets** (Settings → Secrets and variables → Actions):
|
||||
|
||||
- `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` (at least one required)
|
||||
- `OPENROUTER_API_KEY` (optional)
|
||||
|
||||
3. **Configure Repository Variables** (Settings → Secrets and variables → Actions → Variables):
|
||||
|
||||
- `MODEL_PROVIDER`: `anthropic`, `openai`, or `openrouter`
|
||||
- `MODEL_NAME`: Model identifier
|
||||
- `MAX_TOKENS`: Maximum response tokens
|
||||
- `TEMPERATURE`: Model temperature (0-1)
|
||||
|
||||
4. **Enable GitHub Actions Permissions**:
|
||||
- Go to Settings → Actions → General
|
||||
- Select "Read and write permissions"
|
||||
- Check "Allow GitHub Actions to create and approve pull requests"
|
||||
|
||||
## Available Commands
|
||||
|
||||
- `/roo plan` - Create implementation plan
|
||||
- `/roo approve` - Approve plan and implement
|
||||
- `/roo fix` - Direct fix implementation
|
||||
- `/roo review` - Review pull request
|
||||
- `/roo triage` - Triage issue
|
||||
- `/roo label` - Add labels to issue
|
||||
- `/roo` - General bot interaction
|
||||
|
||||
## Testing
|
||||
|
||||
Create an issue or PR comment with `/roo` to trigger the bot.
|
||||
Loading…
Add table
Reference in a new issue