-
Notifications
You must be signed in to change notification settings - Fork 7
feat: add automated bug-fixing GitHub Actions workflow and non-interactive CLI support #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,96 @@ | ||||||||||||||||||||||||||||||||||||||||||
| name: Agent Auto-Fix | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||
| issues: | ||||||||||||||||||||||||||||||||||||||||||
| types: [opened, labeled] | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||
| agent-fix: | ||||||||||||||||||||||||||||||||||||||||||
| # Run only if the issue is labeled with 'agent-fix', or opened with 'agent-fix' label. | ||||||||||||||||||||||||||||||||||||||||||
| if: github.event.label.name == 'agent-fix' || (github.event.action == 'opened' && contains(github.event.issue.labels.*.name, 'agent-fix')) | ||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||
| contents: write | ||||||||||||||||||||||||||||||||||||||||||
| pull-requests: write | ||||||||||||||||||||||||||||||||||||||||||
| issues: write | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||
| - name: Checkout Repository | ||||||||||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - name: Set up Python | ||||||||||||||||||||||||||||||||||||||||||
| uses: actions/setup-python@v5 | ||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||
| python-version: '3.11' | ||||||||||||||||||||||||||||||||||||||||||
| cache: 'pip' | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - name: Install dependencies | ||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||
| python -m pip install --upgrade pip | ||||||||||||||||||||||||||||||||||||||||||
| if [ -f requirements.txt ]; then pip install -r requirements.txt; fi | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - name: Configure Git | ||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||
| git config --global user.name "github-actions[bot]" | ||||||||||||||||||||||||||||||||||||||||||
| git config --global user.email "github-actions[bot]@users.noreply.github.com" | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - name: Run Developer Agent | ||||||||||||||||||||||||||||||||||||||||||
| id: run-agent | ||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | ||||||||||||||||||||||||||||||||||||||||||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||
| AGENT_TASK: | | ||||||||||||||||||||||||||||||||||||||||||
| Issue #${{ github.event.issue.number }}: ${{ github.event.issue.title }} | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| ${{ github.event.issue.body }} | ||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||
| python main.py \ | ||||||||||||||||||||||||||||||||||||||||||
| --repo . \ | ||||||||||||||||||||||||||||||||||||||||||
| --push \ | ||||||||||||||||||||||||||||||||||||||||||
| --pr \ | ||||||||||||||||||||||||||||||||||||||||||
| --base-branch ${{ github.event.repository.default_branch }} \ | ||||||||||||||||||||||||||||||||||||||||||
| --yes | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| - name: Post Comment on Issue | ||||||||||||||||||||||||||||||||||||||||||
| if: always() | ||||||||||||||||||||||||||||||||||||||||||
| uses: actions/github-script@v7 | ||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||
| script: | | ||||||||||||||||||||||||||||||||||||||||||
| const issueNumber = context.issue.number; | ||||||||||||||||||||||||||||||||||||||||||
| const outcome = "${{ steps.run-agent.outputs.outcome }}"; | ||||||||||||||||||||||||||||||||||||||||||
| const prUrl = "${{ steps.run-agent.outputs.pr_url }}"; | ||||||||||||||||||||||||||||||||||||||||||
| const runId = "${{ steps.run-agent.outputs.run_id }}"; | ||||||||||||||||||||||||||||||||||||||||||
| const message = "${{ steps.run-agent.outputs.final_message }}"; | ||||||||||||||||||||||||||||||||||||||||||
| const issuee = context.payload.issue.user.login; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| let commentBody = ""; | ||||||||||||||||||||||||||||||||||||||||||
| if (outcome === "success") { | ||||||||||||||||||||||||||||||||||||||||||
| commentBody = `Hello @${issuee}, | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| I have successfully fixed the issue! 🎉 | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| A Pull Request has been created with the changes: | ||||||||||||||||||||||||||||||||||||||||||
| 🔗 **[Pull Request](${prUrl})** | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| **Run ID:** \`${runId}\` | ||||||||||||||||||||||||||||||||||||||||||
| **Message:** ${message}`; | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+70
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Do not claim a PR was created when
Proposed fix- if (outcome === "success") {
+ if (outcome === "success" && prUrl) {
commentBody = `Hello @${issuee},📝 Committable suggestion
Suggested change
🧰 Tools🪛 actionlint (1.7.12)[error] 73-73: could not parse as YAML: could not find expected ':' (syntax-check) 🪛 YAMLlint (1.37.1)[error] 75-75: syntax error: could not find expected ':' (syntax) 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||
| commentBody = `Hello @${issuee}, | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| I attempted to fix this issue automatically but encountered a problem. | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| **Outcome:** \`${outcome || 'unknown/failed'}\` | ||||||||||||||||||||||||||||||||||||||||||
| **Message:** ${message || 'No additional message was provided.'} | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Please check the GitHub Actions workflow logs for more details.`; | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+71
to
+88
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
if command -v actionlint >/dev/null; then
actionlint .github/workflows/agent-fix.yml
fi
if command -v yamllint >/dev/null; then
yamllint .github/workflows/agent-fix.yml
fiRepository: sreerevanth/repopilot Length of output: 854 🏁 Script executed: #!/bin/bash
set -euo pipefail
# Show the relevant workflow section with line numbers.
sed -n '55,100p' .github/workflows/agent-fix.yml | cat -n
# Also show the surrounding job/step structure to confirm the YAML nesting.
python3 - <<'PY'
from pathlib import Path
p = Path('.github/workflows/agent-fix.yml')
for i, line in enumerate(p.read_text().splitlines(), 1):
if 50 <= i <= 105:
print(f"{i:4}: {line}")
PYRepository: sreerevanth/repopilot Length of output: 3701 Indent the template literal body inside 🧰 Tools🪛 actionlint (1.7.12)[error] 73-73: could not parse as YAML: could not find expected ':' (syntax-check) 🪛 YAMLlint (1.37.1)[error] 75-75: syntax error: could not find expected ':' (syntax) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| await github.rest.issues.createComment({ | ||||||||||||||||||||||||||||||||||||||||||
| owner: context.repo.owner, | ||||||||||||||||||||||||||||||||||||||||||
| repo: context.repo.repo, | ||||||||||||||||||||||||||||||||||||||||||
| issue_number: issueNumber, | ||||||||||||||||||||||||||||||||||||||||||
| body: commentBody | ||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -10,14 +10,14 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import argparse | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from html import parser | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import os | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import sys | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Ensure the project root is on the path | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from modules.agent_loop import AutonomousAgent, AgentConfig | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from modules.code_modifier import CodeModificationEngine | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def parse_args() -> argparse.Namespace: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -41,7 +41,7 @@ def parse_args() -> argparse.Namespace: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parser.add_argument("--repo", required=True, help="Path to the git repository") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parser.add_argument("--task", required=True, help="High-level task description") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parser.add_argument("--task", required=False, help="High-level task description (can also be provided via AGENT_TASK env var)") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Execution | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parser.add_argument("--runner", default="pytest", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -91,26 +91,52 @@ def parse_args() -> argparse.Namespace: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parser.add_argument("--api-key", default=None, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| help="Anthropic API key (default: ANTHROPIC_API_KEY env var)") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Non-interactive / CI | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parser.add_argument("--yes", "-y", action="store_true", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| help="Auto-approve file changes (bypass confirmation prompt)") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return parser.parse_args() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def write_github_output(outputs: dict[str, str]): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| github_output_path = os.environ.get("GITHUB_OUTPUT") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if github_output_path: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with open(github_output_path, "a", encoding="utf-8") as f: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for k, v in outputs.items(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if "\n" in v: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| delimiter = "EOF" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f.write(f"{k}<<{delimiter}\n{v}\n{delimiter}\n") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f.write(f"{k}={v}\n") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| except Exception as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"Failed to write to GITHUB_OUTPUT: {e}", file=sys.stderr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def main(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| args = parse_args() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| repo_root = os.path.abspath(args.repo) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if args.rollback: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| modifier = CodeModificationEngine(repo_root=repo_root, backup_dir="backups") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| modifier = CodeModificationEngine(backup_dir="backups") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| success = modifier.git_stash_pop(repo_root) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sys.exit(0 if success else 1) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not os.path.isdir(repo_root): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"ERROR: Repository path does not exist: {repo_root}", file=sys.stderr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sys.exit(1) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| yes_flag = args.yes or os.environ.get("CI") == "true" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| task = args.task or os.environ.get("AGENT_TASK") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not task: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("ERROR: Task description is required. Provide --task or set the AGENT_TASK environment variable.", file=sys.stderr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sys.exit(1) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
124
to
+133
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Write GitHub outputs for pre-run validation failures. These Proposed fix if not os.path.isdir(repo_root):
- print(f"ERROR: Repository path does not exist: {repo_root}", file=sys.stderr)
+ message = f"Repository path does not exist: {repo_root}"
+ print(f"ERROR: {message}", file=sys.stderr)
+ write_github_output({
+ "outcome": "error",
+ "run_id": "",
+ "iterations": "0",
+ "branch_name": "",
+ "pr_url": "",
+ "final_message": message,
+ })
sys.exit(1)
yes_flag = args.yes or os.environ.get("CI") == "true"
task = args.task or os.environ.get("AGENT_TASK")
if not task:
- print("ERROR: Task description is required. Provide --task or set the AGENT_TASK environment variable.", file=sys.stderr)
+ message = "Task description is required. Provide --task or set the AGENT_TASK environment variable."
+ print(f"ERROR: {message}", file=sys.stderr)
+ write_github_output({
+ "outcome": "error",
+ "run_id": "",
+ "iterations": "0",
+ "branch_name": "",
+ "pr_url": "",
+ "final_message": message,
+ })
sys.exit(1)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| config = AgentConfig( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| repo_root=repo_root, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| task=args.task, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| task=task, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dry_run=args.dry_run, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| yes=yes_flag, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Execution | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| test_runner=args.runner, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -155,15 +181,40 @@ def main(): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"MESSAGE : {result.final_message}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"{'='*60}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| write_github_output({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "outcome": result.outcome, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "run_id": result.run_id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "iterations": str(result.iterations_used), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "branch_name": result.branch_name or "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "pr_url": result.pr_url or "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "final_message": result.final_message, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sys.exit(0 if result.outcome == "success" else 1) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| except KeyboardInterrupt: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print("\nInterrupted by user.", file=sys.stderr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| write_github_output({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "outcome": "aborted", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "run_id": "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "iterations": "0", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "branch_name": "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "pr_url": "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "final_message": "Interrupted by user.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sys.exit(130) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| except Exception as e: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| print(f"\nFATAL ERROR: {e}", file=sys.stderr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import traceback | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| traceback.print_exc() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| write_github_output({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "outcome": "error", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "run_id": "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "iterations": "0", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "branch_name": "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "pr_url": "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "final_message": str(e), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sys.exit(1) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: sreerevanth/repopilot
Length of output: 451
🏁 Script executed:
Repository: sreerevanth/repopilot
Length of output: 3135
🏁 Script executed:
Repository: sreerevanth/repopilot
Length of output: 7332
🏁 Script executed:
Repository: sreerevanth/repopilot
Length of output: 2220
🏁 Script executed:
Repository: sreerevanth/repopilot
Length of output: 355
🏁 Script executed:
Repository: sreerevanth/repopilot
Length of output: 1216
🏁 Script executed:
Repository: sreerevanth/repopilot
Length of output: 1096
Quote the step outputs before interpolating them into
github-script. Raw substitution is evaluated as JS here;final_messagecan carry arbitrary text on the error path, so quotes/newlines can break the script and turn into code execution. UsetoJSON()for all four outputs.🤖 Prompt for AI Agents