DEV Community

Shusetsu Toda
Shusetsu Toda

Posted on

How I Built an AI Changelog Generator That Writes Release Notes for Three Different Audience

The Problem Nobody Wants to Own

Every team I've been on has the same ritual. Sprint ends. Someone asks: "Can you write up what shipped?" The room goes quiet.

Developers don't want to do it because they already wrote PR descriptions. Product managers don't want to do it because they don't understand half the technical changes. And customers? They get either nothing or a wall of jargon.

The real pain isn't writing a changelog. It's writing three:

  1. Technical changelog for developers — breaking changes, migration notes, API diffs
  2. Product changelog for PMs and internal stakeholders — features, UX changes, bugs fixed
  3. Customer-facing release notes — polished, non-technical, ready for a blog or newsletter

Same PRs. Three completely different documents. Nobody has time for that.

Existing Tools Fall Short

I looked at what's out there:

  • Release Drafter — Template-based, requires strict PR labeling. One format only.
  • GitHub's native release notes — Auto-generated from PR titles. Bare minimum.
  • semantic-release — Requires conventional commit discipline. Developer-facing only.
  • Changelogfy — Manual editor. Defeats the purpose.

None of them generate multi-audience content. None of them understand the context of changes beyond titles and labels.

Building ShipLogs

I built ShipLogs — a GitHub App that watches merged PRs and generates changelogs for developers, product teams, and customers automatically.

Architecture

GitHub (webhook) → Next.js API → Claude AI → Supabase → Dashboard
Enter fullscreen mode Exit fullscreen mode

Tech stack:

  • Next.js 16 (App Router) on Vercel
  • Supabase (PostgreSQL) for data storage
  • Claude API (Sonnet) for generation
  • Stripe for billing
  • TypeScript in strict mode throughout

How the GitHub App Works

When you install the ShipLogs GitHub App on your org or repos, it registers a webhook for pull request events. When a PR is merged, the webhook fires and we capture:

  • PR title and description
  • Diff summary (files changed, additions, deletions)
  • Labels
  • Linked issues
  • Author

This data goes into Supabase. When you trigger changelog generation (or it runs automatically), we batch the merged PRs and send them to Claude.

The AI Prompting Approach

The interesting part is how we get three distinct outputs from the same input. Each audience mode has a different system prompt that tells Claude:

  • Developer mode: "Focus on technical impact. Highlight breaking changes, new APIs, deprecations, and migration steps. Use precise technical language."
  • Product mode: "Translate technical changes into feature and UX language. Group by user impact. Skip internal refactoring unless it affects performance."
  • Customer mode: "Write as if this is going on a public blog. Lead with benefits, not implementation. No jargon. No PR numbers."

We use Claude's structured output (Zod schemas) so the response is always parseable — title, summary, categorized entries, and metadata.

Prompt caching cuts costs significantly. The system prompt is cached with cache_control: { type: "ephemeral" }, so repeated calls within a window only pay for the PR-specific input. Cost per changelog: roughly $0.06.

Multi-Audience Output Example

From the same set of PRs:

Developer mode:

Breaking: AuthMiddleware now requires explicit session configuration. Migration: update middleware.ts to pass sessionConfig option.

Added: Rate limiting on /api/webhooks/* endpoints (100 req/min). Uses sliding window with Redis backend.

Product mode:

Improved: Login flow is now faster and more reliable with updated session handling.

Infrastructure: API endpoints are now protected against traffic spikes, improving stability during high-usage periods.

Customer mode:

Faster login — We've improved the sign-in experience so you can get to your dashboard quicker.

Better reliability — Behind-the-scenes improvements to keep ShipLogs running smoothly, even during peak hours.

Same changes. Three lenses. That's the value.

Daily PR Summaries via Slack

For teams on the Team plan, ShipLogs sends a daily digest of merged PRs to a Slack channel. Your team starts every morning knowing what shipped yesterday — without anyone writing a summary.

Export & GitHub Releases

One-click export to Markdown or clipboard. You can also draft a GitHub Release directly from the dashboard — it creates the release with the correct tag, title, and body.

Lessons Learned

1. Free tier needs guardrails from day one.
We cap free at 1 repo, 3 changelogs/month, 1/day. Without caps, 10K free users could cost ~$6K/mo in AI calls. With caps, it's ~$1.8K/mo — sustainable as a loss leader.

2. Structured output > raw text.
Using Zod schemas with Claude's structured output means we never have to parse freeform text. The response is always typed and predictable.

3. Multi-installation support matters early.
Users often belong to multiple GitHub orgs. Supporting multiple GitHub App installations per user from the start saved us a painful migration later.

4. Prompt caching is essential for cost control.
System prompts are large and repeated. Caching them cut per-request costs by ~60%.

Try It

ShipLogs is live at shiplogs.xyz.

  • Free: 1 repo, 3 changelogs/month — no credit card
  • Pro ($39/mo): 5 repos, all audience modes, GitHub Releases
  • Team ($69/mo): 10 repos, daily summaries, Slack, custom templates

The free tier is enough to try it on a real project. Install the GitHub App, merge a few PRs, and generate your first multi-audience changelog.

I'd love to hear how your team handles changelogs today. Does the multi-audience approach resonate, or is single-format enough? Let me know in the comments.

Top comments (0)