Last active
February 24, 2026 18:40
-
-
Save xpepper/ae551dbd20782ea79f989658a44f7e24 to your computer and use it in GitHub Desktop.
A script for using gh and copilot to create PR descriptions out of their git diff
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # pr-summarise: Generate and apply a PR description using GitHub Models. | |
| # Usage: pr-summarise [PR number] | |
| # If no PR number is given, uses the current branch's open PR. | |
| # | |
| # Required tools: | |
| # gh - GitHub CLI (https://cli.github.com), authenticated via `gh auth login` | |
| # curl - HTTP client, used to call the GitHub Models API | |
| # jq - JSON processor (https://jqlang.org) | |
| set -euo pipefail | |
| # ── Config ──────────────────────────────────────────────────────────────────── | |
| MODEL="${PR_SUMMARISE_MODEL:-openai/gpt-4.1}" | |
| MAX_DIFF_CHARS="${PR_SUMMARISE_MAX_DIFF_CHARS:-28000}" | |
| ENDPOINT="${PR_SUMMARISE_ENDPOINT:-https://models.github.ai/inference/chat/completions}" | |
| # For org attribution, set: | |
| # export PR_SUMMARISE_ENDPOINT="https://models.github.ai/orgs/<ORG>/inference/chat/completions" | |
| # ── Resolve PR number ───────────────────────────────────────────────────────── | |
| if [[ $# -ge 1 ]]; then | |
| PR="$1" | |
| else | |
| if ! PR=$(gh pr view --json number -q '.number' 2>/dev/null); then | |
| echo "Error: no PR number given and no open PR found for the current branch." >&2 | |
| exit 1 | |
| fi | |
| fi | |
| # ── Fetch existing PR description ───────────────────────────────────────────── | |
| EXISTING_BODY=$(gh pr view "$PR" --json body -q '.body // ""') | |
| MARKER="<!-- pr-summarise -->" | |
| if [[ -n "$EXISTING_BODY" && "$EXISTING_BODY" != *"$MARKER"* ]]; then | |
| echo "PR #$PR already has a human-written description. Skipping." >&2 | |
| echo "" | |
| echo "$EXISTING_BODY" | |
| exit 0 | |
| fi | |
| # ── Fetch diff ──────────────────────────────────────────────────────────────── | |
| echo "Fetching diff for PR #$PR..." | |
| FULL_DIFF=$(gh pr diff "$PR" --patch) | |
| DIFF="${FULL_DIFF:0:$MAX_DIFF_CHARS}" | |
| if [[ -z "$DIFF" ]]; then | |
| echo "Error: no diff found for PR #$PR." >&2 | |
| exit 1 | |
| fi | |
| # ── Call GitHub Models ──────────────────────────────────────────────────────── | |
| echo "Generating summary via GitHub Models ($MODEL)..." | |
| RESPONSE=$(curl -sS -L "$ENDPOINT" \ | |
| -H "Authorization: Bearer $(gh auth token)" \ | |
| -H "Accept: application/vnd.github+json" \ | |
| -H "X-GitHub-Api-Version: 2022-11-28" \ | |
| -H "Content-Type: application/json" \ | |
| -d "$(jq -n \ | |
| --arg model "$MODEL" \ | |
| --arg diff "$DIFF" \ | |
| '{ | |
| model: $model, | |
| temperature: 0.2, | |
| max_tokens: 500, | |
| messages: [{ | |
| role: "user", | |
| content: | |
| "Write a concise GitHub PR description in Markdown for this diff.\n" + | |
| "Format:\n" + | |
| "1) One short summary paragraph.\n" + | |
| "2) A \"## Changes\" section with bullet points.\n" + | |
| "3) A \"## Notes for reviewers\" section (optional, only if useful).\n" + | |
| "Output only Markdown, nothing else.\n\n" + $diff | |
| }] | |
| }')") | |
| SUMMARY=$(echo "$RESPONSE" | jq -r '.choices[0].message.content') | |
| if [[ -z "$SUMMARY" || "$SUMMARY" == "null" ]]; then | |
| echo "Error: empty response from GitHub Models. Raw response:" >&2 | |
| echo "$RESPONSE" >&2 | |
| exit 1 | |
| fi | |
| # ── Compose final body ──────────────────────────────────────────────────────── | |
| FINAL_BODY="${SUMMARY}"$'\n\n'"${MARKER}" | |
| # ── Review and confirm ──────────────────────────────────────────────────────── | |
| echo "" | |
| echo "──── Generated description ────────────────────────────────────────────────" | |
| echo "$FINAL_BODY" | |
| echo "───────────────────────────────────────────────────────────────────────────" | |
| echo "" | |
| read -r -p "Apply this description to PR #$PR? [y/N] " confirm | |
| if [[ "$confirm" =~ ^[Yy]$ ]]; then | |
| gh pr edit "$PR" --body "$FINAL_BODY" | |
| echo "PR #$PR description updated." | |
| else | |
| echo "Aborted. No changes made." | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment