|
1 | | -name: 'Code Review GPT' |
2 | | -description: 'Reviews PR changes with a GPT model from OpenAI' |
3 | | -author: 'Orion Tools' |
| 1 | + |
| 2 | +name: 'Code Review GPT Action' |
| 3 | +description: 'Выполняет автоматический code review с использованием GPT и интеграцией с JIRA' |
| 4 | + |
4 | 5 | inputs: |
5 | | - MODEL: |
6 | | - description: 'Model name to use for review' |
7 | | - required: true |
8 | | - default: 'gpt-4o' |
9 | | - REVIEW_LANGUAGE: |
10 | | - description: 'Target natural language for translation' |
| 6 | + target_branch: |
| 7 | + description: 'Целевая ветка для сравнения (по умолчанию main)' |
11 | 8 | required: false |
12 | | - default: 'English' |
13 | | - OPENAI_API_KEY: |
| 9 | + default: 'main' |
| 10 | + openai_api_key: |
14 | 11 | description: 'OpenAI API Key' |
15 | 12 | required: true |
16 | | - GITHUB_TOKEN: |
17 | | - description: 'Github token' |
18 | | - required: true |
19 | | - OPENAI_BASE_URL: |
20 | | - description: 'OpenAI API Base URL' |
| 13 | + jira_token: |
| 14 | + description: 'JIRA API Token' |
21 | 15 | required: false |
| 16 | + jira_user: |
| 17 | + description: 'JIRA User' |
| 18 | + required: false |
| 19 | + jira_base_url: |
| 20 | + description: 'JIRA Base URL' |
| 21 | + required: false |
| 22 | + github_token: |
| 23 | + description: 'GitHub Token для доступа к PR' |
| 24 | + required: true |
| 25 | + |
| 26 | + |
| 27 | +outputs: |
| 28 | + review_result: |
| 29 | + description: 'Результат code review' |
| 30 | + value: ${{ steps.code_review.outputs.review_result }} |
| 31 | + jira_result: |
| 32 | + description: 'Форматированный результат для JIRA' |
| 33 | + value: ${{ steps.code_review.outputs.jira_result }} |
| 34 | + comment_url: |
| 35 | + description: 'URL комментария с ревью' |
| 36 | + value: ${{ steps.code_review.outputs.comment_url }} |
| 37 | + |
22 | 38 | runs: |
23 | 39 | using: 'composite' |
24 | 40 | steps: |
| 41 | + - uses: actions/checkout@v3 |
| 42 | + with: |
| 43 | + fetch-depth: 0 |
| 44 | + |
| 45 | + - name: Resolve TARGET_BRANCH |
| 46 | + shell: bash |
| 47 | + run: | |
| 48 | + if [ "${{ github.event_name }}" = "repository_dispatch" ]; then |
| 49 | + TARGET_BRANCH_FROM_EVENT="${{ github.event.client_payload.target_branch }}" |
| 50 | + else |
| 51 | + TARGET_BRANCH_FROM_EVENT="${{ inputs.target_branch }}" |
| 52 | + fi |
| 53 | +
|
| 54 | + if [ -z "$TARGET_BRANCH_FROM_EVENT" ]; then |
| 55 | + TARGET_BRANCH_FROM_EVENT="main" |
| 56 | + fi |
| 57 | +
|
| 58 | + echo "TARGET_BRANCH=$TARGET_BRANCH_FROM_EVENT" >> $GITHUB_ENV |
| 59 | +
|
| 60 | + - name: Set BASE_SHA |
| 61 | + shell: bash |
| 62 | + run: | |
| 63 | + if [ "${{ github.event_name }}" = "pull_request" ]; then |
| 64 | + echo "BASE_SHA=${{ github.event.pull_request.base.sha }}" >> $GITHUB_ENV |
| 65 | + else |
| 66 | + BASE_SHA=$(git merge-base origin/$TARGET_BRANCH HEAD) |
| 67 | + CURRENT_SHA=$(git rev-parse HEAD) |
| 68 | + echo "BASE_SHA = $BASE_SHA / CURRENT_SHA = $CURRENT_SHA" |
| 69 | + |
| 70 | + if [ "$BASE_SHA" = "$CURRENT_SHA" ]; then |
| 71 | + echo "BASE_SHA=$(git rev-parse HEAD~1)" >> $GITHUB_ENV |
| 72 | + else |
| 73 | + echo "BASE_SHA=$BASE_SHA" >> $GITHUB_ENV |
| 74 | + fi |
| 75 | + fi |
| 76 | +
|
25 | 77 | - uses: oven-sh/setup-bun@v2 |
26 | 78 | with: |
27 | 79 | bun-version: latest |
28 | | - |
| 80 | + |
29 | 81 | - name: Install and Run Code Review GPT |
| 82 | + id: code_review |
| 83 | + shell: bash |
| 84 | + run: | |
| 85 | + git clone https://github.com/forproxyband/code-review-gpt.git |
| 86 | + cd code-review-gpt |
| 87 | + rm -rf .git |
| 88 | + bun install |
| 89 | + bun run review --ci=github --modelString=openai:gpt-4o --reviewLanguage=Russian --reviewType=changed |
| 90 | + env: |
| 91 | + OPENAI_API_KEY: ${{ inputs.openai_api_key }} |
| 92 | + BASE_SHA: ${{ env.BASE_SHA }} |
| 93 | + GITHUB_TOKEN: ${{ inputs.github_token }} |
| 94 | + |
| 95 | + - name: Extract JIRA ticket |
30 | 96 | shell: bash |
31 | 97 | run: | |
32 | | - bun add code-review-gpt@latest |
33 | | - bun code-review-gpt review --ci=github --model=$MODEL --reviewLanguage=$REVIEW_LANGUAGE |
| 98 | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then |
| 99 | + RUN_TITLE="${{ github.event.workflow.name }} ${{ github.run_number }}" |
| 100 | + JIRA_TICKET=$(echo $RUN_TITLE | grep -oP '[A-Z]+-\d+' || echo "") |
| 101 | + elif [ "${{ github.event_name }}" = "pull_request" ]; then |
| 102 | + TITLE="${{ github.event.pull_request.title }}" |
| 103 | + JIRA_TICKET=$(echo $TITLE | grep -oP '[A-Z]+-\d+' || echo "") |
| 104 | + else |
| 105 | + COMMIT_MSG=$(git log -1 --pretty=%B) |
| 106 | + JIRA_TICKET=$(echo $COMMIT_MSG | grep -oP '[A-Z]+-\d+' || echo "") |
| 107 | + fi |
| 108 | + |
| 109 | + if [ -n "$JIRA_TICKET" ]; then |
| 110 | + echo "Найден код задачи JIRA: $JIRA_TICKET" |
| 111 | + echo "JIRA_TICKET=$JIRA_TICKET" >> $GITHUB_ENV |
| 112 | + else |
| 113 | + echo "Код задачи JIRA не найден" |
| 114 | + fi |
| 115 | +
|
| 116 | + - name: Comment to JIRA |
| 117 | + if: env.JIRA_TICKET != '' && inputs.jira_token != '' |
| 118 | + shell: bash |
| 119 | + run: | |
| 120 | + echo '{ |
| 121 | + "body": "'"${REVIEW_RESULT}"'\n |
| 122 | + [✨ Детальная информация|'"${COMMENT_URL}"']" |
| 123 | + }' > comment.json |
| 124 | +
|
| 125 | + curl --request POST \ |
| 126 | + --user "${{ inputs.jira_user }}:${{ inputs.jira_token }}" \ |
| 127 | + --header "Accept: application/json" \ |
| 128 | + --header "Content-Type: application/json" \ |
| 129 | + --url "${{ inputs.jira_base_url }}/rest/api/2/issue/${JIRA_TICKET}/comment" \ |
| 130 | + -d @comment.json |
34 | 131 | env: |
35 | | - MODEL: ${{ inputs.MODEL }} |
36 | | - REVIEW_LANGUAGE: ${{ inputs.REVIEW_LANGUAGE }} |
37 | | - OPENAI_API_KEY: ${{ inputs.OPENAI_API_KEY }} |
38 | | - BASE_SHA: ${{ github.event.pull_request.base.sha }} |
39 | | - GITHUB_TOKEN: ${{ inputs.GITHUB_TOKEN }} |
40 | | - OPENAI_BASE_URL: ${{ inputs.OPENAI_BASE_URL }} |
| 132 | + REVIEW_RESULT: ${{ steps.code_review.outputs.jira_result }} |
| 133 | + GITHUB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} |
| 134 | + COMMENT_URL: ${{ steps.code_review.outputs.comment_url }} |
41 | 135 |
|
42 | 136 | branding: |
43 | 137 | icon: 'code' |
|
0 commit comments