diff --git a/.github/workflows/codex.yml b/.github/workflows/codex.yml new file mode 100644 index 0000000..7105ecd --- /dev/null +++ b/.github/workflows/codex.yml @@ -0,0 +1,102 @@ +name: Codex Review + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + +permissions: + contents: read + +jobs: + codex: + name: Review Pull Request + if: | + github.event.pull_request.draft == false && + github.actor != 'dependabot[bot]' && + github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + outputs: + final_message: ${{ steps.run_codex.outputs.final-message }} + steps: + - name: Checkout pull request + uses: actions/checkout@v6 + with: + ref: refs/pull/${{ github.event.pull_request.number }}/merge + persist-credentials: false + + - name: Fetch pull request refs + env: + PR_BASE_REF: ${{ github.event.pull_request.base.ref }} + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + git fetch --no-tags origin \ + "$PR_BASE_REF" \ + "+refs/pull/$PR_NUMBER/head" + + - name: Run Codex review + id: run_codex + uses: openai/codex-action@v1 + with: + openai-api-key: ${{ secrets.OPENAI_API_KEY }} + permission-profile: ":workspace" + prompt: | + This is PR #${{ github.event.pull_request.number }} for ${{ github.repository }}. + + Review only the changes introduced by this pull request. Focus on bugs, + behavior regressions, security risks, and missing tests. Keep feedback + concise and specific, with file and line references where possible. + + Useful commands: + git log --oneline ${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }} + git diff --stat ${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }} + git diff ${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }} + + Pull request title and body: + ---- + ${{ github.event.pull_request.title }} + ${{ github.event.pull_request.body }} + + post_feedback: + name: Post Codex Feedback + needs: codex + if: | + needs.codex.result == 'success' && + needs.codex.outputs.final_message != '' + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - name: Comment on pull request + uses: actions/github-script@v7 + env: + CODEX_FINAL_MESSAGE: ${{ needs.codex.outputs.final_message }} + with: + github-token: ${{ github.token }} + script: | + const marker = ''; + const body = `${marker}\n${process.env.CODEX_FINAL_MESSAGE}`; + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + }); + const existing = comments.find((comment) => + comment.user.type === 'Bot' && comment.body?.includes(marker) + ); + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + body, + }); + }