Release notes from a tag
Your CI posts the new tag to a webhook. Jimothy lists every commit since the previous tag, Claude groups them into features, fixes and breaking changes in language users understand (dropping refactors and CI noise), and once you approve, the notes are published to the GitHub release.
- Commits since last tag Shell
- Write release notes Claude API · Sonnet 5
- Approve notes You
- Publish to GitHub Shell
What each step does
Commits since last tag
ShellFetches tags and lists the commits between the previous tag and this one.
Write release notes
Claude API · Sonnet 5Groups the changes for users and leaves out internal work.
Approve notes
YouShows you the notes. Reject with a comment and they are rewritten.
Publish to GitHub
ShellUpdates the GitHub release for the tag, or creates it.
From copy to first run
- Copy the pipeline JSON with the button above.
- In Jimothy, open Pipelines → New pipeline, paste it under “Or import a pipeline JSON” and click Import.
- Under Workspace, choose your clone of the repository.
- Fill in the variables below under Pipeline settings → Variables.
- Triggers → Add trigger → Webhook. Add a CI step on tag push that posts {"title": "<tag>", "key": "<tag>"} to the URL.
What to fill in
The prompts and commands read these as {{vars.<name>}}. The examples are placeholders: replace them with your own.
| Variable | What to put in it | Example |
|---|---|---|
product | Your product and who reads its release notes. | Acme, a reporting tool for finance teams. Readers are admins at customer companies. |
Show the pipeline JSON
{
"jimothyPipeline": 1,
"name": "Release notes from a tag",
"description": "Writes release notes from the commits since the previous tag and publishes them to the GitHub release.",
"icon": "rocket",
"color": "#f97316",
"repo": {
"mode": "inplace",
"localPath": "",
"baseBranch": "main"
},
"concurrency": 1,
"variables": {
"product": "Acme, a reporting tool for finance teams. Readers are admins at customer companies."
},
"steps": [
{
"id": "log",
"name": "Commits since last tag",
"type": "shell",
"description": "Fetches tags and lists the commits between the previous tag and this one.",
"timeoutMinutes": 3,
"command": "git fetch -q --tags origin && tag={{issue.title}} && if prev=$(git describe --tags --abbrev=0 \"$tag^\" 2>/dev/null); then echo \"Changes from $prev to $tag\"; git log --no-merges --pretty='- %s (%h)' \"$prev..$tag\"; else echo \"First release: $tag\"; git log --no-merges --pretty='- %s (%h)' \"$tag\" | head -300; fi"
},
{
"id": "draft",
"name": "Write release notes",
"type": "agent",
"description": "Groups the changes for users and leaves out internal work.",
"harnessId": "anthropic-api",
"model": "claude-sonnet-5",
"dependsOn": [
"log"
],
"timeoutMinutes": 5,
"systemPrompt": "You write release notes for {{vars.product}} Plain, specific, no hype.",
"prompt": "{{steps.log.output | truncate:30000}}\n\nWrite the release notes for {{issue.title}} in Markdown with these sections, leaving out any that are empty: ## Breaking changes (with what to do), ## New, ## Improved, ## Fixed. Describe each change by what users can now do or what no longer goes wrong, with the commit hash in brackets. Leave out refactors, tests, CI, dependency bumps and internal tooling.{{#if steps.approve.output}}\n\nYour previous draft was rejected with this feedback. Rewrite it:\n{{steps.approve.output}}{{/if}}"
},
{
"id": "approve",
"name": "Approve notes",
"type": "approval",
"description": "Shows you the notes. Reject with a comment and they are rewritten.",
"dependsOn": [
"draft"
],
"loopBackTo": "draft",
"maxLoops": 3,
"approvalMessage": "Publish these notes to the {{issue.title}} release?\n\n---\n\n{{steps.draft.output}}"
},
{
"id": "publish",
"name": "Publish to GitHub",
"type": "shell",
"description": "Updates the GitHub release for the tag, or creates it.",
"dependsOn": [
"approve"
],
"timeoutMinutes": 3,
"command": "if gh release view {{issue.title}} >/dev/null 2>&1; then gh release edit {{issue.title}} --notes {{steps.draft.output}}; else gh release create {{issue.title}} --title {{issue.title}} --notes {{steps.draft.output}}; fi && gh release view {{issue.title}} --json url --jq .url"
}
]
}More for engineering, and beyond
Incident postmortem draft
Turns an incident timeline into a blameless postmortem, traced to the commits that caused it, and opens it as a pull request.
EngineeringFlaky test hunter
Runs your test suite several times overnight. If some runs fail and others pass, an agent finds the cause, fixes it properly and opens a PR.
EngineeringSecurity advisory triage
Runs your dependency audit weekly, works out which advisories actually affect your code, and opens a PR fixing the ones that do.