Recipes · coding

PR Description Generator

Genera descripciones de pull requests completas y bien estructuradas a partir de un diff. Incluye resumen, motivación, cambios y checklist de testing.

claude-sonnet-4-5codinggitprautomationgithubActualizado 2026-04-23

System Prompt

You are a technical writer specializing in pull request descriptions. Given a
git diff and optional context, produce a well-structured PR description.

## Output format (Markdown)
Use exactly this structure:

## Summary
One paragraph (3–5 sentences) describing WHAT changed and WHY. Focus on
the intent, not the implementation details.

## Changes
A bulleted list of the specific changes made, grouped by area if possible.
Use past tense: "Added…", "Fixed…", "Removed…", "Refactored…".

## Motivation
One paragraph explaining WHY this change was needed. What problem does it
solve? What was the previous behavior and why was it insufficient?

## Testing
- [ ] Unit tests added/updated
- [ ] Manual testing steps (if applicable)
- [ ] Edge cases considered

## Notes
Any important caveats, follow-up tasks, or areas that need special review
attention. Omit this section if there are none.

## Rules
- Do not invent features or changes not present in the diff.
- Keep the Summary under 100 words.
- Use present tense in section headers, past tense in bullet points.
- If the diff is too large to fully analyze, say so and focus on the most
  significant changes.

User Prompt template

Generate a PR description for the following diff.

{{#if ticket}}
Related ticket: {{TICKET_URL}}
{{/if}}

{{#if context}}
Additional context from the author:
{{AUTHOR_CONTEXT}}
{{/if}}

Diff:
```diff
{{GIT_DIFF}}

## Implementación (TypeScript + GitHub Actions)

```typescript
import Anthropic from "@anthropic-ai/sdk";
import { execSync } from "child_process";

const client = new Anthropic();

async function generatePRDescription(options: {
  baseBranch?: string;
  ticketUrl?: string;
  authorContext?: string;
}): Promise<string> {
  const { baseBranch = "main", ticketUrl, authorContext } = options;

  // Get the diff against the base branch
  const diff = execSync(`git diff ${baseBranch}...HEAD`, {
    encoding: "utf-8",
    maxBuffer: 1024 * 1024 * 10, // 10MB
  });

  // Truncate very large diffs
  const MAX_DIFF_CHARS = 80_000;
  const truncatedDiff =
    diff.length > MAX_DIFF_CHARS
      ? `${diff.slice(0, MAX_DIFF_CHARS)}\n\n[... diff truncated — ${diff.length} total chars]`
      : diff;

  const userContent = [
    "Generate a PR description for the following diff.",
    ticketUrl ? `\nRelated ticket: ${ticketUrl}` : "",
    authorContext ? `\nContext from author:\n${authorContext}` : "",
    `\nDiff:\n\`\`\`diff\n${truncatedDiff}\n\`\`\``,
  ]
    .filter(Boolean)
    .join("\n");

  const response = await client.messages.create({
    model: "claude-sonnet-4-5",
    max_tokens: 2048,
    system: PR_DESCRIPTION_SYSTEM_PROMPT,
    messages: [{ role: "user", content: userContent }],
  });

  return response.content
    .filter((b): b is Anthropic.TextBlock => b.type === "text")
    .map((b) => b.text)
    .join("");
}

// CLI usage
const description = await generatePRDescription({
  baseBranch: process.env.BASE_BRANCH ?? "main",
  ticketUrl: process.env.TICKET_URL,
  authorContext: process.env.PR_CONTEXT,
});

console.log(description);

GitHub Actions workflow

yaml
name: Generate PR Description
on:
  pull_request:
    types: [opened]
 
jobs:
  generate-description:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
 
      - name: Generate PR description
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          BASE_BRANCH: ${{ github.base_ref }}
        run: |
          npx tsx scripts/generate-pr-description.ts > pr_body.md
 
      - name: Update PR body
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          gh pr edit ${{ github.event.number }} --body-file pr_body.md

Para diffs muy grandes (más de 100 archivos), considera enviar solo los archivos más importantes o usar git diff --stat para generar un resumen de cambios antes de pasar el diff completo al modelo.

Variaciones

  • Commit message: cambia el formato a una línea de subject + cuerpo convencional (feat:, fix:, etc.)
  • Release notes: adapta para generar changelogs agrupando por tipo de cambio
  • RFC / Design doc: sustituye el diff por una descripción de arquitectura y ajusta las secciones