Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add script for generating an initial draft of release notes #162

Merged
merged 3 commits into from
Aug 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions scripts/release-notes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash

if [ ! -d "scripts/release-notes/node_modules" ]; then
echo "Node modules not found. Installing dependencies..."
pnpm install -C scripts/release-notes
fi

pnpm -s tsx scripts/release-notes/release-notes.ts "$@"
5 changes: 5 additions & 0 deletions scripts/release-notes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This script collects all "fix" and "feat" commits since the last stable version. Then it concatenates their `git log -p` outputs into a single file, which can be fed into an LLM for high-quality release notes.

```
tsx scripts/release-notes/release-notes.ts > release-notes.diff
```
86 changes: 86 additions & 0 deletions scripts/release-notes/dedent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { isArray } from 'radashi'

/**
* Remove indentation from a string. The given string is expected to
* be consistently indented (i.e. the leading whitespace of the first
* non-empty line is the minimum required for all non-empty lines).
*
* If the `indent` argument is nullish, the indentation is detected
* from the first non-empty line. Detection is cheap and robust for
* most use cases, so you should only set an explicit `indent` if
* necessary.
*
* @see https://radashi-org.github.io/reference/string/dedent
* @example
* ```ts
* // This is indented with 4 spaces.
* const input = `
* Hello
* World
* `
*
* // Explicit indentation
* dedent(input, ' ')
* // => ' Hello\n World\n'
*
* // Detected indentation
* dedent(input)
* // => 'Hello\nWorld\n'
*
* // Tagged template strings
* const str = dedent`
* Foo ${1 + 1}
* Bar ${2 * 2}
* `
* // => 'Foo 2\nBar 4'
* ```
*/
export function dedent(
template: TemplateStringsArray,
...values: unknown[]
): string

export function dedent(text: string, indent?: string | null): string

export function dedent(
text: string | TemplateStringsArray,
...values: unknown[]
): string {
// Support tagged template strings
if (isArray(text)) {
if (values.length > 0) {
return dedent(
text.reduce((acc, input, i) => {
let value = String(values[i] ?? '')

// Detect the indentation before this embedded string.
const indent =
value.includes('\n') && input.match(/[ \t]*(?=[^\n]*$)/)?.[0]

// Ensure the multi-line, embedded string can be correctly
// dedented.
if (indent) {
value = value.replace(/\n(?=[^\n]*?\S)/g, '\n' + indent)
}

return acc + input + value
}, ''),
)
}

text = text[0]
}

const indent = values[0] ?? detectIndent(text)
const output = indent
? text.replace(new RegExp(`^${indent}`, 'gm'), '')
: text

// Remove the first and last lines (if empty).
return output.replace(/^[ \t]*\n|\n[ \t]*$/g, '')
}

// Find the indentation of the first non-empty line.
function detectIndent(text: string) {
return text.match(/^[ \t]*(?=\S)/m)?.[0]
}
12 changes: 12 additions & 0 deletions scripts/release-notes/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"private": true,
"dependencies": {
"@anthropic-ai/sdk": "^0.25.0",
"@types/node": "^22.1.0",
"execa": "^9.3.0",
"mri": "^1.2.0",
"octokit": "^4.0.2",
"radashi": "12.2.0-beta.7fb6e89",
"tsx": "^4.17.0"
}
}
Loading
Loading