CLI tool
release-drafter/release-drafter avatar
release-drafter/release-drafter

Release Drafter: draft GitHub release notes from merged pull requests

Drafts your next release notes as pull requests are merged into master.

3,944 stars381 forksTypeScriptISC

At a glance

What is it?
Release Drafter is a GitHub Action and CLI that keeps a draft release up to date as pull requests merge, building the changelog from labels and titles. It fits teams that already label pull requests; it fits badly when nobody does.
Who is it for?
Adopt Release Drafter if your pull requests carry labels such as feature, fix or chore, because the categories in .github/release-drafter.yml are matched against them, and if you want the draft release to exist before the tag does. Do not adopt it if your merge history is unlabelled and you will not start labelling; the generated changelog will be a flat list of titles, and the version resolution will fall back rather than infer a bump.
Can I use it commercially?
Yes. ISC is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What Release Drafter solves, and for whom

Writing release notes is a task that gets postponed until the tag is already pushed. Release Drafter inverts the order: the notes are assembled while the pull requests are still merging, and the release stays in draft until someone publishes it. The README states the purpose plainly: "Draft the next release notes as pull requests merge into a branch."

The audience is teams on GitHub that treat pull request labels as structured data. The configuration example in the README maps labels to categories: 'feature' and 'enhancement' become a Features section, 'fix', 'bugfix' and 'bug' become Bug Fixes, 'chore' becomes Maintenance. If your repository already does this, the changelog is nearly free. If labels are applied inconsistently, the output is only as good as the labelling, and the tool will not tell you what it missed.

There is a second audience: people who want a version number decided by rules rather than by argument. The example config attaches semver-increment to a category and adds explicit version-resolver entries for a 'major' label. That means the next version is computed from what merged, not chosen in a meeting.

How the action builds a draft release

The action runs on a workflow trigger, typically push to main. On each run it reads a configuration file, defaulting to .github/release-drafter.yml, fetched through the GitHub API. The README notes you do not need to check out the repository, which keeps the workflow step short.

From that configuration it reads the template, the category rules and the change-template, then renders the body of a draft release. The change-template in the README example is '- $TITLE (#$NUMBER) $AUTHORS', so each merged pull request becomes one line with its title, number and authors. The template wraps those lines, and $CHANGES is the placeholder that receives them.

Category matching is the part worth understanding before you write config. A category can match on labels or on title conditions, and the README shows two shapes: when.labels as a list, and when.label as a single value. Categories can also carry a type. 'pre-exclude' removes matching pull requests from the changelog entirely, which is how the example drops anything labelled 'skip-changelog'. 'version-resolver' categories contribute a semver increment instead of a section. So the same label can either appear in the notes or influence the version number, depending on which category type it is attached to.

One detail that is easy to miss: change-title-escapes. The example sets it to '\<*_&' with the comment that this prevents mentions and code blocks. Pull request titles are user input, and without escaping, a title containing an @handle would notify that person from the release page.

Setting up the Release Drafter GitHub Action

Installation is a workflow file. The README gives this example for .github/workflows/release-drafter.yml. It runs on push to main, requests write access to contents and read access to pull requests, and uses the action at the v7 tag.

yaml
name: Release Drafter

on:
  push:
    branches:
      - main

permissions:
  contents: write
  pull-requests: read

jobs:
  update_release_draft:
    runs-on: ubuntu-slim
    steps:
      - uses: release-drafter/release-drafter@v7
        with:
          config-name: release-drafter.yml

After the first run on main you should see a draft release in the repository's releases page. It will be sparse until pull requests merge.

The action requires a configuration file. The smallest working one from the README is a template with a $CHANGES placeholder:

yml
template: |
  ## What's Changed

  $CHANGES

Save that as .github/release-drafter.yml and the next merge will add a line to the draft. To get grouping and version resolution, extend it with categories and templates. The README's fuller example sets name-template and tag-template to 'v$RESOLVED_VERSION', a change-template of '- $TITLE (#$NUMBER) $AUTHORS', and categories that map labels to sections. The category-template default is "## $TITLE", so each category heading is produced from the category title unless you override it.

Running the CLI locally with --dry-run

The action is not the only entry point. Release Drafter ships a CLI, and the README says it requires Node.js 24 or later. This is the fastest way to see what the tool would produce without touching a release.

sh
npx release-drafter owner/repo --dry-run

Authentication depends on the host. For GitHub.com or GitHub Enterprise Cloud on *.ghe.com, use GH_TOKEN or GITHUB_TOKEN. For GitHub Enterprise Server, use GH_ENTERPRISE_TOKEN or GITHUB_ENTERPRISE_TOKEN. The README is explicit that Release Drafter does not invoke gh, so if you want to reuse GitHub CLI credentials you pass them through the environment:

sh
GH_TOKEN="$(gh auth token)" npx release-drafter owner/repo --dry-run

There is also a check command that validates a single pull request against the same category rules the Check PR action uses:

sh
npx release-drafter check-pr owner/repo 123

That is useful in review: it answers whether pull request 123 would land in a category or be excluded, before it merges. The README points to the package README for the complete option reference, configuration targets, JSON output and exit codes, so treat the commands above as the starting point rather than the full surface.

Where Release Drafter is the wrong tool

The dependency on labels is the main failure mode, and it fails quietly. A category with when.labels only matches pull requests that carry one of those labels. Unlabelled pull requests do not vanish from the changelog; they simply do not appear under a category, and nothing in the tool reports the omission. On a repository where labelling is aspirational, the draft release will look thinner than the actual work.

Version resolution has the same shape. The README example shows a category with semver-increment: minor for features, and separate version-resolver categories for 'major' and 'patch'. If none of those labels is present on the merged pull requests, the resolved version has no signal to work from. Teams that expect the tool to infer a major release from a breaking change description will be disappointed, because the mechanism is label-driven.

There is also a scope question. Release Drafter drafts notes for a branch. It is not a changelog generator that walks every commit, and it does not replace a release process that includes building artifacts, signing, or publishing to a package registry. It produces the text and the draft; what happens when you press publish is yours. The repository layout hints at wider ambitions, with conformance test scripts for gitea, forgejo and gitlab in package.json, but the README documents GitHub Actions usage, and the CLI README is the place the project points for the rest.

Release Drafter compared with release-please

release-please is the alternative people usually weigh against it, and the difference is where the information comes from. release-please derives releases from Conventional Commits: the commit message prefix decides the section and the version bump. Release Drafter derives them from pull request labels and titles, as the change-template and category rules show.

That single choice cascades. With release-please, discipline lives in the commit or squash-merge message, and a well-formed message is enough. With Release Drafter, discipline lives in labels applied at the pull request level, which is easier to enforce with a template and a bot, and easier to inspect before merge. Release Drafter can also pre-exclude entries, so a labelled pull request can be kept out of the notes entirely, which is awkward to express through commit messages alone.

The cost is the same in both directions: neither tool reads intent. If your team writes Conventional Commits but does not label, release-please will produce a better changelog. If your team labels carefully and squash-merges with messy messages, Release Drafter will.

Maintenance, upgrades and the ISC licence

The repository is not archived, and the last push was on 2026-09-23. Releases are frequent: v7.7.0 on 2026-07-29, v7.6.0 on 2026-07-19, v7.5.1 on 2026-06-25. The root package.json declares version 7.7.0 and engines of node ^24.11.0 || >=26.0.0 with npm >=12.0.1, which is a narrow window for a tool you might run in CI on a pinned runner image.

The upgrade cost is mostly configuration drift, not code. The README's workflow example pins the action at release-drafter@v7, so moving to v8 means editing that line and re-checking your categories against whatever changed in the schema. The repository carries a schema.json at the top level, which is the file to consult when a config key stops validating. There is also a documented path for loading a generated configuration, extending another configuration, or loading from another repository, which matters if several repositories share one set of category rules.

The licence is ISC, a permissive licence in the same family as MIT. That permits commercial use and modification, and it requires preserving the copyright and licence notice. This is a description of the licence identifier, not legal advice; if your organisation has a licence policy, run it through that.

Editorial conclusion

Adopt Release Drafter if your pull requests carry labels such as feature, fix or chore, because the categories in .github/release-drafter.yml are matched against them, and if you want the draft release to exist before the tag does. Do not adopt it if your merge history is unlabelled and you will not start labelling; the generated changelog will be a flat list of titles, and the version resolution will fall back rather than infer a bump. Before rolling it out, verify one thing: run npx release-drafter owner/repo --dry-run with a GH_TOKEN and read the output against your last hand-written release notes. If the categories come out empty or wrong, the problem is your labels, not the action.

Frequently asked questions

How to automate release notes with Release Drafter?

Add the Release Drafter GitHub Action to a workflow that runs on push to your main branch, and give it a configuration file at .github/release-drafter.yml. As pull requests merge, the action appends them to a draft release using the change-template and groups them with the categories you define.

How to draft a release in GitHub with Release Drafter?

The action creates and updates a draft release rather than publishing one. The README's workflow example triggers on push to main, and the resulting draft appears in the repository's releases page, where you review it and publish when ready.

Does Release Drafter need a configuration file?

Yes. The README states the action requires a configuration file and loads .github/release-drafter.yml by default through the GitHub API, so no checkout step is needed. The minimum is a template containing the $CHANGES placeholder.

What Node.js version does the Release Drafter CLI need?

The README says the CLI requires Node.js 24 or later. The root package.json declares engines of node ^24.11.0 || >=26.0.0 and npm >=12.0.1 for the workspace itself.

Which token does the Release Drafter CLI use on GitHub Enterprise Server?

For GitHub Enterprise Server, authenticate with GH_ENTERPRISE_TOKEN or GITHUB_ENTERPRISE_TOKEN. For GitHub.com and GitHub Enterprise Cloud on *.ghe.com, use GH_TOKEN or GITHUB_TOKEN instead.

Official sources

  1. License: ISC
  2. Project website
  3. README
  4. release-drafter/release-drafter on GitHub
  5. Releases
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/release-drafter-release-drafter.svg)](https://hysenlabs.com/projects/release-drafter-release-drafter)
Community notes

Community notes