A CLI tool that generates structured, executive-ready Markdown release notes from a GitHub repository for a specified date range. It can also be used as a GitHub Action to generate release notes and post them to Notion, Slack, and Discord.
- Extracts merged Pull Requests within a date range via the GitHub REST API
- Generates a structured Markdown release report with:
- Executive Summary — PR count, contributors, code delta, focus areas
- Changes by Category — Features, Bug Fixes, Security, Refactoring, Other
- Contributors — Sorted leaderboard by PR count
- Automatic PR categorisation via labels with title-keyword fallback
- Handles pagination for large repositories (5,000+ PRs)
- Structured logging via pino
- Runs locally as a CLI and as a scheduled GitHub Action (every Thursday)
- Multi-channel Publishing: Automatically publish release notes to:
- Notion (as a new database page)
- Slack (as a formatted message)
- Discord (as a formatted message, handles splitting for length)
- Node.js 20+
- A GitHub personal access token (classic or fine-grained) with
reporead access - (Optional) Notion Integration Token and Database ID
- (Optional) Slack Webhook URL
- (Optional) Discord Webhook URL
npm install
npm run buildnode dist/cli.js \
--owner <repo-owner> \
--repo <repo-name> \
--from 2026-01-01 \
--to 2026-01-31 \
--github-token <token> \
--output release-notes/release-notes.md \
--publish-slack \
--publish-discord \
--publish-notionGenerate release notes for YOUR_ORG/stellar-dashboard over February 2026 and publish to all channels:
# Using the compiled CLI
node dist/cli.js \
--owner YOUR_ORG \
--repo stellar-dashboard \
--from 2026-02-01 \
--to 2026-02-17 \
--github-token $GH_TOKEN \
--output release-notes/stellar-dashboard-release-notes.md \
--publish-slack \
--publish-discordOr during development (no build step required):
npm run dev -- \
--owner YOUR_ORG \
--repo stellar-dashboard \
--from 2026-02-01 \
--to 2026-02-17 \
--publish-slack| Flag | Required | Description |
|---|---|---|
--owner |
Yes | GitHub repository owner |
--repo |
Yes | GitHub repository name |
--from |
Yes | Start date (YYYY-MM-DD) |
--to |
Yes | End date (YYYY-MM-DD) |
--output |
No | Output file path (default: release-notes/repo_from_to.md) |
--github-token |
No | GitHub token (fallback: GH_TOKEN env var) |
--include-labels |
No | Comma-separated labels to include |
--exclude-labels |
No | Comma-separated labels to exclude |
--publish-slack |
No | Publish generated notes to Slack |
--publish-discord |
No | Publish generated notes to Discord |
--publish-notion |
No | Publish generated notes to Notion |
Create a .env file based on .env.example to store these secrets.
| Variable | Description |
|---|---|
GH_TOKEN |
Fallback GitHub authentication |
LOG_LEVEL |
Pino log level (default: info) |
NOTION_API_KEY |
Notion Integration Token (starts with secret_) |
NOTION_DATABASE_ID |
Notion Database ID |
SLACK_WEBHOOK_URL |
Slack Incoming Webhook URL |
DISCORD_WEBHOOK_URL |
Discord Incoming Webhook URL |
# Run without building (via tsx)
npm run dev -- --owner octokit --repo rest.js --from 2026-01-01 --to 2026-01-31
# Run tests
npm test
# Type-check only
npm run lint- Go to Slack API: Incoming Webhooks.
- Create a new App or select an existing one.
- Enable Incoming Webhooks and click "Add New Webhook to Workspace".
- Select the channel to post to.
- Copy the Webhook URL and add it to your
.envfile asSLACK_WEBHOOK_URL.
- Open your Discord server settings > Integrations > Webhooks.
- Click "New Webhook".
- Copy the Webhook URL and add it to your
.envfile asDISCORD_WEBHOOK_URL.
- Go to Notion Integrations and create a new integration.
- Share your target database with this integration connection.
- Get the Database ID from the URL.
- Add
NOTION_API_KEYandNOTION_DATABASE_IDto your.envfile. - Ensure your database has the following properties:
Name(Title)Date Range(Text)Week(Number)Status(Select, with a "Published" option)
The repository includes workflows for scheduling these tasks. You can now use the main CLI within your actions to publish to multiple destinations by setting the appropriate environment secrets in your repository settings.
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Validation error |
| 2 | GitHub API error |
| 3 | Unexpected error |
MIT
