mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-14 01:30:37 +08:00
Merge pull request #853 from idubnori/feature/gha-outputs-1
feat: set review data to github actions output
This commit is contained in:
@ -119,10 +119,15 @@ Specifically, start by setting the following environment variables:
|
|||||||
github_action_config.auto_review: "true" # enable\disable auto review
|
github_action_config.auto_review: "true" # enable\disable auto review
|
||||||
github_action_config.auto_describe: "true" # enable\disable auto describe
|
github_action_config.auto_describe: "true" # enable\disable auto describe
|
||||||
github_action_config.auto_improve: "true" # enable\disable auto improve
|
github_action_config.auto_improve: "true" # enable\disable auto improve
|
||||||
|
github_action_config.enable_output: "true" # enable\disable github actions output parameter
|
||||||
```
|
```
|
||||||
`github_action_config.auto_review`, `github_action_config.auto_describe` and `github_action_config.auto_improve` are used to enable/disable automatic tools that run when a new PR is opened.
|
`github_action_config.auto_review`, `github_action_config.auto_describe` and `github_action_config.auto_improve` are used to enable/disable automatic tools that run when a new PR is opened.
|
||||||
If not set, the default configuration is for all three tools to run automatically when a new PR is opened.
|
If not set, the default configuration is for all three tools to run automatically when a new PR is opened.
|
||||||
|
|
||||||
|
`github_action_config.enable_output` are used to enable/disable github actions [output parameter](https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#outputs-for-docker-container-and-javascript-actions) (default is `true`).
|
||||||
|
Review result is output as JSON to `steps.{step-id}.outputs.review` property.
|
||||||
|
The JSON structure is equivalent to the yaml data structure defined in [pr_reviewer_prompts.toml](https://github.com/idubnori/pr-agent/blob/main/pr_agent/settings/pr_reviewer_prompts.toml).
|
||||||
|
|
||||||
Note that you can give additional config parameters by adding environment variables to `.github/workflows/pr_agent.yml`, or by using a `.pr_agent.toml` [configuration file](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/#global-configuration-file) in the root of your repo
|
Note that you can give additional config parameters by adding environment variables to `.github/workflows/pr_agent.yml`, or by using a `.pr_agent.toml` [configuration file](https://pr-agent-docs.codium.ai/usage-guide/configuration_options/#global-configuration-file) in the root of your repo
|
||||||
|
|
||||||
For example, you can set an environment variable: `pr_description.publish_labels=false`, or add a `.pr_agent.toml` file with the following content:
|
For example, you can set an environment variable: `pr_description.publish_labels=false`, or add a `.pr_agent.toml` file with the following content:
|
||||||
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import difflib
|
import difflib
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import textwrap
|
import textwrap
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@ -661,3 +662,15 @@ def find_line_number_of_relevant_line_in_file(diff_files: List[FilePatchInfo],
|
|||||||
absolute_position = start2 + delta - 1
|
absolute_position = start2 + delta - 1
|
||||||
break
|
break
|
||||||
return position, absolute_position
|
return position, absolute_position
|
||||||
|
|
||||||
|
def github_action_output(output_data: dict, key_name: str):
|
||||||
|
try:
|
||||||
|
if not get_settings().get('github_action_config.enable_output', False):
|
||||||
|
return
|
||||||
|
|
||||||
|
key_data = output_data.get(key_name, {})
|
||||||
|
with open(os.environ['GITHUB_OUTPUT'], 'a') as fh:
|
||||||
|
print(f"{key_name}={json.dumps(key_data, indent=None, ensure_ascii=False)}", file=fh)
|
||||||
|
except Exception as e:
|
||||||
|
get_logger().error(f"Failed to write to GitHub Action output: {e}")
|
||||||
|
return
|
@ -59,6 +59,8 @@ async def run_action():
|
|||||||
get_settings().set("OPENAI.ORG", OPENAI_ORG)
|
get_settings().set("OPENAI.ORG", OPENAI_ORG)
|
||||||
get_settings().set("GITHUB.USER_TOKEN", GITHUB_TOKEN)
|
get_settings().set("GITHUB.USER_TOKEN", GITHUB_TOKEN)
|
||||||
get_settings().set("GITHUB.DEPLOYMENT_TYPE", "user")
|
get_settings().set("GITHUB.DEPLOYMENT_TYPE", "user")
|
||||||
|
enable_output = get_setting_or_env("GITHUB_ACTION_CONFIG.ENABLE_OUTPUT", True)
|
||||||
|
get_settings().set("GITHUB_ACTION_CONFIG.ENABLE_OUTPUT", enable_output)
|
||||||
|
|
||||||
# Load the event payload
|
# Load the event payload
|
||||||
try:
|
try:
|
||||||
|
@ -140,6 +140,7 @@ try_fix_invalid_inline_comments = true
|
|||||||
# auto_review = true # set as env var in .github/workflows/pr-agent.yaml
|
# auto_review = true # set as env var in .github/workflows/pr-agent.yaml
|
||||||
# auto_describe = true # set as env var in .github/workflows/pr-agent.yaml
|
# auto_describe = true # set as env var in .github/workflows/pr-agent.yaml
|
||||||
# auto_improve = true # set as env var in .github/workflows/pr-agent.yaml
|
# auto_improve = true # set as env var in .github/workflows/pr-agent.yaml
|
||||||
|
# enable_output = true # set as env var in .github/workflows/pr-agent.yaml
|
||||||
|
|
||||||
[github_app]
|
[github_app]
|
||||||
# these toggles allows running the github app from custom deployments
|
# these toggles allows running the github app from custom deployments
|
||||||
|
@ -8,7 +8,7 @@ from pr_agent.algo.ai_handlers.base_ai_handler import BaseAiHandler
|
|||||||
from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler
|
from pr_agent.algo.ai_handlers.litellm_ai_handler import LiteLLMAIHandler
|
||||||
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
from pr_agent.algo.pr_processing import get_pr_diff, retry_with_fallback_models
|
||||||
from pr_agent.algo.token_handler import TokenHandler
|
from pr_agent.algo.token_handler import TokenHandler
|
||||||
from pr_agent.algo.utils import convert_to_markdown, load_yaml, ModelType
|
from pr_agent.algo.utils import convert_to_markdown, github_action_output, load_yaml, ModelType
|
||||||
from pr_agent.config_loader import get_settings
|
from pr_agent.config_loader import get_settings
|
||||||
from pr_agent.git_providers import get_git_provider
|
from pr_agent.git_providers import get_git_provider
|
||||||
from pr_agent.git_providers.git_provider import IncrementalPR, get_main_pr_language
|
from pr_agent.git_providers.git_provider import IncrementalPR, get_main_pr_language
|
||||||
@ -192,6 +192,7 @@ class PRReviewer:
|
|||||||
data = load_yaml(self.prediction.strip(),
|
data = load_yaml(self.prediction.strip(),
|
||||||
keys_fix_yaml=["estimated_effort_to_review_[1-5]:", "security_concerns:", "possible_issues:",
|
keys_fix_yaml=["estimated_effort_to_review_[1-5]:", "security_concerns:", "possible_issues:",
|
||||||
"relevant_file:", "relevant_line:", "suggestion:"])
|
"relevant_file:", "relevant_line:", "suggestion:"])
|
||||||
|
github_action_output(data, 'review')
|
||||||
|
|
||||||
if 'code_feedback' in data:
|
if 'code_feedback' in data:
|
||||||
code_feedback = data['code_feedback']
|
code_feedback = data['code_feedback']
|
||||||
|
50
tests/unittest/test_github_action_output.py
Normal file
50
tests/unittest/test_github_action_output.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import os
|
||||||
|
import json
|
||||||
|
from pr_agent.algo.utils import get_settings, github_action_output
|
||||||
|
|
||||||
|
class TestGitHubOutput:
|
||||||
|
def test_github_action_output_enabled(self, monkeypatch, tmp_path):
|
||||||
|
get_settings().set('GITHUB_ACTION_CONFIG.ENABLE_OUTPUT', True)
|
||||||
|
monkeypatch.setenv('GITHUB_OUTPUT', str(tmp_path / 'output'))
|
||||||
|
output_data = {'key1': {'value1': 1, 'value2': 2}}
|
||||||
|
key_name = 'key1'
|
||||||
|
|
||||||
|
github_action_output(output_data, key_name)
|
||||||
|
|
||||||
|
with open(str(tmp_path / 'output'), 'r') as f:
|
||||||
|
env_value = f.read()
|
||||||
|
|
||||||
|
actual_key = env_value.split('=')[0]
|
||||||
|
actual_data = json.loads(env_value.split('=')[1])
|
||||||
|
|
||||||
|
assert actual_key == key_name
|
||||||
|
assert actual_data == output_data[key_name]
|
||||||
|
|
||||||
|
def test_github_action_output_disabled(self, monkeypatch, tmp_path):
|
||||||
|
get_settings().set('GITHUB_ACTION_CONFIG.ENABLE_OUTPUT', False)
|
||||||
|
monkeypatch.setenv('GITHUB_OUTPUT', str(tmp_path / 'output'))
|
||||||
|
output_data = {'key1': {'value1': 1, 'value2': 2}}
|
||||||
|
key_name = 'key1'
|
||||||
|
|
||||||
|
github_action_output(output_data, key_name)
|
||||||
|
|
||||||
|
assert not os.path.exists(str(tmp_path / 'output'))
|
||||||
|
|
||||||
|
def test_github_action_output_notset(self, monkeypatch, tmp_path):
|
||||||
|
# not set config
|
||||||
|
monkeypatch.setenv('GITHUB_OUTPUT', str(tmp_path / 'output'))
|
||||||
|
output_data = {'key1': {'value1': 1, 'value2': 2}}
|
||||||
|
key_name = 'key1'
|
||||||
|
|
||||||
|
github_action_output(output_data, key_name)
|
||||||
|
|
||||||
|
assert not os.path.exists(str(tmp_path / 'output'))
|
||||||
|
|
||||||
|
def test_github_action_output_error_case(self, monkeypatch, tmp_path):
|
||||||
|
monkeypatch.setenv('GITHUB_OUTPUT', str(tmp_path / 'output'))
|
||||||
|
output_data = None # invalid data
|
||||||
|
key_name = 'key1'
|
||||||
|
|
||||||
|
github_action_output(output_data, key_name)
|
||||||
|
|
||||||
|
assert not os.path.exists(str(tmp_path / 'output'))
|
Reference in New Issue
Block a user