Skip to content

yt/conventional-release

Repository files navigation

conventional-release

GitHub Release Go Report Card CI License: MIT

Lightweight semantic release tool with GitHub Copilot release notes. A single binary reimplementation of semantic-release — no Node.js required, works with any project.

Features

  • Conventional commit parsing (Angular preset) with full spec compliance
  • GitHub Copilot release notes via gh CLI
  • Template-based release notes as fallback (no AI key required)
  • Custom keyword-to-bump mappings in config
  • GitHub release creation with asset uploads (glob patterns)
  • GitHub Actions auto-detection (token, repo, branch from env)
  • Dry-run mode with full output preview
  • Large repo support — streaming git log, batched AI notes, truncated templates
  • Safety guards — PR skip, behind-remote detection, auto dry-run outside CI

Install

Download from GitHub Releases.

Usage

# Preview without publishing
conventional-release --dry-run

# With Copilot release notes
conventional-release --copilot

# In GitHub Actions (auto-detects token, repo, branch)
conventional-release

GitHub Copilot Release Notes

When --copilot is set (or ai.enabled: true in config), release notes are generated by calling the GitHub Copilot API via the gh CLI.

Prerequisites

  1. Install the gh CLI: https://cli.github.com
  2. Authenticate (local only — not needed in GitHub Actions):
    gh auth login
  3. Set COPILOT_GITHUB_TOKEN to a GitHub classic PAT with Copilot access. In GitHub Actions this is typically a PAT stored as a repository secret.

GitHub Actions setup

- name: Release
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
  run: conventional-release --copilot

If COPILOT_GITHUB_TOKEN is not set, gh falls back to its own authenticated session (GH_TOKEN / GITHUB_TOKEN in Actions).

Custom prompt file

Create .conventional-release-prompt in your project root to append instructions to the base system prompt sent to Copilot. The file is optional — if it doesn't exist it is silently ignored.

Always write in a friendly tone.
Group breaking changes first and highlight them clearly.
Keep each bullet point to one sentence.

The path can be changed in config via ai.promptFile.

Repo context

By default Copilot only sees what is explicitly passed in the prompt (version, commits). Pass --repo-context to also grant Copilot shell access to git commands, allowing it to pull richer information about the repository:

conventional-release --copilot --repo-context
# or just --repo-context (implies --copilot)
conventional-release --repo-context

When --repo-context is active, Copilot may run any of the following during note generation:

What Copilot accesses Why
git log --oneline Full commit history for context
git diff <tag>..HEAD Detailed diff of changes
git show Commit bodies and metadata
cat README.md Project description and context

These are read-only git commands. No writes, pushes, or network calls are made by the tool access itself.

Fallback

If --copilot is not set, template-based release notes are generated with no external calls.

Configuration

Create .conventional-release.yaml in your project root:

tagPrefix: "v"
branch: "main"
firstVersion: "1.0.0"

ai:
  enabled: true          # same as --copilot flag
  promptFile: ".conventional-release-prompt"  # custom prompt appended to system prompt (default)

keywords:
  big: "major"
  problem: "major"

assets:
  - "dist/*.tar.gz"
  - "dist/*.zip"

commitsPerSection: 50    # max commits per section in template notes (0 = unlimited)

Priority

CLI flags > environment variables > CI-detected values > config file > defaults.

Environment Variables

Variable Description
GITHUB_TOKEN GitHub API token for creating releases
COPILOT_GITHUB_TOKEN GitHub token with Copilot access (classic PAT)

CLI Flags

Flag Short Description
--dry-run -n Preview without publishing
--config -c Config file path (default .conventional-release.yaml)
--copilot Generate release notes with GitHub Copilot
--repo-context Allow Copilot to run git commands for possibly more repo aware knowledge (implies --copilot)
--github-token GitHub token
--no-ci Force real release when not in CI
--verbose -V Enable debug logging
--version -v Print version

How It Works

  1. Detect CI environment (GitHub Actions)
  2. Load config (file + env + flags)
  3. Find latest semver tag
  4. Collect commits since last tag
  5. Parse conventional commits
  6. Determine bump type (major/minor/patch)
  7. Generate release notes (Copilot via gh api or template)
  8. Create git tag + GitHub release
  9. Upload assets

Commit Types

Type Bump
feat minor
fix, perf patch
revert patch
Breaking change (! or BREAKING CHANGE footer) major
Everything else (chore, docs, non-conventional, merge commits, etc.) none

Special Behaviors

  • [skip release] or [release skip] in commit message: excluded from analysis
  • PR builds: automatically skipped (exit 0)
  • Behind remote: skipped to prevent conflicts
  • Not in CI: auto dry-run (override with --no-ci)

Multi-branch Releases

By default, any branch named main, master, next, next-major, beta, or alpha is a release branch, matching the semantic-release defaults. Maintenance branches (1.x, 2.3.x, etc.) are also detected automatically.

Override with an explicit branches list in config:

branches:
  - name: main
  - name: next
  - name: beta
    prerelease: true       # produces v1.1.0-beta.1, v1.1.0-beta.2, …
  - name: alpha
    prerelease: true

Maintenance branches

A branch named 1.x or 1.1.x restricts releases to that version line:

main:  v2.1.0
1.x:   v1.5.2 → fix: patch → v1.5.3   (never reaches 2.0.0)
1.1.x: v1.1.9 → fix: patch → v1.1.10  (never reaches 1.2.0)

Prerelease branches

branches:
  - name: beta
    prerelease: true      # identifier = branch name
  - name: rc-candidate
    prerelease: "rc"      # explicit identifier

Versions produced: v2.0.0-beta.1, v2.0.0-beta.2, …, v2.0.0-rc.1, …

A prerelease branch has no version range constraint. Once merged to a release branch, the next run on that branch cuts the stable release.

Tag format

Change the tag format with tagFormat (default: v${version}):

tagFormat: "${version}"        # no prefix: 1.2.3
tagFormat: "app/v${version}"   # scoped: app/v1.2.3

The format is also used to filter which existing tags are treated as releases for this project.

Glob branch patterns

branches:
  - name: "release/*"
    channel: "${name}"

${name} is substituted with the matched branch name. Non-existent remote branches are silently dropped.

Branch validation

The tool validates the branch config at startup and exits with a descriptive error on:

  • Duplicate branch names
  • Maintenance branch patterns that overlap
  • Prerelease branches sharing the same identifier
  • Fewer than 1 or more than 3 release branches
  • Invalid branch names (containing ~ or ^)

License

MIT

About

Lightweight semantic release tool with GitHub Copilot release notes.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors