# Turn passing Buildkite deploys into customer-ready release notes

> When a production deploy passes, an agent writes plain-English release notes, adds them to your Notion changelog, and posts a summary to Slack.

- Workflow type: agent
- Services: Buildkite, GitHub, Notion, Slack Bot
- Categories: Product, Engineering
- Published: 2026-08-14

## What it does

- Watches your production deploy pipeline and runs only when a build actually finishes successfully, ignoring failed and canceled runs
- Works out everything that shipped since the last successful deploy by collecting the pull requests merged into your main branch in that window
- Sorts the changes into New, Improved and Fixed, and rewrites each one in language a customer can understand instead of an engineering shorthand title
- Leaves out internal-only work like dependency updates, build configuration changes and behind-the-scenes refactors
- Adds a dated entry to your Notion changelog page and posts a short summary with a link into Slack, so support and customer success hear it first
- Skips the run completely when a release contains nothing customer facing, so you never publish an empty changelog entry

## What you'll need

- A Buildkite account with the production deploy pipeline you want to announce
- A GitHub account and access to the repository the deploys are built from
- A Notion workspace with a changelog page, shared with your Notion connection so it can be edited
- A Slack workspace and a channel where your support and customer success team should be notified

## Prompt

Poll Buildkite for finished builds, and whenever a build finishes on my production deploy pipeline, turn that release into customer readable release notes. Only continue when the build's state is passed and the build belongs to my production deploy pipeline. Ignore failed and canceled builds, and ignore builds on every other pipeline.

Start by using Buildkite's Get a Build operation to pull the full record for the build that just finished, so you know exactly what shipped: the commit SHA, the branch, the pipeline, and the time the build finished. Buildkite addresses builds by their per pipeline sequential number, not by the UUID id, and most Buildkite paths are scoped by organization slug, so look up the organization slug first if you need it.

Next, establish the start of the release window. Use Buildkite's List Builds for a Pipeline operation against the same production deploy pipeline, filtered to passed builds, to find the previous successful deploy before this one. Take the time that build finished as the lower bound of the range. If there is no previous successful deploy, fall back to the last 7 days so the first run still produces something sensible.

Now gather what actually shipped. Use GitHub's List Pull Requests operation on the repository, filtered to closed pull requests with the main branch as the base and sorted by most recently updated. Keep only pull requests that were genuinely merged, and only those merged between the previous successful deploy and this build. Do not attempt a commit range comparison, since a compare commits operation is not available here. The merged pull request list bounded by those two deploy timestamps is the definition of this release.

Then do the editorial work. Group the changes into three sections: New, Improved and Fixed. Rewrite every item in plain language aimed at a non engineering reader, describing the benefit or the behavior change rather than the implementation. Turn a title like refactor session token refresh path into something a customer would understand, such as fixed an issue where you could be signed out unexpectedly. Drop internal only work entirely, including dependency bumps, CI and build configuration changes, test only changes, and pure refactors with no user visible effect. Where a pull request title is too cryptic to interpret confidently, use its description for context, and leave it out rather than guessing.

If every merged pull request in the range turns out to be internal only, skip the run entirely. Do not append anything to Notion and do not post to Slack, so we never publish an empty release note.

When there is at least one customer facing change, append the finished notes to our Notion changelog page using the Append Block Children operation. Add it as a new dated entry on the existing page rather than creating a new page: a heading with the release date, then only the sections that have content, each with its items as bullets. Keep the existing entries untouched so the page reads as a running changelog with the newest release at the end.

Finally, post a short summary into Slack using the Slack Bot Send a Message operation, so support and customer success know what changed before customers start asking. Keep it to a few lines: the release date, a one sentence sense of the headline changes, the counts per section, and a link to the Notion changelog page for the full detail. Do not paste the entire release notes into the channel.

## How to customize

- Point it at a different pipeline or a different branch if you release from something other than main
- Change the Slack channel, or send to several channels if support, customer success and leadership each want their own copy
- Adjust what counts as internal only, for example keeping performance improvements visible while still hiding dependency updates
- Reword the three groupings if your changelog uses different headings, such as Added, Changed and Fixed

## FAQ

### Will this post something every single time a build runs?

No. It only runs when a build finishes successfully on the production deploy pipeline you choose, so failed and canceled builds are ignored. On top of that, if everything in the release is internal work with nothing worth telling customers about, the run stops without posting anything.

### How does it know what shipped in this release?

It looks at when your previous successful production deploy happened, then gathers every pull request merged into your main branch between then and now. That range becomes the contents of the release.

### Will customers see raw engineering titles?

No. Rewriting technical pull request titles into plain language is the main job here. An entry like a fix for a session token edge case becomes something a non-technical reader can actually follow.

### What if we deploy several times a day?

That works fine. Each successful deploy only covers the work merged since the last one, so busy days produce several small entries rather than one big one. Many teams point it at a release pipeline instead of every deploy if they would rather batch the announcements.

### Can it write to a page we already use as our changelog?

Yes. It adds each release as a new dated entry on the existing page rather than creating a new page every time, so your changelog stays in one place. You just need to share that page with your Notion connection first.

Use this prompt in General Input: https://www.generalinput.com/prompts/turn-passing-buildkite-deploys-into-customer-ready-release-notes