Writing pull request descriptions can be tedious, especially when you're focused on code. In this tutorial, you'll set up a GitHub Action that uses an AI agent (powered by OpenAI's GPT-4) to automatically generate a PR description from the diff. This workflow runs whenever a PR is opened or updated, saving you time and ensuring consistency.
Prerequisites
- Basic knowledge of GitHub Actions and YAML
- Python 3.9+ installed locally (for testing)
- An OpenAI API key (set as a repository secret)
- A GitHub repository with write access
Step 1: Create the Python Script
Create a file .github/scripts/generate_pr_description.py with the following code. It fetches the diff from the PR event, sends it to the AI, and writes the generated description to a file that the action will use.
import os
import json
import requests
# Get environment variables
diff = os.environ.get("DIFF", "")
api_key = os.environ.get("OPENAI_API_KEY")
if not diff or not api_key:
print("Missing DIFF or OPENAI_API_KEY")
exit(1)
prompt = f"""You are an expert code reviewer. Generate a concise pull request description from the following diff.
The description should include:
- Summary of changes
- Key modified files and their purpose
- Any potential impacts or considerations
Diff:
{diff[:6000]}
""" # Truncate to avoid token limits
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
data = {
"model": "gpt-4",
"messages": [
{"role": "user", "content": prompt}
],
"max_tokens": 500,
"temperature": 0.3
}
response = requests.post(
"https://api.openai.com/v1/chat/completions",
headers=headers,
json=data
)
response.raise_for_status()
description = response.json()["choices"][0]["message"]["content"]
# Save to file for later use
with open("/tmp/pr_description.txt", "w") as f:
f.write(description)
print("Description generated successfully")
Step 2: Create the GitHub Action Workflow
Create .github/workflows/auto-pr-description.yml:
name: Auto PR Description
on:
pull_request:
types: [opened, synchronize]
jobs:
generate-description:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Needed to get full diff
- name: Get diff
id: diff
run: |
git diff origin/${{ github.base_ref }}...${{ github.head_ref }} > /tmp/diff.txt
cat /tmp/diff.txt
shell: bash
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install dependencies
run: pip install requests
- name: Generate PR description
id: ai
env:
DIFF: ${{ steps.diff.outputs.diff_content }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: python .github/scripts/generate_pr_description.py
- name: Update PR description
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
DESCRIPTION=$(cat /tmp/pr_description.txt)
gh pr edit ${{ github.event.number }} --body "$DESCRIPTION"
run does not set outputs correctly. In the next step we'll fix this with a proper method.
Step 3: Fix the Diff Capture
The get diff step above will not save the diff to an output variable as written. Use this corrected version instead:
- name: Get diff
id: diff
run: |
DIFF_CONTENT=$(git diff origin/${{ github.base_ref }}...${{ github.head_ref }})
echo "diff_content<> $GITHUB_OUTPUT
echo "$DIFF_CONTENT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
shell: bash
Then update the Generate PR description step to use ${{ steps.diff.outputs.diff_content }} as the DIFF environment variable.
Step 4: Add the OpenAI API Key as a Secret
Go to your repository → Settings → Secrets and variables → Actions → New repository secret. Name it OPENAI_API_KEY and paste your key.
Step 5: Test the Workflow
Create a new branch, make a meaningful change, and open a PR. After a few seconds, you should see the PR description updated automatically with the AI-generated content.
Next Steps & Improvements
- Add error handling: if the API call fails, fall back to a default message.
- Use a cheaper model (e.g.,
gpt-3.5-turbo) for smaller diffs. - Include structured labels: append “AI-generated: review required”.
- Integrate with your ticket system by parsing branch names (e.g.,
JIRA-123-feature).
This workflow saves at least 5 minutes per PR and ensures consistent descriptions across your team. Happy coding! 🚀
Comments
No comments yet
Connect with Google to comment or reply.
Connect with Google