diff --git a/.github/workflows/reusable-workflow-ci-ai-agents.yaml b/.github/workflows/reusable-workflow-ci-ai-agents.yaml index 2de8a8e..8f1004a 100644 --- a/.github/workflows/reusable-workflow-ci-ai-agents.yaml +++ b/.github/workflows/reusable-workflow-ci-ai-agents.yaml @@ -48,15 +48,49 @@ on: description: "LLM model to use for general purpose tasks" required: false type: string + codex_model: + description: "OpenAI model to use for Codex agent" + required: false + type: string + default: "o3" jobs: - run-ci-ai-agent: + detect-agent: if: | inputs.event_name == 'issues' || inputs.event_name == 'issue_comment' || + inputs.event_name == 'pull_request' || inputs.event_name == 'pull_request_review_comment' || inputs.event_name == 'pull_request_review' runs-on: gha-production-medium + outputs: + agent: ${{ steps.parse.outputs.agent }} + codex_prompt: ${{ steps.parse.outputs.codex_prompt }} + steps: + - name: Parse agent from comment + id: parse + shell: bash + env: + EVENT_PAYLOAD: ${{ inputs.event_payload }} + run: | + comment=$(echo "$EVENT_PAYLOAD" | jq -r '.comment.body // .review.body // .issue.body // ""') + + if echo "$comment" | grep -q '/codex-'; then + echo "agent=codex" >> $GITHUB_OUTPUT + # Extract the command after /codex- (e.g., "review-pr" from "/codex-review-pr") + codex_cmd=$(echo "$comment" | grep -oE '/codex-[^ ]+' | head -1 | sed 's|/codex-||') + # Extract any additional context after the command on the same line or following lines + full_prompt=$(echo "$comment" | sed -n '/\/codex-/,$p' | sed '1s|.*/codex-[^ ]*||') + echo "codex_prompt=${codex_cmd}${full_prompt}" >> $GITHUB_OUTPUT + else + echo "agent=claude" >> $GITHUB_OUTPUT + echo "codex_prompt=" >> $GITHUB_OUTPUT + fi + + run-claude-agent: + needs: detect-agent + if: needs.detect-agent.outputs.agent == 'claude' + runs-on: gha-production-medium container: ci-images-release.arti.tw.ee/actions_java_17_and_21 permissions: contents: write @@ -64,6 +98,43 @@ jobs: issues: write id-token: write actions: read + env: + PR_PROMPT: | + REPO: ${{ github.repository }} + PR NUMBER: ${{ github.event.pull_request.number }} + + Perform a comprehensive code review with the following focus areas: + + 1. **Code Quality** + - Clean code principles and best practices + - Proper error handling and edge cases + - Code readability and maintainability + + 2. **Security** + - Check for potential security vulnerabilities + - Validate input sanitization + - Review authentication/authorization logic + + 3. **Performance** + - Identify potential performance bottlenecks + - Review database queries for efficiency + - Check for memory leaks or resource issues + + 4. **Testing** + - Verify adequate test coverage + - Review test quality and edge cases + - Check for missing test scenarios + + 5. **Documentation** + - Ensure code is properly documented + - Verify README updates for new features + - Check API documentation accuracy + + Provide detailed feedback using inline comments for specific issues. + Use top-level comments for general observations or praise. + Update the PR description section in the PR body with a concise summary for the human + reviewer that surfaces security and correctness risks, highlights suspicious diffs, and + provides a brief change summary. steps: - name: Checkout repository uses: actions/checkout@v5 @@ -93,6 +164,7 @@ jobs: - name: Run AI Agent uses: transferwise/claude-code-action@main with: + prompt: ${{ inputs.event_name == 'pull_request' && env.PR_PROMPT || '' }} trigger_phrase: "/run-ci-ai-agents" use_commit_signing: "true" anthropic_bedrock_base_url: ${{ secrets.ANTHROPIC_BEDROCK_BASE_URL }} @@ -106,5 +178,59 @@ jobs: api.github.com ${{ secrets.ANTHROPIC_BEDROCK_BASE_URL }} claude_args: | - --allowedTools "mcp__github_inline_comment__create_inline_comment,mcp__github_file_ops__commit_files,mcp__github_file_ops__delete_files" - --model ${{ inputs.generic_model != '' && inputs.generic_model || vars.ANTHROPIC_DEFAULT_HAIKU_MODEL }} \ No newline at end of file + --allowedTools "Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),mcp__github_inline_comment__create_inline_comment,mcp__github_file_ops__commit_files,mcp__github_file_ops__delete_file,mcp__github__update_pull_request" + --model ${{ inputs.generic_model != '' && inputs.generic_model || vars.ANTHROPIC_DEFAULT_OPUS_MODEL }} + + - name: Show Claude execution output + if: always() + run: | + cat /__w/_temp/claude-execution-output.json + + run-codex-agent: + needs: detect-agent + if: needs.detect-agent.outputs.agent == 'codex' + runs-on: gha-production-medium + # container: ci-images-release.arti.tw.ee/actions_java_17_and_21 + permissions: + contents: write + pull-requests: write + issues: write + id-token: write + actions: read + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + fetch-depth: 1 + + - name: "Add repo as safe directory" + run: | + git config --global --add safe.directory "$GITHUB_WORKSPACE" + + - name: Sync caller event context + shell: bash + env: + CALLER_EVENT_PAYLOAD: ${{ inputs.event_payload }} + run: | + event_file="$RUNNER_TEMP/original_event.json" + printf '%s' "$CALLER_EVENT_PAYLOAD" > "$event_file" + { + echo "GITHUB_EVENT_PATH=$event_file" + echo "GITHUB_EVENT_NAME=${{ inputs.event_name }}" + echo "GITHUB_REPOSITORY=${{ inputs.repository }}" + echo "GITHUB_REF=${{ inputs.ref }}" + echo "GITHUB_SHA=${{ inputs.sha }}" + echo "GITHUB_ACTOR=${{ inputs.actor }}" + } >> "$GITHUB_ENV" + + - name: Run Codex Agent + uses: transferwise/codex-action@v1.4-test + env: + GITHUB_API_URL: https://eu.api.openai.com + with: + prompt: ${{ needs.detect-agent.outputs.codex_prompt }} + openai-api-key: ${{ secrets.OPENAI_API_KEY }} + model: ${{ inputs.codex_model }} + sandbox: "workspace-write" + allow-users: "*" + safety-strategy: "unsafe" \ No newline at end of file diff --git a/workflow-templates/call-ci-ai-agents.yml b/workflow-templates/call-ci-ai-agents.yml index 93c7a47..3e63b52 100644 --- a/workflow-templates/call-ci-ai-agents.yml +++ b/workflow-templates/call-ci-ai-agents.yml @@ -13,10 +13,10 @@ on: jobs: call-ci-ai-agents: if: | - (github.event_name == 'issue_comment' && contains(github.event.comment.body, '/run-ci-ai-agents')) || - (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '/run-ci-ai-agents')) || - (github.event_name == 'pull_request_review' && contains(github.event.review.body, '/run-ci-ai-agents')) || - (github.event_name == 'issues' && (contains(github.event.issue.body, '/run-ci-ai-agents') || contains(github.event.issue.title, '/run-ci-ai-agents'))) + (github.event_name == 'issue_comment' && (contains(github.event.comment.body, '/run-ci-ai-agents') || contains(github.event.comment.body, '/codex-'))) || + (github.event_name == 'pull_request_review_comment' && (contains(github.event.comment.body, '/run-ci-ai-agents') || contains(github.event.comment.body, '/codex-'))) || + (github.event_name == 'pull_request_review' && (contains(github.event.review.body, '/run-ci-ai-agents') || contains(github.event.review.body, '/codex-'))) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '/run-ci-ai-agents') || contains(github.event.issue.title, '/run-ci-ai-agents') || contains(github.event.issue.body, '/codex-') || contains(github.event.issue.title, '/codex-'))) uses: transferwise/.github/.github/workflows/reusable-workflow-ci-ai-agents.yaml@master secrets: inherit with: