cloudparts

release-plz

A release tool for Rust that runs in CI: it keeps a release pull request with the next versions and changelogs of your crates up to date, and when you merge it, publishes the new versions to crates.io, tags them and creates GitHub, GitLab or Gitea releases.

Type
Open source
Made by
Marco Ieni and contributors
License
MIT or Apache 2.0
Facts checked
24 October 2026

What it is

release-plz works from two commands, usually run as two jobs on every push to main. release-plz release-pr downloads the last published version of each package from the cargo registry, compares it with the local code to find the commits that changed the package or its dependencies, bumps the version in Cargo.toml, updates CHANGELOG.md, and opens a pull request with the result, or replaces the one already open. release-plz release then publishes every package whose local version isn’t on the registry yet: it creates a git tag named <package>-v<version>, runs cargo publish, and creates a release on the forge. Merging the release pull request is therefore the decision to release.

The next version comes from the commit messages, using the next_version crate. Conventional Commits raise the version the usual way, with a Rust twist for 0.x crates: there a feat bumps the patch and a breaking change bumps the minor, because Cargo treats 0.x to 0.(x+1) as incompatible. Commits that aren’t conventional still produce a release, with a patch bump and an entry under “Other” in the changelog. If cargo-semver-checks is installed, release-plz also runs it on each library, reports “API breaking changes” in the pull request, and bumps the major version (or the minor, under 1.0) when it finds any.

It needs no configuration file: package names, versions, registries and dependencies come from Cargo.toml, and an optional release-plz.toml changes defaults per package. Changelogs are generated with git-cliff used as a library, in Keep a Changelog format by default. It supports workspaces, publishes to crates.io or any other cargo registry, and runs as a GitHub Action, a GitLab CI component or a plain CLI. On GitHub it can publish to crates.io with trusted publishing (OIDC) instead of a stored token.

Why teams pick it

  • Built for Cargo: reads everything from Cargo.toml and the registry, so a workspace needs no manifest or config files to start
  • Works whether or not the project tags releases or writes conventional commits, because it compares against what is published on the registry
  • The only release tool that runs cargo-semver-checks, so an accidental API break shows up in the release pull request before it ships
  • A person still chooses when to release, by merging the pull request, and can edit the proposed changelog first

Watch out for

  • Rust only: polyglot repositories need release-please, Changesets or another tool for their other packages
  • No hooks: custom steps around the release go in separate CI jobs, driven by the action’s outputs
  • With GitHub’s default GITHUB_TOKEN, the release pull request does not trigger your other workflows, so CI checks on it need a personal access token or a GitHub App token
  • Brand-new crates can’t use crates.io trusted publishing: their first version has to be published by hand or with a token

Alternatives

What all release automation have in common →Compare side by side →

How it fits with other technologies

.github/workflows/release-plz.yml: the release job (the release-pr job is the same with `command: release-pr`) · yaml

name: Release-plz
on:
  push:
    branches: [main]
jobs:
  release-plz-release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: read
      id-token: write          # crates.io trusted publishing
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
          persist-credentials: false
      - uses: dtolnay/rust-toolchain@stable
      - uses: release-plz/action@v0.5
        with:
          command: release    # publish what isn't on crates.io yet
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

See it in a real stack

No architecture uses release-plz yet. Drop it into the playground and wire it up yourself.Open playground →
Where it came from2021–2026

Releasing a Rust crate by hand means editing the version in Cargo.toml, bumping it in every crate that depends on it, writing the changelog, publishing in dependency order and tagging. Existing Rust tools such as cargo-release, cargo-workspaces and cargo-smart-release automated parts of this from a developer’s terminal. Marco Ieni started release-plz in December 2021, in a repository under his own GitHub account, to do it in CI through a release pull request, as Google’s release-please does for other languages. He published it to crates.io on February 1, 2022.

He kept two differences from release-please on purpose. Many Rust projects publish to crates.io without ever creating git tags, so release-plz takes the last released version from the registry when no tag exists. And it opens a release pull request for any change to a package, including dependency updates in Cargo.lock, instead of requiring Conventional Commits. Its other distinguishing feature is cargo-semver-checks: the release pull request says whether the library’s public API changed incompatibly, and if so proposes a major release.

The repository later moved to a release-plz GitHub organization. The project now has a documentation site, a GitHub Action, a GitLab CI component and Gitea support, and is sponsored by Encore. It releases very often: 0.3.0 came out in April 2023 and was followed by more than 170 patch releases, and 0.4.0 was released on October 23, 2026.

Why it’s built this way

Read state from the cargo registry, not only git tags
Release-please treats a package as released only when its tag exists, but many Rust projects just run cargo publish. Comparing with the registry makes release-plz work with either habit.
Don’t require Conventional Commits
Every change to a package, including a dependency bump, can matter to its users, so release-plz proposes a release anyway and falls back to a patch bump when commit messages carry no type.
Run cargo-semver-checks before proposing a version
A breaking API change released as a patch breaks users’ builds on their next cargo update. Checking first lets the maintainer revert the change, or merge a release pull request that already bumps the major version.
Focus on CI rather than the terminal
The other Rust release tools are command-line tools. A pull request gives reviewers a place to see and edit the next versions and changelog before anything is published.

Timeline

  1. 2021

    Marco Ieni creates the repository (December 19)

  2. 2022

    First published to crates.io (February 1)

  3. 2023

    0.3.0 (April 16); Marco Ieni presents it at RustLab 23

  4. 2024

    Rustacean Station episode with its creator (April 12)

  5. 2026

    0.4.0 released (October 23) after 0.3.174

Sources14 · facts checked 24 October 2026

Improve this page on GitHub