# Release Notes

> Generate comprehensive release notes combining commit history and code diffs

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](https://github.com/microsoft/genaiscript/releases/tag/1.41.6).

```markdown
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

[Section titled “Commit history and diff”](#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

```js
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

```js
def("COMMITS", commits, { maxTokens: 4000 });
def("DIFF", diff, { maxTokens: 20000 });
```

## Role and task

[Section titled “Role and task”](#role-and-task)

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

```js
$`
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

[Section titled “The script”](#the-script)

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

git-release-notes.genai.mjs

```js
script({
  system: ["system"],
  temperature: 0.5,
  model: "github:openai/gpt-4o",
});


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.slice(0, 50) + "...");
const diff = await git.diff({
  base: tag,
  head: "HEAD",
  excludedPaths,
});
console.debug(diff.slice(0, 1000) + "...");


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

[Section titled “Release-it integration”](#release-it-integration)

GenAIScript uses [release-it](https://github.com/release-it/release-it) to automate the release process. We configured release-it to run the script using the [cli](/genaiscript/reference/cli) by adding a `github.releaseNotes` field in the `release-it` configuration.

package.json

```json
 "release-it": {
     "github": {
        "releaseNotes": "node packages/cli/dist/src/index.js run git-release-notes --cache --cache-name releases --no-run-trace --no-output-trace"
     }
 }
```