feat: AI auto-merge PR after implementation #42
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: AI Iteration | |
| on: | |
| pull_request: | |
| types: [opened, synchronize] | |
| schedule: | |
| - cron: '0 0 * * *' | |
| issue_comment: | |
| types: [created] | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: read | |
| jobs: | |
| ai-iterate: | |
| if: github.event_name == 'schedule' || (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: | |
| ref: ${{ github.head_ref }} | |
| fetch-depth: 1 | |
| - name: Setup bun | |
| uses: oven-sh/setup-bun@v1 | |
| with: | |
| bun-version: latest | |
| - name: Install OpenCode and oh-my-opencode | |
| run: | | |
| bun add -g opencode-ai | |
| bunx oh-my-opencode install --no-tui --claude=no --gemini=no --copilot=no | |
| - name: Copy oh-my-opencode config | |
| run: | | |
| mkdir %USERPROFILE%\.config\opencode | |
| copy .github\workflows\oh-my-opencode.json %USERPROFILE%\.config\opencode\oh-my-opencode.json | |
| - name: Extract issue number | |
| id: extract | |
| run: | | |
| for /f "tokens=2 delims=/" %%a in ("%GITHUB_HEAD_REF%") do echo issue_number=%%a >> %GITHUB_OUTPUT% | |
| echo pr_number=%GITHUB_PR_NUMBER% >> %GITHUB_OUTPUT% | |
| - name: Set environment variables | |
| run: | | |
| echo "ISSUE_NUM=${{ steps.extract.outputs.issue_number }}" >> $env:GITHUB_ENV | |
| echo "PR_NUMBER=${{ steps.extract.outputs.pr_number }}" >> $env:GITHUB_ENV | |
| - name: Get PR comments | |
| id: comments | |
| uses: actions/github-script@v7 | |
| with: | |
| result-encoding: string | |
| script: | | |
| const prNum = '${{ steps.extract.outputs.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: Run OpenCode for changes | |
| if: steps.comments.outputs.result != '[]' | |
| id: opencode | |
| env: | |
| MINIMAX_API_KEY: ${{ secrets.MINIMAX_API_KEY }} | |
| COMMENTS_DATA: ${{ steps.comments.outputs.result }} | |
| run: | | |
| bun add -g opencode-ai | |
| bunx oh-my-opencode install --no-tui --claude=no --gemini=no --copilot=no | |
| # 替换配置文件中的占位符 | |
| powershell -Command "$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" | |
| node -e "const fs=require('fs');const c=JSON.parse(process.env.COMMENTS_DATA);let p=fs.readFileSync('.github/workflows/prompts/ai-iterate-prompt.txt','utf8');p=p.replace(/{{issue_number}}/g,'$env:ISSUE_NUM').replace(/{{pr_number}}/g,'$env:PR_NUMBER').replace(/{{comments}}/g,c.join('\n\n'));fs.writeFileSync('prompt.txt',p);" | |
| opencode . < prompt.txt --opencode-go=yes | |
| - 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('${{ steps.extract.outputs.pr_number }}'), | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| - name: Merge PR | |
| if: steps.changes.outputs.changed > 0 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh pr merge --squash --delete-branch "ai/issue-$env:ISSUE_NUM" --auto 2>nul || echo "PR merge failed or already merged" | |
| body: body | |
| }); |