From zero to release notes in 10 minutes

A hands-on guide to installing Cullit, configuring it for your project, and generating your first set of production release notes.

10 min read
📋 7 steps
🔧 Beginner
In this tutorial
  1. Prerequisites & what you’ll build 1 min
  2. Install Cullit 1 min
  3. Initialize your config 2 min
  4. Generate your first release notes 1 min
  5. Add AI-powered generation 2 min
  6. Publish to Slack, Discord & GitHub 2 min
  7. Automate with GitHub Actions 2 min
💻 Collect Git / Jira / Linear
🔍 Enrich Ticket context
🧠 Generate AI or template
📤 Publish Slack / Discord / GH
1

Prerequisites & what you’ll build

By the end of this tutorial, you’ll have Cullit generating categorized release notes from your git history, with optional AI enhancement and automated publishing.

What you need

Requirement Details
Node.js v22 or later — node --version
Git repository Any repo with commits and at least one tag
AI API key (optional) Anthropic, OpenAI, or Gemini key for AI-powered notes
💡
No AI key? Cullit works without one! The free tier uses template-based generation — still categorized and structured, just without AI writing. You can add AI later.

Which provider should I use?

Pick your provider

I want the best quality notes with minimal setup anthropic
I already have an OpenAI key openai
I want free AI via Google gemini
I want to run everything locally, no cloud ollama
I don’t want AI at all — just structured templates none
2

Install Cullit

Install globally so you can run cullit from any repo.

terminal
$ npm install -g cullit

added 1 package in 2s

$ cullit --version
cullit v0.2.1

Or use it without installing via npx:

terminal
$ npx cullit generate --from v1.0.0
📦
Package managers: Also works with pnpm add -g cullit or yarn global add cullit
3

Initialize your config

Navigate to your project and run the interactive setup. Cullit will ask a few questions and create a .cullit.yml config file.

~/your-project
$ cd my-project
$ cullit init

Cullit — Project Setup

AI provider (anthropic/openai/gemini/ollama/openclaw/none) [anthropic]: none
Source type (local/jira/linear) [local]: local
Audience (developer/end-user/executive) [developer]: developer
Tone (professional/casual/terse) [professional]: professional
Enrich from (jira/linear/both/none) [none]: none

✓ Created .cullit.yml
Run "cullit generate --from <tag>" to generate release notes.

Here’s what .cullit.yml looks like:

.cullit.yml
# Cullit Configuration # https://cullit.io ai: provider: none # start free, upgrade anytime audience: developer tone: professional categories: [features, fixes, breaking, improvements, chores] source: type: local publish: - type: stdout
💡
Pro tip: You can skip cullit init entirely. Cullit uses sensible defaults if no config file exists.
4

Generate your first release notes

First, check what tags you have:

~/your-project
$ cullit tags
Recent tags:
→ v1.2.0
v1.1.0
v1.0.0

Now generate notes between two tags:

~/your-project
$ cullit generate --from v1.1.0 --to v1.2.0

» License: 🆓 Free
# Collecting commits between v1.1.0..v1.2.0
» Found 12 commits, 4 PRs
» Generating with template...

## Release v1.2.0 — March 13, 2026

✨ Features
- feat: add user profile page
- feat: implement dark mode toggle

🐛 Bug Fixes
- fix: resolve login redirect loop
- fix: correct date formatting in reports

🔧 Improvements
- perf: optimize database queries for dashboard

✓ Done in 0.8s

You just generated categorized release notes from your commit history, with zero AI cost. The template engine parses conventional commits (feat:, fix:, chore:, etc.) and groups them automatically.

💡
Shortcut: If you omit --from and --to, Cullit auto-detects by using the two most recent tags.

Save to a file

terminal
$ cullit generate --from v1.1.0 --format html --dry-run > release-notes.html

Output format comparison

## Release v1.2.0 — March 13, 2026

### ✨ Features

  • Add user profile page
  • Implement dark mode toggle

### 🐛 Bug Fixes

  • Resolve login redirect loop
  • Correct date formatting in reports

<h1>Release v1.2.0</h1>

Semantic HTML with <h2> categories, <ul> lists, and a metadata footer. Ready to embed in your docs site or email template.

XSS-safe: all content is escaped

{
  "version": "v1.2.0",
  "date": "2026-03-13",
  "changes": [
    { "description": "Add user profile page",
      "category": "features" },
    ...
  ],
  "changeCount": 5,
  "contributors": ["alice", "bob"]
}
5

Add AI-powered generation

Template-based notes are structured, but AI makes them readable. The AI rewrites your commit messages into polished, audience-appropriate descriptions.

Set your API key

terminal
# Pick ONE provider and set its key:
$ export ANTHROPIC_API_KEY=sk-ant-...
# or
$ export OPENAI_API_KEY=sk-...
# or
$ export GOOGLE_AI_API_KEY=AIza...

Update your config

.cullit.yml
ai: provider: anthropic # or openai, gemini, ollama audience: developer tone: professional
🔑
Pro license required for AI providers. Set your CULLIT_API_KEY (format: clt_...) to unlock AI, Jira enrichment, Linear enrichment, and all publishers. Get your key →

Now generate with AI:

~/your-project
$ cullit generate --from v1.1.0 --to v1.2.0

» License: 🔑 Pro
# Collecting commits between v1.1.0..v1.2.0
» Found 12 commits, 4 PRs
» Generating with Claude (claude-sonnet-4-20250514)...

## Release v1.2.0 — March 13, 2026

A focused release that introduces user profiles and dark mode,
fixes critical auth and date formatting issues, and optimizes
core dashboard performance.

✨ Features
- Introduced user profile pages with avatar, bio, and activity history
- Added system-wide dark mode toggle with persistent preference storage

🐛 Bug Fixes
- Fixed an infinite redirect loop during OAuth login flow that
affected users with expired sessions
- Corrected date formatting in generated reports to respect
the user's locale settings

🔧 Improvements
- Optimized dashboard database queries, reducing p95 load time by 40%

✓ Done in 3.8s

Notice the difference? The AI version has a summary, human-readable descriptions, and context that commit messages alone don’t provide.

Audience modes — same data, different output

Audience Best for Style
developer Engineering team, internal changelog Technical, references PRs and commits
end-user Product updates, customer-facing Plain language, benefit-focused
executive Leadership updates, board reports High-level impact, metrics-oriented
terminal
# Generate customer-facing notes
$ cullit generate --from v1.1.0 --audience end-user

# Generate executive summary
$ cullit generate --from v1.1.0 --audience executive
6

Publish to Slack, Discord & GitHub

Add publish targets to your config and Cullit will push release notes to multiple destinations simultaneously.

.cullit.yml
publish: - type: stdout - type: file path: RELEASE_NOTES.md - type: slack webhook_url: $SLACK_WEBHOOK_URL - type: discord webhook_url: $DISCORD_WEBHOOK_URL - type: github-release
⚠️
Environment variables: The $SLACK_WEBHOOK_URL syntax tells Cullit to read from your environment. Never commit webhook URLs directly in config files.
💻 Terminal stdout
📄 File RELEASE_NOTES.md
💬 Slack #releases channel
🎮 Discord webhook embed
📦 GitHub Release page

Setting up Slack webhooks

terminal
# 1. Create a Slack Incoming Webhook at:
# https://api.slack.com/messaging/webhooks
# 2. Set the env var:
$ export SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../xxx

# Now publish:
$ cullit generate --from v1.1.0
» Published to: stdout, RELEASE_NOTES.md, Slack
✓ Done in 4.1s
7

Automate with GitHub Actions

The real power of Cullit is running it automatically on every release. Add the GitHub Action to generate and publish notes when you push a tag.

.github/workflows/release-notes.yml
name: Release Notes on: push: tags: ['v*'] jobs: release-notes: runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # full history for commit range - uses: mttaylor/cullit@main with: provider: anthropic publish: github-release,slack api-key: ${{ secrets.CULLIT_API_KEY }} env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
⚙️
fetch-depth: 0 is required so Cullit can access the full git history to find commits between tags. Without it, only the triggering commit is available.

What happens when you push a tag

🏷️ git push tag v1.2.0
⚙️ Action runs collects & generates
AI writes notes Claude / GPT / etc
🚀 Published GH Release + Slack
terminal
# Tag and push — release notes generate automatically
$ git tag v1.2.0
$ git push origin v1.2.0

# ✓ GitHub Release created
# ✓ Slack notification sent to #releases
# Zero manual effort

Bonus: Release Advisor

Not sure if you should release? Cullit analyzes your unreleased commits and tells you.

~/your-project
$ cullit status

╔═══════════════════════════════════════════╗
║ Cullit — Release Readiness ║
╚═══════════════════════════════════════════╝

Current version: v1.2.0
Suggested next: v1.3.0 (minor)
Last release: 5 day(s) ago
Unreleased commits: 8

Commit breakdown:
✨ Features: ██████ 3
🐛 Fixes: ████ 2
🧹 Chores: ██████ 3

Should you release? 🟢 Yes — time to release

Why:
→ 3 new features ready to ship
→ 2 bug fixes waiting for release

What’s next

Topic Link
Full configuration reference Configuration docs →
Jira & Linear as primary source Integration docs →
Using as a TypeScript library Library usage →
REST API server API docs →
Docker deployment Docker docs →
Report issues or contribute GitHub →