DEV Community

Changenotes
Changenotes

Posted on

Stop Writing Changelogs by Hand: Automate Them with AI and GitHub Releases

Every dev team knows the feeling. You ship a release. Your PM asks "can you update the changelog?" You open CHANGELOG.md, stare at it for ten minutes, write something vague like "bug fixes and improvements," and close it. Then nobody reads it anyway.

But changelogs actually matter. Your users, your team, your future self — they all benefit from knowing what changed and why. The problem isn't motivation. It's friction.

In this post I'll show you how to completely automate changelog generation using GitHub releases and AI — so changelogs happen automatically every time you push a release, with zero extra work.

Why changelogs fail in practice

Most projects either skip changelogs entirely or maintain them inconsistently. The root cause is always the same: writing a good changelog is a separate task that happens after shipping, when you're already mentally done with the work.

The information already exists in your commits and PRs. You shouldn't have to write it a second time.

The anatomy of a good changelog

A good changelog entry looks like this:

## v2.4.0 — March 5, 2026

### Features
- **Dark mode**: The app now supports system dark mode preference.

### Bug Fixes
- Fixed an issue where users would be logged out unexpectedly after 30 minutes.

### Improvements
- Reduced initial page load time by 40% through code splitting.
Enter fullscreen mode Exit fullscreen mode

Notice what changed:

  • Commits grouped by type (features, fixes, improvements)
  • Dependency bumps collapsed or omitted
  • User-facing language instead of developer-speak
  • Context about what the change means, not just that it happened

Writing this from scratch takes 20-30 minutes per release. Multiply by 2 releases a week and it's 2+ hours per month doing something a computer could do better.

How to automate it with GitHub webhooks

GitHub fires a release webhook event every time you publish a release. You can subscribe to this and trigger a pipeline that:

  1. Fetches the release's associated commits and merged PRs
  2. Categorizes them by type (feat/fix/chore in conventional commits, or by PR labels)
  3. Generates human-readable descriptions using an LLM
  4. Posts the result to your changelog

Here's a minimal Node.js webhook handler:

import Anthropic from "@anthropic-ai/sdk";

export async function handleGithubRelease(payload) {
  const { release, repository } = payload;
  const commits = await fetchCommitsSince(repository.full_name, release.tag_name);
  const categorized = categorizeCommits(commits);

  const client = new Anthropic();
  const response = await client.messages.create({
    model: "claude-opus-4-6",
    max_tokens: 1024,
    messages: [{
      role: "user",
      content: "Generate a user-facing changelog for version " + release.tag_name + " with these commits: " + JSON.stringify(categorized)
    }],
  });

  return response.content[0].text;
}
Enter fullscreen mode Exit fullscreen mode

This works, but there's a lot of boilerplate: webhook verification, GitHub API auth, pagination, edge cases (merge commits, bot commits), storage, hosting the changelog page, RSS feeds...

What we built: Changenotes

We were building this exact pipeline internally and decided to package it as a service: Changenotes.

The flow is:

  1. Connect your GitHub repo (OAuth, takes 10 seconds)
  2. Push a release as you normally would
  3. Changenotes generates a categorized, AI-written changelog entry automatically
  4. Review the draft, edit if needed, publish to your hosted changelog page

The generated output handles the hard parts automatically:

  • Dependency bumps are collapsed or omitted
  • Bot commits (Dependabot, Renovate) are filtered
  • Conventional commits are parsed, but non-conventional repos work too
  • Everything is editable before publishing

Each project gets a public changelog page at changenotes.app/your-org/your-repo with an RSS feed.

Conventional commits help a lot

If your team uses Conventional Commits, changelog generation becomes much more reliable:

feat(auth): add OAuth2 login with GitHub
fix(api): handle rate limit errors gracefully
chore(deps): update dependencies
Enter fullscreen mode Exit fullscreen mode

The type prefix gives the LLM strong signal for categorization. Even if you're not using conventional commits today, it's worth adopting incrementally.

The result

After setting this up, changelogs stop being a chore. Your users get clear, consistent release notes. Your team never has to argue about whether something is worth documenting.

If you found this useful, Changenotes is what we built to solve this. $29/mo per workspace, 14-day free trial, no credit card required. Happy to answer questions in the comments.

Top comments (0)