This script automatically generates release notes by extracting Linear task IDs from Git commit messages and fetching their details from the Linear API.
- 📝 Extracts Linear task IDs (e.g.,
JS-1234) from commit messages - 🔗 Fetches task titles, descriptions, and metadata from Linear API
- 📊 Groups tasks by priority (Urgent, High, Medium, Low)
- 📋 Includes commits without Linear task IDs
- 📄 Supports both Markdown and JSON output formats
- 🏷️ Works with tags or commit ranges
- Linear API Key: Get your API key from Linear Settings
- Node.js: The script uses Node.js built-in modules (no additional dependencies required)
You can set the API key in multiple ways:
Option A: Environment variable (temporary)
export LINEAR_API_KEY="lin_api_xxxxxxxxxxxxx"Option B: .env file (recommended for development)
echo "LINEAR_API_KEY=lin_api_xxxxxxxxxxxxx" >> .env
# Then source it before running the script
source .envOption C: In your shell profile (permanent)
Add to ~/.bashrc, ~/.zshrc, or equivalent:
export LINEAR_API_KEY="lin_api_xxxxxxxxxxxxx"Test that everything works:
LINEAR_API_KEY=your_key npm run release:notes -- --helpGenerate release notes from the last tag to HEAD:
LINEAR_API_KEY=your_key npm run release:notesOr if you've set the environment variable:
npm run release:notesGenerate notes between two specific tags:
npm run release:notes -- --from v0.51.17-alpha --to v0.51.18-alphaSave to a file:
npm run release:notes -- --output RELEASE_NOTES.mdGenerate JSON output:
npm run release:notes -- --format json --output release-notes.jsonUse with specific commit range:
npm run release:notes -- --from abc123 --to def456| Option | Description | Default |
|---|---|---|
--from <tag> |
Start tag/commit | Latest tag |
--to <tag> |
End tag/commit | HEAD |
--output <file> |
Output file path | stdout |
--format <type> |
Output format (markdown or json) |
markdown |
--help |
Show help message | - |
The script generates release notes with the following structure:
# Release Notes: v0.51.18-alpha
Changes from v0.51.17-alpha to v0.51.18-alpha
Generated: 2025-12-02T10:00:00.000Z
## 🔴 Urgent
### JS-8441: Fix critical authentication bug
Brief description of the task from Linear...
**Details:** Status: Done | Assignee: John Doe | Labels: bug, security
**Commits:**
- `de7281a` JS-8441: fix
## 🟠 High Priority
### JS-7802: Improve performance
...
## 📝 Other Commits
- `153c1a9` fix crash
- `7956004` add analyticsSpaceId{
"version": "v0.51.18-alpha",
"from": "v0.51.17-alpha",
"generatedAt": "2025-12-02T10:00:00.000Z",
"tasks": [
{
"id": "JS-8441",
"title": "Fix critical authentication bug",
"description": "Full description...",
"state": "Done",
"priority": 1,
"team": "JavaScript",
"assignee": "John Doe",
"labels": ["bug", "security"],
"commits": [
{
"hash": "de7281ad42...",
"subject": "JS-8441: fix",
"author": "Developer Name",
"date": "2025-12-02 10:00:00 +0000"
}
]
}
],
"otherCommits": [...]
}Add to your .github/workflows/release.yml:
name: Create Release
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Fetch all history for tags
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Generate Release Notes
env:
LINEAR_API_KEY: ${{ secrets.LINEAR_API_KEY }}
run: |
npm run release:notes -- --output RELEASE_NOTES.md
- name: Create Release
uses: softprops/action-gh-release@v1
with:
body_path: RELEASE_NOTES.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}You can integrate this with electron-builder's release process. Add to your build hooks:
electron/hook/afterpack.js (or create a new hook):
const { execSync } = require('child_process');
const fs = require('fs');
exports.default = async function(context) {
// Generate release notes after packaging
try {
console.log('Generating release notes...');
execSync('npm run release:notes -- --output dist/RELEASE_NOTES.md', {
stdio: 'inherit'
});
} catch (error) {
console.warn('Failed to generate release notes:', error.message);
}
};For the script to work effectively, use this commit message format:
JS-1234: Add new feature
JS-5678: Fix bug in editor
JS-9012: Update dependencies (JS-9013)
fix bug # No Linear ID
WIP # No Linear ID
JS1234: fix # Missing hyphen
- Start with the Linear ID: Begin your commit message with the task ID
- Use descriptive messages: Even though the script fetches details from Linear, the commit message should be meaningful
- One task per commit: Keep commits focused on a single task when possible
- Multiple tasks: If a commit relates to multiple tasks, list them:
JS-1234: Main task (also relates to JS-5678)
Make sure you've set the LINEAR_API_KEY environment variable. Get your key from https://linear.app/settings/api
If you don't have any Git tags yet, the script will include all commits. Create a tag first:
git tag v0.1.0Your API key is invalid or expired. Generate a new one from Linear settings.
This means there are no commits between the specified range. Check your tag names:
git tag --list
git log --oneline v0.51.17-alpha..v0.51.18-alphaMake sure your commit messages follow the correct format: TEAM-NUMBER (e.g., JS-1234). The pattern is case-sensitive and requires a hyphen.
Test with a small commit range:
LINEAR_API_KEY=your_key node scripts/generate-release-notes.js --from HEAD~5 --to HEADAdd debug output by uncommenting console.log statements in the script, or use:
node --inspect scripts/generate-release-notes.jsThis script is part of the Anytype project. See the main LICENSE.md for details.