I shipped 47 app updates last year. I wrote the release notes for maybe seven of them. The rest? “Bug fixes and performance improvements.” You know the ones. Every developer writes them. Every user ignores them. I get why we do it — writing release notes is tedious. Nobody went into software development because they love summarizing merge commits.
But those release notes matter. A 2024 SplitMetrics study found apps with detailed update descriptions saw an 11% higher conversion rate from the update screen. Users read them. The App Store’s algorithm also notices engagement signals tied to update quality.
So we’re stuck in a developer paradox: the task is boring but important. Exactly the kind of problem automation solves. And with AI, we can automate it well — not just fill in a template, but generate notes that sound like a rushed, deadline-crushed human wrote them.
Why You Shouldn’t Write Another Release Note By Hand
Before we get into the how, let’s talk about the why. Because I’ve heard the objection before: “it only takes ten minutes.”
If you’re shipping bi-weekly, that’s 26 releases a year. Scale to a team of eight shipping weekly, and you’re looking at roughly 70 person-hours per year describing what you already built. That’s nearly two full work weeks. And consistency? Week one: a beautifully crafted changelog with emoji and a joke. Week twelve, after a brutal sprint: “v2.4.1 — fixes.” The quality delta is enormous. AI doesn’t cut corners at 11 PM on a Friday.
Step 1: Turn Your Git History Into A Raw Changelog
Every automated release notes pipeline starts in the same place: your commit history. But not just any commit history. You need conventional commits — the spec that prefixes every commit with a type like feat:, fix:, or chore:. It was designed by the Angular team and it’s become the de facto standard for automation-friendly repositories.
The spec is straightforward: type(scope): message. So feat(checkout): add Apple Pay support or fix(auth): resolve token refresh race condition. That structure makes commits machine-readable — a script knows immediately if something is a feature, a fix, or a breaking change. If you’re not using this yet, it takes about one sprint to adjust. Tools like commitlint enforce the format in CI. The payoff: your commits become structured data instead of a stream-of-consciousness diary.
Once your commits are conventional, you can generate a raw changelog with a single command. git log v2.4.0..HEAD --oneline --no-merges gives you the commit list. Or you can use dedicated tools that handle grouping, sorting, and formatting. The point is: you now have structured input that a machine can reason about.
Step 2: Feed The Raw Changelog To An AI Model
This is where the magic happens — and where most implementations get it wrong.
You don’t hand the AI your commits and say “make this sound good.” You need a prompt with structure, tone guidelines, and explicit formatting rules. Include: the raw changelog, the target platform (iOS App Store and Google Play have different limits), the desired tone, a ban on marketing-speak (no “revolutionary”), and a request to group changes thematically. Ask the model to flag breaking changes and deprecations — those go at the top.
On the App Store, you’re working with a 4,000 character limit. Google Play gives you 500 characters for “What’s New” — considerably tighter. The AI needs these constraints upfront, otherwise you’ll be hacking apart its output afterwards. One detail most tutorials skip: tell the AI what not to include. Internal refactors, test-only changes, dependency bumps. Your raw log might contain dozens of chore entries meaningless to users. Filter those at the prompt level.
Step 3: Polish The AI Output Into App Store Copy
Let’s be real about this step. The AI will get you 85% of the way there. That last 15% is what separates “obviously AI-generated” from “written by a developer who cares.”
Apple’s App Store Review Guidelines don’t explicitly regulate release note style, but the review team notices patterns. Generic or misleading notes can flag your update for closer scrutiny. The key is to make them specific and honest. If you fixed a crash, say which screen it was on. If you added a feature, mention one detail that shows you thought about it — not just that it exists.
Here’s what the AI-to-human polish step looks like in practice:
- Add one sentence of personality. A joke. An acknowledgment of a long-standing bug. Something that reads like a human typed it.
- Double-check that every listed change actually shipped. AI models sometimes hallucinate features from commit messages that were reverted later.
- Verify platform-specific formatting. iOS supports basic Unicode (emojis work). Google Play strips some characters. Test on-device before shipping.
- Remove the AI’s tendency to use certain phrases. “Seamless experience” is a dead giveaway. “Streamlined workflow” is another.
The polish step takes about three minutes per release. Compare that to twenty minutes writing from scratch. The math works.
Wiring It Into CI/CD
The whole point of this pipeline is that it runs without you. Here’s how to stitch it together:
GitHub Actions is the most common choice. On every push to your release branch or when you create a release tag, a workflow triggers. It parses conventional commits, feeds the output to an AI API — GPT-4o, Claude, whatever you use — and stores the generated notes as an artifact or pushes them to your release draft.
For iOS apps specifically, you can integrate this with Fastlane. The upload_to_app_store action accepts a release_notes parameter. Populate it with the AI-generated text, and your CI pipeline goes from “build and submit” to “build, generate notes, and submit with actual content.”
Always keep a manual override. Add a RELEASE_NOTES_OVERRIDE environment variable or a text file in your repo. If it exists, skip the AI step. Some releases need human judgment — a nuanced security fix, or copy the marketing team already wrote. Don’t paint yourself into an automation corner.
Tools Worth Your Time
Several open-source projects already solve large chunks of this pipeline:
release-please (Google) — Automates CHANGELOG generation and version bumps by parsing conventional commits. It creates release PRs that stay updated as work gets merged. Merge the PR and it handles the tag, changelog, and GitHub release in one go.
semantic-release — A plugin-based version of the same concept. Supports any language. The plugin architecture means you can add an LLM step that takes the auto-generated changelog and outputs polished notes. Community plugins exist for ChatGPT integration already.
git-cliff — Rust-based changelog generator with Tera templating. Output in any format: Markdown for GitHub, HTML for a changelog page, or plain text for app stores. You can embed the generated notes into an AI prompt directly in your CI config.
For the AI step, most teams use OpenAI’s API or Anthropic’s Claude API. The entire integration — parsing, generation, submission — fits in under 50 lines of shell or a single GitHub Actions workflow file.
QA Checklist Before You Ship
Automation doesn’t mean abdication. Run through this list before trusting the pipeline with a live release:
- Character limits respected. iOS App Store: 4,000 characters. Google Play “What’s New”: 500 characters. Truncate, don’t let the store truncate for you.
- No internal jargon. “Refactored the DI container” means nothing to users. “Improved app startup speed” does.
- Breaking changes called out. If you deprecated an API or removed a feature, it goes at the top. Bold it.
- No placeholder text. The AI occasionally outputs “describe the fix here” or “[feature description].” Add a grep check for bracket patterns.
- Tone matches your brand. A banking app and a gaming app should not sound the same. Review one release note from each against your style guide.
- Links are tested. If you’re linking to a changelog page or blog post, the URL needs to work on launch day — not just in staging.
Getting Started Tomorrow
You don’t need a weekend project. You need one hour. Here’s the minimal viable pipeline:
- Adopt conventional commits in your next sprint. Install commitlint in CI to enforce it. This is the foundation and it costs you nothing except a slight adjustment to how you type commit messages.
- Write a 20-line shell script that runs
git logbetween the last two tags, pipes the output to your AI API of choice with a well-structured prompt, and saves the result to a file. Test it on your last three releases to calibrate the prompt. - Wire it into your CI as an optional step — not a blocker. Let it run alongside your build for a sprint or two while you build confidence in the output.
After three or four releases, you’ll wonder why you ever wrote these things by hand. The AI won’t write literary masterpieces. It won’t capture the inside joke your team shares about the checkout screen. But it’ll produce release notes that are accurate, readable, and — crucially — done. And done beats perfect every single time.