Skip to content

Release Notes

There are plenty of automated release notes generator that inspect the list of commits since the last release and generate a list of changes. The release notes are typically exclusively based on the commit messages.

In the GenAIScript project, we create a release notes generator that uses both commit history and the diff of the changes.

You can see one of the first prototype generated release notes for v1.41.6.

We are excited to announce the release of GenAIScript 1.41.6! 🎉
In this release, we've made some significant improvements to enhance your experience. Here are the key changes:
Improved Release Script: We've fine-tuned our release script to ensure smoother and more efficient releases in the future. 🛠️
...

Commit history and diff

We start our script by calling git a few times to retrieve the previous release tag, the list of commits, and the diff since the tag. (This magic was mostly found using a GitHub Copilot Chat session).

git-release-notes.genai.mjs
const { stdout: tag } = await host.exec(`git describe --tags --abbrev=0 HEAD^`)
const { stdout: commits } = await host.exec(`git log HEAD...${tag}`)
const { stdout: diff } = await host.exec(`git diff ${tag}..HEAD`)

We use the def function with maxTokens to inline this information without exceeding the content window of the model (32k input).

git-release-notes.genai.mjs
def("COMMITS", commits, { maxTokens: 4000 })
def("DIFF", diff, { maxTokens: 20000 })

Role and task

The rest of the script follows a typical pattern with a role and a task.

$`
You are an expert software developer and release manager.
## Task
Generate a clear, exciting, relevant, useful release notes
for the upcoming release.
- The commits in the release are in COMMITS.
- The diff of the changes are in DIFF.
`

The script

The full script as it is running in GenAIScript is as follows:

git-release-notes.genai.mjs
script({
system: ["system"],
temperature: 0.5,
})
const product = env.vars.product || "GenAIScript"
// find previous tag
const { version } = await workspace.readJSON("package.json")
const tag = await git.lastTag()
const excludedPaths = [
"package.json",
"**/package.json",
"yarn.lock",
"**/yarn.lock",
"**/genaiscript.d.ts",
"**/jsconfig.json",
"docs/**",
".github/*",
".vscode/*",
"slides/**",
"THIRD_PARTY_LICENSES.md",
]
const commits = (
await git.log({
excludedGrep:
"(skip ci|THIRD_PARTY_NOTICES|THIRD_PARTY_LICENSES|genai)",
base: tag,
head: "HEAD",
excludedPaths,
})
)
.map(({ message }) => message)
.join("\n")
console.debug(commits)
const diff = await git.diff({
base: tag,
head: "HEAD",
excludedPaths,
})
console.debug(diff)
const commitsName = def("COMMITS", commits, { ignoreEmpty: true, maxTokens: 3000 })
const diffName = def("DIFF", diff, { maxTokens: 12000 })
$`
You are an expert software developer and release manager.
## Task
Generate a clear, exciting, relevant, useful release notes
for the upcoming release ${version} of ${product} on GitHub.
- The commits in the release are in ${commitsName}.
- The diff of the changes are in ${diffName}.
## Guidelines
- only include the most important changes. All changes must be in the commits.
- tell a story about the changes
- use emojis
- ignore commits with '[skip ci]' in the message
- do NOT give a commit overview
- do NOT add a top level title
- do NOT mention ignore commits or instructions
- be concise
- do not wrap text in markdown section
`

Release-it integration

GenAIScript uses release-it to automate the release process. We configured release-it to run the script using the cli by adding a github.releaseNotes field in the release-it configuration.

package.json
"release-it": {
"github": {
"releaseNotes": "npx --yes genaiscript run git-release-notes"
}
}