release-please: release PRs from Conventional Commits
Project brief: generate release PRs based on the conventionalcommits.org spec. Linear git commit history (use squash-merge) We highly recommend that you use squash-merges when merging pull requests.
At a glance
- What is it?
- release-please turns Conventional Commit messages into a standing release pull request that maintains CHANGELOG.md, version bumps and GitHub releases. It is a good fit for teams with linear git history and a poor fit for anyone who wants the tool to publish to a package registry.
- Who is it for?
- Adopt release-please if your default branch is squash-merged, your commits follow the Conventional Commits spec, and you only need changelog, tag and GitHub Release automation. Do not adopt it if you expect it to publish to npm, PyPI or another registry, or if you rely on plain merge commits, because the README states the BEGIN_COMMIT_OVERRIDE feature does not work with them.
- Can I use it commercially?
- Yes. Apache-2.0 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 15 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 17, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What release-please automates, and what it deliberately leaves out
The project parses git history for Conventional Commit messages and maintains a release pull request on your default branch. That pull request is not a one-off: release-please keeps it up to date as further work lands, and merging it is the trigger for the rest of the sequence. On merge, the README states that release-please updates your changelog file (for example CHANGELOG.md) along with language-specific files such as package.json, tags the commit with the version number, and creates a GitHub Release from that tag.
The audience is teams that already write Conventional Commits and want releases to be a review step rather than a script. The scope boundary is stated plainly in the README: it does not handle publication to package managers or complex branch management. So release-please stops at the tag and the GitHub Release. Pushing the artifact to npm, PyPI or a container registry is somebody else's job, and any team that expects one tool to cover both halves will be disappointed.
Version selection follows the commit prefixes. A fix: commit correlates to a SemVer patch, feat: to a minor, and feat!:, fix!: or refactor!: to a major. The README also notes that a releasable unit is a commit with one of the prefixes feat, fix or deps, and that chore or build commits are not releasable units. Some languages add their own prefixes on top of that set; the README gives docs as an example for Java and Python.
The release PR lifecycle and its status labels
The mechanism is label-driven, and understanding the labels is most of understanding the tool. A release pull request starts in the autorelease: pending state. Once it is merged and the release has been tagged in GitHub, the label becomes autorelease: tagged. There is a third state, autorelease: snapshot, described as a special state for snapshot version bumps. A fourth, autorelease: published, is intended to mark that a GitHub release has been published from the release PR, but the README is explicit that release-please does not add it automatically and recommends it only as a convention for publication tooling.
That last point matters more than it looks. Because the published state is not set by the tool, any dashboard that treats autorelease: published as the end of the pipeline is reading a label a human or a downstream job has to apply. The pending label is the one with real teeth: for GitHub application users, release-please will not create a new pull request while an existing pull request carries autorelease: pending. The README attributes the common cause to GitHub API failures, where the tag was not removed correctly after a previous release, leaving release-please convinced that the previous release is still pending. The documented remedy is to confirm there is no genuine pending release and then remove the autorelease: pending or autorelease: triggered label.
This is a state machine whose failure mode is silence. Nothing errors; no release PR appears. The README's troubleshooting flow is therefore ordered: first confirm that releasable units have been merged since the last release, then hunt for the stale label, then rerun release-please.
How to install release-please and open your first release PR
The package is published on npm under the name release-please, and package.json declares the binary at build/src/bin/release-please.js. A local install therefore gives you a release-please command without any GitHub App configuration:
npm install release-please
npx release-please --helpRunning the CLI against a repository requires a token for the GitHub API and a target repository. The README does not spell out the full flag list, so check the command's own help output before scripting it. What the README does document is the pattern for forcing a specific version. A commit to the main branch whose body contains Release-As: x.x.x, case insensitive, makes release-please open a pull request for that exact version. The documented empty-commit form is:
git commit --allow-empty -m "chore: release 2.0.0" -m "Release-As: 2.0.0"That produces a commit whose subject is chore: release 2.0.0 and whose body is Release-As: 2.0.0. The repository also ships a release-please-config.json and a .release-please-manifest.json at its top level, which is the layout the manifest-driven mode expects; those files are the project's own configuration rather than a template you copy verbatim.
The most common first run is the GitHub Action, since it needs no local installation at all. The README does not reproduce the workflow YAML, so take the action's inputs from the repository's own documentation rather than from a blog post. Whatever route you choose, the first observable result is a pull request, not a release.
Fixing release notes after the fact with BEGIN_COMMIT_OVERRIDE
Release notes are generated from commit messages, and commit messages written inside a pull request often make no sense once merged. The README gives a concrete example: a branch may contain feat: introduce feature A followed by fix: some bugfix introduced in the first commit, where the fix is irrelevant to the release notes because the bug never existed on the main branch. Squash-merging collapses that noise into one commit.
When it is too late for that, release-please supports an override block. Editing the body of the merged pull request and adding a section between BEGIN_COMMIT_OVERRIDE and END_COMMIT_OVERRIDE makes the next run use that section instead of the merged commit message:
BEGIN_COMMIT_OVERRIDE
feat: add ability to override merged commit message
fix: another message
chore: a third message
END_COMMIT_OVERRIDEThe README attaches a warning to this feature: it will not work with plain merges, because release-please does not know which commit or commits to apply the override to. The recommendation is squash-merge instead. That is a real constraint, and it is the clearest signal in the documentation that the project's design assumes one commit per merged pull request.
The same assumption applies to a single commit carrying several logical changes. The README shows a commit whose body holds additional feat and fix footers, each becoming its own changelog entry, with a BREAKING-CHANGE footer attaching a breaking-change note to one of them. The README states the additional messages must be at the bottom of the commit.
Where release-please is the wrong tool
The sharpest limitation is the one the README states outright: release-please does not publish to package managers. If your release process is defined as "a version appears on npm", release-please gets you to a tag and a GitHub Release and stops there. Wiring up the publish step is separate work, and the autorelease: published label is the suggested convention for signalling that the downstream job finished.
The second limitation is history shape. The README highly recommends squash-merges and lists the reasons: commits stay sorted by merge date, git bisect stays useful, the changelog stays under control, and the main branch does not pass through states where tests fail, as it would with red/green development merged or rebase-merged. The override feature breaks under plain merges. Teams that treat merge commits as non-negotiable are working against the tool's assumptions, not merely using it differently.
The third is prefix discipline. A commit that does not carry feat, fix or deps is not a releasable unit, and a branch full of chore and build commits will produce no release PR at all. The README's first troubleshooting step is exactly this check, which tells you how often it happens in practice. Release-please does not infer intent from diffs; it reads messages, and messages that do not conform simply do not count.
Finally, the pending-label deadlock described above is an operational hazard rather than a design flaw, but it is the kind of hazard that costs an afternoon if nobody on the team knows the label exists.
release-please against semantic-release and changesets
The meaningful difference from semantic-release is where the decision point sits. semantic-release publishes on every qualifying merge to the release branch: the pipeline runs, the version is computed, and the release happens without a human in the loop. release-please inverts that. It prepares a pull request and waits. Merging that pull request is the release decision, and until someone merges it, the changelog diff and the version bump are visible and reviewable. Teams that want an approval gate before a version number is burned should prefer the release PR model; teams that want zero ceremony should not.
Changesets sits closer to release-please in that it also accumulates pending release information, but its unit of input is a changeset file written alongside the code, not the commit message. That means a contributor declares the version bump explicitly in a file rather than encoding it in a commit prefix. It also means the repository carries those files, and the changelog is assembled from them. If your contributors already write Conventional Commits, release-please needs no extra artifact; if you would rather not police commit messages, a changeset file moves the requirement somewhere easier to review.
Both comparisons come down to one question: do you want the release decision to be a pull request you merge, and are you willing to keep commit messages clean to make that pull request correct? If the answer to the second half is no, the first half does not save you.
Licence, maintenance and the cost of staying current
The project is Apache-2.0, and package.json carries the same identifier. Apache-2.0 includes an explicit patent grant and requires that notices and the licence text be preserved in redistributions. If you vendor the source or ship a modified build, that obligation travels with it. This is a description of the licence text, not legal advice; have counsel review anything you redistribute.
The repository is not archived, and the last push was on 2026-08-24, which is the same timestamp as the v17.11.2 release. The two releases before it, v17.11.0 and v17.11.1, landed on 2026-07-30 and 2026-07-31. So the project is being released, and the cadence over that window is roughly one minor and a couple of patches per month.
Upgrade cost is dominated by the fact that release-please writes to your repository. A new version can change how CHANGELOG.md is formatted, how version files are rewritten, or how the release PR is titled, and those changes show up as diffs in the release PR you are about to merge. The project's own test suite leans on snapshot testing, with a test:snap script that sets SNAPSHOT_UPDATE=1, which is a hint about how much of the output is contract-like. For consumers, the practical consequence is that a version bump deserves a look at the release PR it produces on a scratch branch before it reaches the branch that matters. The release-please-config.json and .release-please-manifest.json files in your repository are the surface most likely to need attention, since they encode the strategy and the last released version.
Editorial conclusion
Adopt release-please if your default branch is squash-merged, your commits follow the Conventional Commits spec, and you only need changelog, tag and GitHub Release automation. Do not adopt it if you expect it to publish to npm, PyPI or another registry, or if you rely on plain merge commits, because the README states the BEGIN_COMMIT_OVERRIDE feature does not work with them. Before rolling it out, verify two things in your own repository: that every merge lands as a single commit with a Conventional Commit subject, and that no stale pull request is sitting under an autorelease: pending or autorelease: triggered label, since the README says that label blocks new release PRs.
Frequently asked questions
What does release-please do?
It parses git history for Conventional Commit messages and maintains a release pull request. Merging that pull request updates the changelog and language-specific files, tags the commit, and creates a GitHub Release.
What is a release PR in release-please?
It is a standing pull request that release-please keeps up to date as more work is merged to the default branch. When you are ready to tag a release, you merge it. Its state is shown by labels such as autorelease: pending and autorelease: tagged.
How do I set up release-please?
The package is published on npm as release-please, and package.json declares its binary, so a local install gives you the command. The README does not reproduce the GitHub Action workflow YAML, so take the action's inputs from the repository's own documentation.
How do I use release-please to force a specific version?
Put Release-As: x.x.x in the body of a commit to the main branch, case insensitive, and release-please opens a pull request for that version. The README's example is an empty commit with the message chore: release 2.0.0 and a body of Release-As: 2.0.0.
What is the difference between release-please and semantic-release?
semantic-release publishes on every qualifying merge, while release-please prepares a release pull request and waits for you to merge it. That makes the version bump and changelog diff reviewable before a release happens.
Official sources
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.
[](https://hysenlabs.com/projects/googleapis-release-please)