Skip to content

offload-project/release-champion

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Release Champion

A GitHub Action that automates semantic versioning and releases using conventional commits. Merge a PR and the action handles the rest — version bumps, changelogs, tags, and GitHub releases. Optionally gate releases behind a label.

Quick start

  1. Add the workflow to your repo (see Usage below)
  2. Merge a PR — the action creates a release PR with the version bump and changelog
  3. Review and merge the release PR — the action creates the tag and GitHub release

By default, every merged PR triggers a release. If you'd rather control when releases happen, set require-release-label: true and add the configured label (default: change-release) to PRs that should trigger a release.

How it works

The action operates in two phases, both triggered by pull_request closed events:

Phase 1: Create a release PR

When a PR is merged (and the release label requirement is met, if enabled):

  1. Finds the latest version tag
  2. Analyzes all commits since that tag using conventional commit prefixes
  3. Determines the appropriate semver bump (major, minor, or patch)
  4. Creates a release/<prefix><version> branch
  5. Bumps package.json version if npm publishing is enabled
  6. Optionally generates/updates CHANGELOG.md
  7. Opens a release PR with a summary of what's included

Phase 2: Finalize the release

When the release PR (detected by the release/ branch prefix) is merged:

  1. Creates an annotated git tag
  2. Optionally creates a GitHub release with auto-generated release notes
  3. Optionally publishes to an npm registry

Usage

# .github/workflows/release.yml
name: Release

on:
  pull_request:
    types: [ closed ]

permissions:
  contents: write
  pull-requests: write

jobs:
  release:
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          ref: ${{ github.event.pull_request.merge_commit_sha }}
          fetch-depth: 0
      - uses: offload-project/release-champion@v1
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}

Note: fetch-depth: 0 is required so the action can access the full commit history and tags.

Inputs

Input Description Required Default
github-token GitHub token for creating PRs, tags, and releases Yes
release-label Label that marks a PR for release (only used when require-release-label is true) No change-release
require-release-label Require the release label to trigger a release PR. When false, every merged PR triggers a release No false
version-prefix Prefix for version tags (e.g., v produces v1.2.3) No v
create-tag Create a git tag when the release PR is merged No true
create-release Create a GitHub release when the release PR is merged No true
draft-release Create the GitHub release as a draft (unpublished) No true
changelog Generate or update CHANGELOG.md in the release PR No true
publish-npm Publish the package to an npm registry when the release PR is merged No false
npm-token Auth token for the npm registry (required when publish-npm is true) No
npm-registry npm registry URL (set to https://npm.pkg.github.com for GitHub Packages) No https://registry.npmjs.org
npm-build-command Build command to run before npm publish (e.g., npm run build) No

Outputs

Output Description
version The new version string (e.g., 1.2.3)
release-pr URL of the created release PR (Phase 1)
tag The created tag name (Phase 2)
release-url URL of the created GitHub release (Phase 2)

Conventional commits and version bumps

The action parses commit messages to determine the version bump:

Commit prefix Bump Example
feat!: or BREAKING CHANGE major feat!: drop support for Node 14
feat: minor feat(auth): add OAuth2 support
fix: patch fix: resolve null pointer in parser
chore:, docs:, refactor:, perf:, style:, build: patch chore: update dependencies

The highest applicable bump wins. If any commit contains a breaking change, the bump is always major.

Changelog format

When changelog is enabled, the action generates a CHANGELOG.md grouped by change type with links to the associated PRs:

## v1.3.0 - 2026-03-27

### Added

- Add support for wildcard permissions [#234](https://github.com/owner/repo/pull/234)
- Add `hasAnyPermission` method [#230](https://github.com/owner/repo/pull/230)

### Fixed

- Fix cache invalidation on role update [#232](https://github.com/owner/repo/pull/232)

### Changed

- Update minimum PHP version to 8.1 [#228](https://github.com/owner/repo/pull/228)

Commits that can't be linked to a PR will reference the commit SHA instead.

Examples

Minimal — tags and draft releases

- uses: offload-project/release-champion@v1
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}

Published releases, no changelog

- uses: offload-project/release-champion@v1
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    draft-release: false
    changelog: false

Require a label to release

- uses: offload-project/release-champion@v1
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    require-release-label: true

Custom label and no version prefix

- uses: offload-project/release-champion@v1
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    require-release-label: true
    release-label: 'ready-to-release'
    version-prefix: ''

Publish to npm

- uses: offload-project/release-champion@v1
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    publish-npm: true
    npm-token: ${{ secrets.NPM_TOKEN }}
    npm-build-command: 'npm run build'

Publish to GitHub Packages

- uses: offload-project/release-champion@v1
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    publish-npm: true
    npm-token: ${{ secrets.GITHUB_TOKEN }}
    npm-registry: 'https://npm.pkg.github.com'
    npm-build-command: 'npm run build'

Tag only, no GitHub release

- uses: offload-project/release-champion@v1
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    create-release: false

Using outputs

steps:
  - uses: actions/checkout@v6
    with:
      ref: ${{ github.event.pull_request.merge_commit_sha }}
      fetch-depth: 0
  - uses: offload-project/release-champion@v1
    id: release
    with:
      github-token: ${{ secrets.GITHUB_TOKEN }}
  - if: steps.release.outputs.version
    run: echo "Released version ${{ steps.release.outputs.version }}"

Permissions

The workflow needs contents: write (for tags and releases) and pull-requests: write (for creating PRs). If publishing to GitHub Packages, also add packages: write. If using the default GITHUB_TOKEN, set these under the job's permissions key.

Tests

bats tests/conventional.bats

License

MIT

About

Automated semantic versioning and releases using conventional commits

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages