---
title: Release notes automation
description: Skills, prompting strategies, and headless workflows to automate
  product release notes.
date: 2026-08-16
tags:
  - ai
  - documentation
---

Here are a few skills/prompts that I use to automate release note documentation and related processes. They can be used with a human-in-the-loop (HITL) or plugged into various headless workflows like `claude -p` and `copilot -p` running in CI, for example.

A necessary prerequisite is work over a versioned software repository (git, subversion, or anything else that exposes incremental diffs) or, outside software, anything else that works similarly. Limited experience there, sorry.

The main idea is to capture each change, feed its context and all other available surrounding information to an agent, and have it, following a generic template, fill out an accurate description.

A general flow can look like this:

1. A JIRA ticket with the issue description exists, is tagged for the upcoming release, and, optionally, links to a pull request.
2. An agent gets fed all this information, and provided with tools to access the relevant information: JIRA issue body and comments, pull request changeset, desired output template. This happens via an external trigger such as a webhook, manually starting a pipeline/git workflow, locally from a CLI, and so on.
3. The agent processes the task and outputs the data according to your requirements: locally, as a new pull request to the docs repo, a comment in the JIRA issue.

The specific application of course heavily depends on individual requirements, project structure, and other variables. In this post, let's take a look at two possible implementations: one human-driven and the other fully headless with a review step at the end.

## Human-driven execution (HITL)

With a human driving the flow, the process is simple - use existing terminal or GUI tools together with agent skills to point the agent at a changeset and all related details, and have it produce the release note.

When setting up, I use the `tech-writing` plugin from my [giga-skills](https://github.com/skurekjakub/giga-skills) marketplace. The plugin installs the `install-tech-writing-skills` that asks for details about the target environment and writes targeted skills for it.

To set up the plugin in Claude Code:

1. Add the marketplace.

```bash
/plugin marketplace add skurekjakub/giga-skills
```

2. Install the plugin.

```bash
/plugin install tech-writing@skurekjakub/giga-skills
```

3. Tell the agent to load and follow `install-tech-writing-skills`, then have it guide you through the setup process.

The setup adds three skills:

**docs-write-release-notes**
Writes user-facing release note entries. It asks for a branch, commit, or PR before it writes anything. It confirms what it understood about the change with you before it drafts the note.

**docs-write-hotfix-notes**
Writes "Fixed issues" entries from a pasted ticket, bug report, or diff. It refuses to guess. If the input is thin, it asks a question instead of guessing.

**docs-source-validation**
Checks a documentation claim against the real source code. It reports each claim as verified, incorrect, partially correct, or outdated, with the file and line that prove it.

When you give `docs-write-release-notes` a source path, it also uses `docs-source-validation` to check the code before it drafts anything.

A single session looks like this:

1. Open the repository with the release changes.
2. Start `docs-write-release-notes`. Give it the ticket ID or the PR number. Answer follow-up questions from the agent.
3. The agent writes the release notes and hands the control back to you.

That last step deliberately leaves the output in your hands. You can follow up by having the agent create a pull request or take over and finish the workflow yourself.

## Headless execution

We can use the same general approach when generating release notes headlessly. Instead of having humans steer the agent mid-session, the entire process runs autonomously and produces output for human review.

![An overview of the headless pipeline](https://skurekjakub.dev/blog/changelog-automation/headless-pipeline.drawio.svg)

The initial trigger can be anything:

- a CI pipeline that runs on a release tag
- a JIRA webhook triggered by state transition/release label
- a scheduled task

Before the run, decide how you approach environment setup.

### MCP-driven

Connect the agent to MCP servers for the repository host (GitHub, Azure DevOps, etc.) and for your ticketing system. Then let the agent collect the context - the issue and the pull request details - for itself:

```bash
claude -p "Use docs-write-release-notes. Write the release note for PR #${PR_NUMBER}. \
Fetch the ticket and the changeset yourself. Post the note as a comment on ${TICKET_ID}. \
Use the MCP tools available to you to gather the required context"
  --mcp-config .mcp.json \
  --output-format json > note.json
```

This setup requires little custom code to get up and running, but you are trusting the agent with credentials to multiple external systems, so limiting its options via a tool allowlist is preferred. It also requires more planning, which is something that weaker and cheaper models may struggle with.

### Script-driven

For environments with more sandboxing requirements, the pipeline can prepare the environment via scripting:

```bash
# Clones the source code repository
git clone --depth 1 --branch "${RELEASE_TAG}" "${REPO_URL}" .
# Gets the pull request details
gh pr diff "${PR_NUMBER}" > changes.diff
# Gets issue details (using the JIRA REST API)
curl -s -u "${JIRA_EMAIL}:${JIRA_API_TOKEN}" \
  "https://${JIRA_SITE}/rest/api/3/issue/${TICKET_ID}?fields=summary,description,comment" \
  > ticket.json
```

The agent gets only the local Read and Grep tools, plus one MCP server, allowlisted to a single `post-comment` tool. Since it starts with a complete and fixed context, it limits the surface where it can make mistakes to just the immediate environment and the written comment or generated PR. This option is safer for headless mode and for weak models.

The generative step is a simple script that invokes the LLM via your preferred harness.

```bash
claude -p "Use docs-write-release-notes. Write the release note for PR #${PR_NUMBER}. \
Read ticket.json for context and changes.diff for the changeset. \
Post the note as a comment on ${TICKET_ID}." \
  --mcp-config mcp.json \
  --allowed-tools "Read,Grep,mcp__jira" \
  --output-format json > note.json
```

For Copilot, swap to `copilot -p`, everything else stays the same.

Finally, route the agent output somewhere suitable for human review: a new pull request in the docs repo, or a comment on the JIRA ticket. From there, another round of automation can take it to your docs application.

## Conclusion

With the latest updates to even historically weaker models such as Sonnet, the likelihood of the agent going "rogue" is - given a properly set up environment and clear instructions - largely nonexistent.

Both headless and HITL methods are a valid approach and depend largely on your preferences and possible limitations of your environment.

---

Sources:

- Copilot CLI args - <https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-command-reference>
- Claude Code CLI args - <https://code.claude.com/docs/en/cli-reference>
- JIRA REST API issues - <https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issues/>
