Skip to content

fix: restore local bot api startup #257

fix: restore local bot api startup

fix: restore local bot api startup #257

Workflow file for this run

name: AI Iteration
on:
workflow_dispatch:
inputs:
issue_number:
description: 'Issue number to iterate'
required: false
pr_number:
description: 'PR number to iterate'
required: false
pull_request:
types: [opened, synchronize]
issue_comment:
types: [created]
permissions:
contents: write
pull-requests: write
issues: read
id-token: write
jobs:
ai-iterate:
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && startsWith(github.head_ref, 'ai/issue-')) || (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@ai'))
runs-on: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Setup bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Get opencode version
id: version
run: |
VERSION=$(curl -sf https://api.github.com/repos/anomalyco/opencode/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d'"' -f4)
echo "version=${VERSION:-latest}" >> $GITHUB_OUTPUT
- name: Cache opencode
id: cache
uses: actions/cache@v4
with:
path: ~/.opencode/bin
key: opencode-${{ runner.os }}-${{ runner.arch }}-${{ steps.version.outputs.version }}
- name: Install opencode
if: steps.cache.outputs.cache-hit != 'true'
run: curl -fsSL https://opencode.ai/install | bash
- name: Add opencode to PATH
run: echo "$HOME/.opencode/bin" >> $GITHUB_PATH
- name: Install oh-my-opencode
run: |
bunx oh-my-opencode install --no-tui --claude=no --gemini=no --copilot=no
- name: Copy oh-my-opencode config
env:
MINIMAX_API_KEY: ${{ secrets.MINIMAX_API_KEY }}
run: |
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.config\opencode" | Out-Null
$content = Get-Content '.github/workflows/opencode.json' -Raw
$content = $content -replace 'MINIMAX_API_KEY', $env:MINIMAX_API_KEY
Set-Content -Path "$env:USERPROFILE\.config\opencode\opencode.json" -Value $content
$content = Get-Content '.github/workflows/oh-my-opencode.json' -Raw
$content = $content -replace 'MINIMAX_API_KEY', $env:MINIMAX_API_KEY
Set-Content -Path "$env:USERPROFILE\.config\opencode\oh-my-opencode.json" -Value $content
- name: Determine trigger type and get PR info
id: determine
uses: actions/github-script@v7
with:
result-encoding: string
script: |
const isSchedule = context.eventName === 'schedule';
const isDispatch = context.eventName === 'workflow_dispatch';
const isPR = context.eventName === 'pull_request';
const isComment = context.eventName === 'issue_comment';
let issueNumber = null;
let prNumber = null;
let branchName = null;
if (isDispatch && context.payload.inputs && context.payload.inputs.issue_number) {
issueNumber = parseInt(context.payload.inputs.issue_number);
prNumber = issueNumber;
branchName = 'ai/issue-' + issueNumber;
} else if (isPR) {
const match = context.payload.pull_request.head.ref.match(/ai\/issue-(\d+)/);
if (match) {
issueNumber = parseInt(match[1]);
prNumber = context.payload.pull_request.number;
branchName = context.payload.pull_request.head.ref;
}
} else if (isComment) {
const match = context.payload.issue.body.match(/#(\d+)/);
if (context.payload.issue.pull_request) {
prNumber = context.payload.issue.number;
const prMatch = context.payload.issue.head.ref.match(/ai\/issue-(\d+)/);
if (prMatch) {
issueNumber = parseInt(prMatch[1]);
branchName = context.payload.issue.head.ref;
}
}
} else if (isSchedule) {
const { data: prs } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
head: 'ai/issue-'
});
if (prs.length > 0) {
const pr = prs[0];
const match = pr.head.ref.match(/ai\/issue-(\d+)/);
issueNumber = parseInt(match[1]);
prNumber = pr.number;
branchName = pr.head.ref;
}
}
return JSON.stringify({ issueNumber, prNumber, branchName, isSchedule });
- name: Set issue/PR number from dispatch/schedule
id: set_issue_pr
if: steps.determine.outputs.result != '{}'
run: |
node -e "const d=JSON.parse(process.env.RESULT); console.log('issueNumber='+(d.issueNumber||'')); console.log('prNumber='+(d.prNumber||'')); console.log('branchName='+(d.branchName||''))" >> %GITHUB_OUTPUT%
env:
RESULT: ${{ steps.determine.outputs.result }}
- name: Skip if no PRs found
if: steps.determine.outputs.result == '{}' || steps.set_issue_pr.outputs.branchName == ''
run: |
echo "SKIP=true" >> %GITHUB_OUTPUT%
echo "No PRs found to iterate"
- name: Checkout branch for schedule trigger
if: steps.set_issue_pr.outputs.branchName != ''
env:
BRANCH: ${{ steps.set_issue_pr.outputs.branchName }}
run: |
git fetch origin %BRANCH%
git checkout %BRANCH%
- name: Set environment variables
if: steps.set_issue_pr.outputs.branchName != ''
run: |
echo "ISSUE_NUM=${{ steps.set_issue_pr.outputs.issueNumber }}" >> %GITHUB_ENV%
echo "PR_NUMBER=${{ steps.set_issue_pr.outputs.prNumber }}" >> %GITHUB_ENV%
- name: Get PR comments
if: steps.set_issue_pr.outputs.branchName != ''
id: comments
uses: actions/github-script@v7
with:
result-encoding: string
script: |
const prNum = '${{ env.PR_NUMBER }}';
const { data: comments } = await github.rest.issues.listComments({
issue_number: parseInt(prNum),
owner: context.repo.owner,
repo: context.repo.repo
});
const newComments = comments.filter(c =>
c.user.type !== 'Bot' &&
new Date(c.created_at) > new Date('${{ github.event.pull_request.updated_at || github.event.comment.created_at }}')
);
return JSON.stringify(newComments.map(c => c.body));
- name: Prepare prompt for iteration
if: steps.comments.outputs.result != '[]' && steps.comments.outputs.result != ''
id: prepare_prompt
env:
COMMENTS_DATA: ${{ steps.comments.outputs.result }}
run: |
$comments = '${{ steps.comments.outputs.result }}'
if ($comments -eq '' -or $comments -eq '[]') {
Write-Host 'No new comments, skipping'
exit 0
}
$c = $comments | ConvertFrom-Json
$prompt = Get-Content '.github/workflows/prompts/ai-iterate-prompt.txt' -Raw
$prompt = $prompt -replace '{{issue_number}}', '${{ env.ISSUE_NUM }}'
$prompt = $prompt -replace '{{pr_number}}', '${{ env.PR_NUMBER }}'
$commentText = ($c | ForEach-Object { $_ }) -join "`n`n"
$prompt = $prompt -replace '{{comments}}', $commentText
# Write to temp file for opencode action
$prompt | Out-File -FilePath "$env:TEMP\prompt.txt" -Encoding UTF8
# Also output as environment variable for action
echo "PROMPT_CONTENT=$prompt" >> $env:GITHUB_ENV
- name: Run OpenCode for changes
if: steps.comments.outputs.result != '[]' && steps.comments.outputs.result != ''
id: opencode
run: opencode github run
env:
MINIMAX_API_KEY: ${{ secrets.MINIMAX_API_KEY }}
MODEL: minimax-cn-coding-plan/MiniMax-M2.5
AGENT: sisyphus
PROMPT: ${{ env.PROMPT_CONTENT }}
- name: Check changes
id: changes
if: steps.opencode.outputs.result != ''
run: |
for /f %%a in ('git status --porcelain ^| find /c /v ""') do echo changed=%%a >> %GITHUB_OUTPUT%
- name: Commit and push
if: steps.changes.outputs.changed > 0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config user.name "AI Agent"
git config user.email "ai@github.local"
git add -A
git commit -m "AI: Iterate based on feedback" 2>nul
git push origin "ai/issue-$env:ISSUE_NUM" 2>nul
- name: Post iteration report
if: steps.changes.outputs.changed > 0
uses: actions/github-script@v7
with:
script: |
const body = "## AI Iteration Report\n\nChanges made:\n- Applied requested changes from PR comments\n- Fixed identified issues\n\nFiles modified: See commit history\nTest results: See workflow logs";
await github.rest.issues.createComment({
issue_number: parseInt('${{ env.PR_NUMBER }}'),
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
- name: Cleanup temp files
if: always()
run: |
Remove-Item -Force "$env:TEMP\prompt.txt" -ErrorAction SilentlyContinue || true