GitHub Action
Cargo Release PR
A GitHub Action for creating "Release PRs" for Cargo projects.
This action uses cargo-release
to perform a release
of a Cargo project or a crate, but commits the result to a new branch, and submits that branch as a
Pull Request on the repo.
It is meant to be invoked as a "manual" action (via workflow_dispatch
).
The result is a PR which can be reviewed, approved, and merged with the same protocol as normal PRs, avoiding the need for special push permissions for people doing releases. This also provides a staging ground for drafting release notes, and serves as a kind of pre-release announcement, or an "intent to release" declaration.
The body and title of the PR can be customised via inputs, or completely overriden using custom templates.
With a single crate (no workspace):
name: Open a release PR
on:
workflow_dispatch:
inputs:
version:
description: Version to release
required: true
type: string
jobs:
make-release-pr:
runs-on: ubuntu-latest
steps:
- name: Install cargo-release
uses: taiki-e/install-action@v1
with:
tool: cargo-release
- uses: actions/checkout@v3
with:
ref: main
- uses: cargo-bins/release-pr@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
version: ${{ inputs.version }}
With a workspace:
name: Open a release PR
on:
workflow_dispatch:
inputs:
crate:
description: Crate to release
required: true
type: choice
options:
- widget
- gadget
- budget
- fidget
- nugget
version:
description: Version to release
required: true
type: string
jobs:
make-release-pr:
runs-on: ubuntu-latest
steps:
- name: Install cargo-release
uses: taiki-e/install-action@v1
with:
tool: cargo-release
- uses: actions/checkout@v3
with:
ref: main
- uses: cargo-bins/release-pr@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
version: ${{ inputs.version }}
crate-name: ${{ inputs.crate }}
The action does not include a build of cargo-release
itself. Instead, it's expected that
cargo-release
be installed into the workflow prior to this action running, as with the usage
examples above. If cargo-release
is not present when the action runs, it will attempt to install
it with cargo install
(which can be very slow!). If cargo-binstall
is available in the workflow,
it will instead attempt to use that to install cargo-release
.
The action runs cargo-release
with these CLI options:
--verbose
--dependent-version upgrade
--execute
,--no-confirm
(no dry run)--no-push
,--no-tag
(only commit)--no-publish
(no publishing to crates.io yet)--allow-branch release/1.2.3
(so thatcargo-release
doesn't refuse to work)- with working directory set to the root of the crate being released
Otherwise, cargo-release
will behave as normal. Notably, it will read release.toml
files where
present, which can provide further configuration. There are two additional restrictions:
You must not disable commit creation, and you must not enable post-release version bumps.
Doing so will break this action.
Name | Type | Default | Description |
---|---|---|---|
github-token |
String | required | Should be set to ${{ secrets.GITHUB_TOKEN }} . |
version |
String | required | The exact version to release, or any of the bump levels cargo-release supports. It's recommended to use an exact version. |
crate-name |
String | (discovered) | The name of the crate to publish. This is required if there is more than one crate in the repo, e.g. for workspaces, unless crate-path is provided. |
crate-path |
String | (discovered) | The relative (from the repo root) path to the crate to publish. This is required if there is more than one crate in the repo, e.g. for workspaces, unless crate-name is provided. |
pr-title |
String | release: <%= crate.name %> v<%= version.actual %> |
An EJS template string (or a literal string, so long as no EJS tags are present) for the title of the PR. |
pr-label |
String | optional | The name of a label to add to the PR. |
pr-draft |
Boolean | false |
Set to true to create the PR as Draft. |
pr-modifiable |
Boolean | true |
Set to false to disallow maintainers from editing the PR. Note that this is rarely enforceable, as the branch is created in the same repo. |
pr-template |
String | optional | An EJS template string for the body of the PR. This is mutually exclusive with pr-template-file . If neither is provided, the default template is used. |
pr-template-file |
String | optional | The path to an EJS template file for the body of the PR. This is mutually exclusive with pr-template . If neither is provided, the default template is used. |
pr-merge-strategy |
String | squash |
The merge strategy that should be used to merge the release PR. Note that this action is not involved in merging the PR; this input is only a hint which is rendered by the (default) template. May be either of: squash , merge , rebase , bors . |
pr-release-notes |
Boolean | false |
Includes a section in the PR body (with the default template) which can be used to fill in release notes. |
git-user-name |
String | github-actions |
The git user name, which will be used for the release commit. |
git-user-email |
String | github-actions@github.com |
The git user email, which will be used for the release commit. |
base-branch |
String | (discovered) | The branch which the release PR will target. Note that the action does not checkout this branch, so mismatches could cause odd behaviour. Defaults to the repo's configured default branch. |
branch-prefix |
String | release |
The prefix to use to name the branch used for the PR. This will be joined onto the version input with / . |
PR title and body templates are EJS. The following variables are available:
interface TemplateVars {
pr: {
title: string; // value of the `pr-title` input
label?: string; // value of the `pr-label` input
draft: boolean; // value of the `pr-draft` input
modifiable: boolean; // value of the `pr-modifiable` input
template?: string; // value of the `pr-template` input
templateFile?: string; // value of the `pr-template-file` input
mergeStrategy: string; // value of the `pr-merge-strategy` input
releaseNotes: boolean; // value of the `pr-release-notes` input
};
crate: {
name: string; // the name of the crate being released
path: string; // the full/absolute path to the crate
};
version: {
previous: string; // the version of the crate prior to any changes
actual: string; // the version of the crate after being released
desired: string; // the value of the `version` input
};
branchName: string; // the name of the branch used for the PR
title?: string; // the rendered title of the PR
// this is only available to the PR body template
}
The action sets the following:
pr-branch
(String) The name of the branch used for the PRpr-url
(String) The URL to the newly-created PRversion
(String) The version of the crate after release
This action pairs with two other actions:
cargo-bins/pr-release-notes
: extract release notes from a PR, such as the one created by this actioncargo-bins/tag-on-merge
: publish a tag when a commit with a particular message is merged