Skip to content

Commit 630ac96

Browse files
authored
Add example of how to leverage OpenAI reasoning models to SDLC for code quality and security checks. (openai#1610)
1 parent ee98bc0 commit 630ac96

File tree

5 files changed

+271
-1
lines changed

5 files changed

+271
-1
lines changed
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
# Reasoning over Code Quality and Security in GitHub Pull Requests
2+
3+
## Introduction
4+
This guide explains how to integrate OpenAI reasoning models into your GitHub Pull Request (PR) workflow to automatically review code for quality, security, and enterprise standards compliance. By leveraging AI-driven insights early in the development process, you can catch issues sooner, reduce manual effort, and maintain consistent best practices across your codebase.
5+
6+
## Why Integrate OpenAI Reasoning Models in PRs?
7+
• Save time during code reviews by automatically detecting code smells, security vulnerabilities, and style inconsistencies.
8+
• Enforce coding standards organization-wide for consistent, reliable code.
9+
• Provide developers with prompt, AI-guided feedback on potential improvements.
10+
11+
## Example Use Cases
12+
• A reviewer wants feedback on the security of a new code change before merging.
13+
• A team seeks to enforce standard coding guidelines, ensuring consistent code quality across the organization.
14+
15+
## Prerequisites
16+
17+
### 1. Generate an OpenAI “Project Key”
18+
1. Go to platform.openai.com/api-keys and click to create a new secret key.
19+
2. Securely store the token in your GitHub repository secrets as OPENAI_API_KEY.
20+
21+
### 2. Choose Your OpenAI Model
22+
Use [OpenAI Reasoning Models](https://platform.openai.com/docs/guides/reasoning) for in-depth analysis of code changes. Begin with the most advanced model and refine your prompt as needed.
23+
24+
### 3. Select a Pull Request
25+
1. Confirm GitHub Actions is enabled for your repository.
26+
2. Ensure you have permissions to configure repository secrets or variables (e.g., for your PROMPT, MODELNAME, and BEST_PRACTICES variables).
27+
28+
### 4. Define Enterprise Coding Standards
29+
Store your standards as a repository variable (BEST_PRACTICES). These may include:
30+
• Code style & formatting
31+
• Readability & maintainability
32+
• Security & compliance
33+
• Error handling & logging
34+
• Performance & scalability
35+
• Testing & QA
36+
• Documentation & version control
37+
• Accessibility & internationalization
38+
39+
### 5. Define Prompt Content
40+
Construct a meta-prompt to guide OpenAI toward security, quality, and best-practice checks. Include:
41+
1. Code Quality & Standards
42+
2. Security & Vulnerability Analysis
43+
3. Fault Tolerance & Error Handling
44+
4. Performance & Resource Management
45+
5. Step-by-Step Validation
46+
47+
Encourage OpenAI to provide a thorough, line-by-line review with explicit recommendations.
48+
49+
## Create Your GitHub Actions Workflow
50+
51+
This GitHub Actions workflow is triggered on every pull request against the main branch and comprises two jobs. The first job gathers a diff of all changed files—excluding .json and .png files—and sends these changes to OpenAI for analysis. Any suggested fixes from OpenAI are included in a comment on the PR. The second job evaluates the PR against your defined enterprise standards and returns a markdown table that summarizes the code’s adherence to those standards. You can easily adjust or refine the workflow by updating variables such as the prompt, model name, and best practices.
52+
53+
```yaml
54+
name: PR Quality and Security Check
55+
56+
on:
57+
pull_request:
58+
branches: [main]
59+
60+
permissions:
61+
contents: read
62+
pull-requests: write
63+
64+
jobs:
65+
quality-security-analysis:
66+
runs-on: ubuntu-latest
67+
steps:
68+
- name: Check out code
69+
uses: actions/checkout@v3
70+
with:
71+
fetch-depth: 0 # Ensure full history for proper diff
72+
73+
- name: Gather Full Code From Changed Files
74+
run: |
75+
CHANGED_FILES=$(git diff --name-only origin/main...HEAD)
76+
echo '{"original files": [' > original_files_temp.json
77+
for file in $CHANGED_FILES; do
78+
if [[ $file == *.json ]] || [[ $file == *.png ]]; then
79+
continue
80+
fi
81+
if [ -f "$file" ]; then
82+
CONTENT=$(jq -Rs . < "$file")
83+
echo "{\"filename\": \"$file\", \"content\": $CONTENT}," >> original_files_temp.json
84+
fi
85+
done
86+
sed -i '$ s/,$//' original_files_temp.json
87+
echo "]}" >> original_files_temp.json
88+
89+
- name: Display Processed Diff (Debug)
90+
run: cat original_files_temp.json
91+
92+
- name: Get Diff
93+
run: |
94+
git diff origin/main...HEAD \
95+
| grep '^[+-]' \
96+
| grep -Ev '^(---|\+\+\+)' > code_changes_only.txt
97+
jq -Rs '{diff: .}' code_changes_only.txt > diff.json
98+
if [ -f original_files_temp.json ]; then
99+
jq -s '.[0] * .[1]' diff.json original_files_temp.json > combined.json
100+
mv combined.json diff.json
101+
102+
- name: Display Processed Diff (Debug)
103+
run: cat diff.json
104+
105+
- name: Analyze with OpenAI
106+
env:
107+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
108+
run: |
109+
DIFF_CONTENT=$(jq -r '.diff' diff.json)
110+
ORIGINAL_FILES=$(jq -r '."original files"' diff.json)
111+
PROMPT="Please review the following code changes for any obvious quality or security issues. Provide a brief report in markdown format:\n\nDIFF:\n${DIFF_CONTENT}\n\nORIGINAL FILES:\n${ORIGINAL_FILES}"
112+
jq -n --arg prompt "$PROMPT" '{
113+
"model": "gpt-4",
114+
"messages": [
115+
{ "role": "system", "content": "You are a code reviewer." },
116+
{ "role": "user", "content": $prompt }
117+
]
118+
}' > request.json
119+
curl -sS https://api.openai.com/v1/chat/completions \
120+
-H "Content-Type: application/json" \
121+
-H "Authorization: Bearer ${OPENAI_API_KEY}" \
122+
-d @request.json > response.json
123+
124+
- name: Extract Review Message
125+
id: extract_message
126+
run: |
127+
ASSISTANT_MSG=$(jq -r '.choices[0].message.content' response.json)
128+
{
129+
echo "message<<EOF"
130+
echo "$ASSISTANT_MSG"
131+
echo "EOF"
132+
} >> $GITHUB_OUTPUT
133+
134+
- name: Post Comment to PR
135+
env:
136+
COMMENT: ${{ steps.extract_message.outputs.message }}
137+
GH_TOKEN: ${{ github.token }}
138+
run: |
139+
gh api \
140+
repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments \
141+
-f body="$COMMENT"
142+
enterprise-standard-check:
143+
runs-on: ubuntu-latest
144+
needs: [quality-security-analysis]
145+
146+
steps:
147+
- name: Checkout code
148+
uses: actions/checkout@v3
149+
with:
150+
fetch-depth: 0 # ensures we get both PR base and head
151+
152+
- name: Gather Full Code From Changed Files
153+
run: |
154+
# Identify changed files from the base (origin/main) to the pull request HEAD
155+
CHANGED_FILES=$(git diff --name-only origin/main...HEAD)
156+
157+
# Build a JSON array containing filenames and their content
158+
echo '{"original files": [' > original_files_temp.json
159+
for file in $CHANGED_FILES; do
160+
# Skip .json and .txt files
161+
if [[ $file == *.json ]] || [[ $file == *.txt ]]; then
162+
continue
163+
fi
164+
165+
# If the file still exists (i.e., wasn't deleted)
166+
if [ -f "$file" ]; then
167+
CONTENT=$(jq -Rs . < "$file")
168+
echo "{\"filename\": \"$file\", \"content\": $CONTENT}," >> original_files_temp.json
169+
fi
170+
done
171+
172+
# Remove trailing comma on the last file entry and close JSON
173+
sed -i '$ s/,$//' original_files_temp.json
174+
echo "]}" >> original_files_temp.json
175+
176+
- name: Analyze Code Against Best Practices
177+
id: validate
178+
env:
179+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
180+
run: |
181+
set -e
182+
# Read captured code
183+
ORIGINAL_FILES=$(cat original_files_temp.json)
184+
185+
# Construct the prompt:
186+
# - Summarize each best-practice category
187+
# - Provide a rating for each category: 'extraordinary', 'acceptable', or 'poor'
188+
# - Return a Markdown table titled 'Enterprise Standards'
189+
PROMPT="You are an Enterprise Code Assistant. Review each code snippet below for its adherence to the following categories:
190+
1) Code Style & Formatting
191+
2) Security & Compliance
192+
3) Error Handling & Logging
193+
4) Readability & Maintainability
194+
5) Performance & Scalability
195+
6) Testing & Quality Assurance
196+
7) Documentation & Version Control
197+
8) Accessibility & Internationalization
198+
199+
Using \${{ vars.BEST_PRACTICES }} as a reference, assign a rating of 'extraordinary', 'acceptable', or 'poor' for each category. Return a markdown table titled 'Enterprise Standards' with rows for each category and columns for 'Category' and 'Rating'.
200+
201+
Here are the changed file contents to analyze:
202+
$ORIGINAL_FILES"
203+
204+
# Create JSON request for OpenAI
205+
jq -n --arg system_content "You are an Enterprise Code Assistant ensuring the code follows best practices." \
206+
--arg user_content "$PROMPT" \
207+
'{
208+
"model": "${{ vars.MODELNAME }}",
209+
"messages": [
210+
{
211+
"role": "system",
212+
"content": $system_content
213+
},
214+
{
215+
"role": "user",
216+
"content": $user_content
217+
}
218+
]
219+
}' > request.json
220+
221+
# Make the API call
222+
curl -sS https://api.openai.com/v1/chat/completions \
223+
-H "Content-Type: application/json" \
224+
-H "Authorization: Bearer $OPENAI_API_KEY" \
225+
-d @request.json > response.json
226+
227+
# Extract the model's message
228+
ASSISTANT_MSG=$(jq -r '.choices[0].message.content' response.json)
229+
230+
# Store for next step
231+
{
232+
echo "review<<EOF"
233+
echo "$ASSISTANT_MSG"
234+
echo "EOF"
235+
} >> $GITHUB_OUTPUT
236+
237+
- name: Post Table Comment
238+
env:
239+
COMMENT: ${{ steps.validate.outputs.review }}
240+
GH_TOKEN: ${{ github.token }}
241+
run: |
242+
# If COMMENT is empty or null, skip posting
243+
if [ -z "$COMMENT" ] || [ "$COMMENT" = "null" ]; then
244+
echo "No comment to post."
245+
exit 0
246+
fi
247+
248+
gh api \
249+
repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments \
250+
-f body="$COMMENT"
251+
```
252+
253+
## Test the Workflow
254+
Commit this workflow to your repository, then open a new PR. The workflow will run automatically, posting AI-generated feedback as a PR comment.
255+
256+
*For a public example, see the OpenAI-Forum repository’s workflow: [pr_quality_and_security_check.yml](https://github.com/alwell-kevin/OpenAI-Forum/blob/main/.github/workflows/pr_quality_and_security_check.yml).*
257+
258+
![pr_quality_and_security_check.png](../../images/pr_quality_and_security_check.png)
259+
260+
![workflow_check.png](../../images/workflow_check.png)
288 KB
Loading

images/repository_variables.png

421 KB
Loading

images/workflow_check.png

100 KB
Loading

registry.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1761,10 +1761,20 @@
17611761
- chatgpt
17621762
- chatgpt-middleware
17631763

1764+
- title: Reasoning over Code Quality and Security in GitHub Pull Requests
1765+
path: examples/third_party/Code_quality_and_security_scan_with_GitHub_Actions.md
1766+
date: 2024-12-24
1767+
authors:
1768+
- alwell-kevin
1769+
tags:
1770+
- SDLC
1771+
- reasoning
1772+
- completions
1773+
17641774
- title: How to evaluate LLMs for SQL generation
17651775
path: examples/evaluation/How_to_evaluate_LLMs_for_SQL_generation.ipynb
17661776
date: 2024-01-23
17671777
authors:
17681778
- colin-jarvis
17691779
tags:
1770-
- guardrails
1780+
- guardrails

0 commit comments

Comments
 (0)