Introduction

releaser-pleaser is a tool designed to automate versioning and changelog management for your projects. Building on the concepts of release-please, it streamlines the release process through GitHub Actions or GitLab CI.

Badge: Documentation Badge: Stable Release Badge: License GPL-3.0

Features

  • Automated Pull Requests: Opens a PR when releasable changes are detected.
  • Smart Versioning: Suggests new versions based on conventional commits and semantic versioning.
  • Version Reference Updates: Automatically updates committed version references in the PR.
  • Changelog Generation: Creates new changelog entries based on commits.
  • Automated Releases: Upon PR merge, creates tags and GitHub/GitLab Releases with appropriate messages.
  • Version Overrides: Allows manual override of the suggested version.
  • Prerelease Support: Offers options to create alpha, beta, or release candidate versions.

releaser-pleaser simplifies release management, allowing maintainers to focus on development while ensuring consistent and well-documented releases.

Relation to release-please

After using release-please for 1.5 years, I've found it to be the best tool for low-effort releases currently available. While I appreciate many of its features, I identified several additional capabilities that would significantly enhance my workflow. Although it might be possible to incorporate these features into release-please, I decided to channel my efforts into creating a new tool that specifically addresses my needs.

Key differences in releaser-pleaser include:

  • Support for multiple forges (both GitHub and GitLab)
  • Better support for pre-releases

One notable limitation of release-please is its deep integration with the GitHub API, making the addition of support for other platforms (like GitLab) a substantial undertaking. releaser-pleaser aims to overcome this limitation by design, offering a more versatile solution for automated release management across different platforms and project requirements.

License

This project is licensed under the GNU General Public License v3.0 (GPL-3.0).

Getting started on GitHub

In this tutorial you will learn how to set up releaser-pleaser in your GitHub project with GitHub Actions.

1. Repository Settings

1.1. Squash Merging

releaser-pleaser requires you to use squash merging. With other merge options it can not reliably find the right pull request for every commit on main.

Open your repository settings to page General:

https://github.com/YOUR-NAME/YOUR-PROJECT/settings

In the "Pull Requests" section make sure that only "Allow squash merging" is enabled and "Allow merge commits" and "Allow rebase merging" is disabled.

Screenshot of the required merge settings

1.2. Workflow Permissions

releaser-pleaser creates release pull requests for you. By default, Actions are not allowed to create pull requests, so we need to enable this.

Open your repository settings to page Actions > General:

https://github.com/YOUR-NAME/YOUR-PROJECT/settings/actions

In the "Workflow permissions" section make sure that "Allow GitHub Actions to create and approve pull requests" is enabled.

Screenshot of the required workflow settings

2. GitHub Actions Workflow

Create a new file .github/workflows/releaser-pleaser.yaml with this content. Make sure that it is available on the main branch.

name: releaser-pleaser

on:
  push:
    branches: [main]
  pull_request_target:
    types:
      - edited
      - labeled
      - unlabeled

jobs:
  releaser-pleaser:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - name: releaser-pleaser
        uses: apricote/releaser-pleaser@v0.4.0

3. Release Pull Request

Once this job runs for the first time, you can check the logs to see what it did. If you have releasable commits since the last tag, releaser-pleaser opens a release pull request for the proposed release.

Once you merge this pull request, releaser-pleaser automatically creates a Git tag and GitHub Release with the proposed version and changelog.

Getting started on GitLab

In this tutorial you will learn how to set up releaser-pleaser in your GitLab project with GitLab CI.

In releaser-pleaser documentation we mostly use "Pull Request" (GitHub wording) instead of "Merge Request" (GitLab wording). The GitLab-specific pages are an exception and use "Merge Request".

1. Project Settings

1.1. Merge Requests

releaser-pleaser requires Fast-forward merges and squashing. With other merge options it can not reliably find the right merge request for every commit on main.

Open your project settings to page Merge Requests:

https://gitlab.com/YOUR-PATH/YOUR-PROJECT/-/settings/merge_requests

In the "Merge method" section select "Fast-forward merge":

Screenshot of the required merge method settings

In the "Squash commits when merging" section select "Require":

Screenshot of the required squash settings

2. API Access Token

releaser-pleaser uses the GitLab API to create the release merge request and subsequent releases for you. The default GITLAB_TOKEN available in CI jobs does not have enough permissions for this, so we need to create an Access Token and make it available in a CI variable.

2.1. Create Project Access Token

Open your project settings to page Access tokens:

https://gitlab.com/YOUR-PATH/YOUR-PROJECT/-/settings/access_tokens

Create a token with these settings:

  • Name: releaser-pleaser
  • Role: Maintainer
  • Scopes: api, read_repository, write_repository

Copy the created token for the next step.

Screenshot of the access token settings

2.2. Save token in CI variable

Open your project settings to page CI/CD:

https://gitlab.com/YOUR-PATH/YOUR-PROJECT/-/settings/ci_cd

In the section "Variables" click on the "Add variable" button to open the form for a new variable. Use these settings to create the new variable:

  • Type: Variable
  • Visibility: Masked
  • Flags: Uncheck "Protect variable" if your main branch is not protected
  • Key: RELEASER_PLEASER_TOKEN
  • Value: The project access token from the previous step

3. GitLab CI/CD

releaser-pleaser is published as a GitLab CI/CD Component: https://gitlab.com/explore/catalog/apricote/releaser-pleaser

Create or open your .gitlab-ci.yml and add the following include to your configuration:

stages: [build]

include:
  - component: $CI_SERVER_FQDN/apricote/releaser-pleaser/run@v0.4.0-beta.1
    inputs:
      token: $RELEASER_PLEASER_TOKEN

You can set the stage input if you want to run releaser-pleaser during a different stage.

If you want to use releaser-pleaser on a self-managed GitLab instance, you need to mirror the GitLab.com component to your instance. See the official GitLab documentation for details.

4. Release Merge Request

Once the releaser-pleaser job runs for the first time, you can check the logs to see what it did. If you have releasable commits since the last tag, releaser-pleaser opens a release merge request for the proposed release.

Once you merge this merge request, releaser-pleaser automatically creates a Git tag and GitLab Release with the proposed version and changelog.

Release Pull Request

A release pull request is opened by releaser-pleaser when it detects that there are releasable changes. The pull request contains an auto-generated Changelog and a suggested next version. Once someone merges this pull request, releaser-pleaser will create a matching Git Tag and Release on GitHub/GitLab.

Maintainers can fill various fields in the pull request description and through labels to change the proposed release. Some examples of this are: Changelog Prefix & Suffix text and requesting a pre-release (alpha, beta, rc) version.

The pull request is automatically updated by releaser-pleaser every time it runs.

Example Screenshot

Screenshot of an example Release Pull Request on GitHub

Customizing Release Notes

You can customize the generated Release Notes in two ways:

For a single commit / pull request

Editing the Release Notes

After merging a non-release pull request, you can still modify how it appears in the Release Notes.

To do this, add a code block named rp-commits in the pull request description. When this block is present, releaser-pleaser will use its content for generating Release Notes instead of the commit message. If the code block contains multiple lines, each line will be treated as if it came from separate pull requests. This is useful for pull requests that introduce multiple features or fix several bugs.

You can update the description at any time after merging the pull request but before merging the release pull request. releaser-pleaser will then re-run and update the suggested Release Notes accordingly.

```rp-commits
feat(api): add movie endpoints
feat(api): add cinema endpoints
fix(db): invalid schema for actor model
```

Using GitHub as an example, the pull request you are trying to change the Release Notes for should look like this:

Screenshot of a pull request page on GitHub. Currently editing the description of the pull request and adding the rp-commits snippet from above.

In turn, releaser-pleaser updates the release pull request like this:

Screenshot of a release pull request on GitHub. It shows the release notes with the three commits from the rp-commits example.

Removing the pull request from the Release Notes

If you add an empty code block, the pull request will be removed from the Release Notes.

```rp-commits
```

For the release

It is possible to add custom prefix and suffix Markdown-formatted text to the Release Notes.

The release pull request description has text fields where maintainers can add the prefix and suffix. To see these fields, toggle the collapsible section in the description:

Screenshot of the collapsed section

When you edit the description, make sure to put your desired content into the code blocks named rp-prefix and rp-suffix. Only the content of these blocks is considered.

```rp-prefix
### Prefix

This will be shown as the Prefix.
```

```rp-suffix
### Suffix

This will be shown as the Suffix.
```

To match the style of the auto-generated release notes, you should start any headings at level 3 (### Title).

Once the description was updated releaser-pleaser automatically runs again and adds the prefix and suffix to the Release Notes and to the committed Changelog:

## v1.1.0

### Prefix

This will be shown as the Prefix.

### Features

- Added cool new thing (#1)

### Suffix

This will be shown as the Suffix.

Pre-releases

Pre-releases are a concept of SemVer. They follow the normal versioning schema but use a suffix out of -alpha.X, -beta.X and -rc.X.

Pre-releases are not considered "stable" and are usually not recommended for most users.

Creating a pre-release

If you want to create a pre-release, you can set one of the following labels on the release pull request:

  • rp-next-version::alpha
  • rp-next-version::beta
  • rp-next-version::rc

This will cause releaser-pleaser to run, and it will change the release pull request to a matching version according to the type of pre-release.

Versioning

For pre-releases, releaser-pleaser analyzes the commits made since the last stable release. The version bump from this is then applied to the last stable release and the pre-release info is added to the version number. If a previous pre-release of the matching type exists, the "pre-release counter" at the end of the version is increased by one.

An examples:

  • The last stable version was v1.0.0
  • Since then a feat commit was merged, this causes a bump of the minor version: v1.1.0
  • The release pull request has the label rp-next-version::beta. This changes the suggested version to v1.1.0-beta.0

If there was already a v1.1.0-beta.0, then the suggested version would be v1.1.0-beta.1.

Changing the pre-release type (for example from beta to rc), resets the counter. v1.1.0-beta.1 would be followed by v1.1.0-rc.0.

Stable Release

releaser-pleaser ignores pre-releases when looking for releasable commits. This means that right after creating a new pre-release, releaser-pleaser again detects releasable commits and opens a new release pull request for the stable version.

Workflow Permissions on GitHub

Default GitHub token permissions

The GitHub tutorial uses the builtin GITHUB_TOKEN for the action to get access to the repository. It uses the following permissions on the token:

jobs:
  releaser-pleaser:
    permissions:
      # - list commits
      # - push commits for the release pull request
      # - push new releases & tags
      contents: write

      # - read pull requests for Changelog
      # - read and write release pull request
      # - create labels on the repository
      pull-requests: write

These permissions are sufficient for simple operations. But fail if you want to run another workflow on push: tag.

Workflows on Tag Push

When using the automatic GITHUB_TOKEN to create tags, GitHub does not create new workflow runs that are supposed to be created. This is done to prevent the user from "accidentally creating recursive workflow runs". You can read more about this behaviour in the GitHub Actions docs.

Workflows that have a trigger on pushed tags are often used to build artifacts for the release, like binaries or container images.

on:
  push:
    tags:
      - "v*.*.*"

To circumvent this restriction, you can create a personal access token and instruct releaser-pleaser to use that instead to talk to GitHub.

1. Create Personal Access Token

On your account settings, navigate to the Personal access tokens section.

You can either use a "Fine-grained" or "Classic" token for this. Fine-grained tokens can be restricted to specific actions and repositories and are more secure because of this. On the other hand they have a mandatory expiration of 1 year maximum. Classic tokens have unrestricted access to your account, but do not expire.

Copy the token for the next step.

Fine-grained token

When you create a fine-grained token, restrict the access to the repository where you are using releaser-pleaser.

In the repository permissions you need to give read and write access for Contents and Pull requests. All other permissions can be set to No access (default).

No account permissions are required and you can set all to No access (default).

2. Repository Secret

Next you need to add the personal access token as a repository secret.

Open the repository settings to Secrets and variables > Actions:

https://github.com/YOUR-NAME/YOUR-REPO/settings/secrets/actions

Click on New repository secret and add the personal access token to a secret named RELEASER_PLEASER_TOKEN.

3. Update Workflow

Update the workflow file (.github/workflows/releaser-pleaser.yaml) to pass the new secret to the releaser-pleaser action. You can also remove the permissions of the job, as they are now unused.

 jobs:
   releaser-pleaser:
     runs-on: ubuntu-latest # The action uses docker containers
-    permissions:
-      contents: write
-      pull-requests: write
     steps:
       - name: releaser-pleaser
         uses: apricote/releaser-pleaser@v0.2.0
+        with:
+          token: ${{ secrets.RELEASER_PLEASER_TOKEN }}

The next release created by releaser-pleaser will now create the follow-up workflows as expected.

Updating arbitrary files

In some situations it makes sense to have the current version committed in files in the repository:

  • Documentation examples
  • A source-code file that has the version for user agents and introspection
  • Reference to a container image tag that is built from the repository

releaser-pleaser can automatically update these references in the Release PR.

Markers

The line that needs to be updated must have the marker x-releaser-pleaser-version somewhere after the version that should be updated.

For example:

// version/version.go

package version

const Version = "v1.0.0" // x-releaser-pleaser-version

Extra Files

You need to tell releaser-pleaser which files it should update. This happens through the CI-specific configuration.

GitHub Action

In the GitHub Action you can set the extra-files input with a list of the files. They need to be formatted as a single multi-line string with one file path per line:

jobs:
  releaser-pleaser:
    steps:
      - uses: apricote/releaser-pleaser@v0.4.0
        with:
          extra-files: |
            version.txt
            version/version.go
            docker-compose.yml

GitLab CI/CD Component

In the GitLab CI/CD Component you can set the extra-files input with a list of files. They need to be formatted as a single multi-line string with one file path per line:

include:
  - component: $CI_SERVER_FQDN/apricote/releaser-pleaser/run@v0.4.0
    inputs:
      extra-files: |
        version.txt
        version/version.go
        docker-compose.yml

Glossary

Changelog

The Changelog is a file in the repository (CHANGELOG.md) that contains the Release Notes for every release of that repository. Usually, new releases are added at the top of the file.

Conventional Commits

Conventional Commits is a specification for commit messages. It is the only supported commit message schema in releaser-pleaser. Follow the link to learn more.

Forge

A forge is a web-based collaborative software platform for both developing and sharing computer applications.1

Right now only GitHub is supported. We plan to support GitLab in the future (#4). For other forges like Forgejo or Gitea, please open an issue and submit a pull request.

Markdown

Markdown is a lightweight markup language used on many forges as the preferred way to format text.

In releaser-pleaser Markdown is used for most texts.

Pre-release

Pre-releases are a concept of SemVer. They follow the normal versioning schema but use a suffix out of -alpha.X, -beta.X and -rc.X.

Pre-releases are not considered "stable" and are usually not recommended for most users.

Learn more in the Pre-releases guide.

Release Pull Request

A Release Pull Request is opened by releaser-pleaser whenever it finds releasable commits in your project. It proposes a new version number and the Changelog. Once it is merged, releaser-pleaser creates a matching release.

Learn more in the Release Pull Request explanation.

Release Notes

Release Notes describe the changes made to the repository since the last release. They are made available in the Changelog, in Git Tags and through the forge-native Releases.

Learn more in the Release Notes customization guide.

Semantic Versioning (SemVer)

Semantic Versioning is a specification for version numbers. It is the only supported versioning schema in releaser-pleaser. Follow the link to learn more.

Pull Request Options

The proposed releases can by influenced by changing the description and labels of either the release pull request or the normal pull requests created by other developers. This document lists the available options for both types of pull requests.

Release Pull Request

Created by releaser-pleaser.

Release Type

Labels:

  • rp-next-version::alpha
  • rp-next-version::beta
  • rp-next-version::rc
  • rp-next-version::normal

Adding one of these labels will change the type of the next release to the one indicated in the label. This is used to create pre-releases.

Adding more than one of these labels is not allowed and the behaviour if multiple labels are added is undefined.

Release Notes

Code Blocks:

  • rp-prefix
  • rp-suffix

Any text in code blocks with these languages is being added to the start or end of the Release Notes and Changelog. Learn more in the Release Notes guide.

Examples:

```rp-prefix
#### Awesome new feature!

This text is at the start of the release notes.
```

```rp-suffix
#### Version Compatibility

And this at the end.
```

Status

Labels:

  • rp-release::pending
  • rp-release::tagged

These labels are automatically added by releaser-pleaser to release pull requests. They are used to track if the corresponding release was already created.

Users should not set these labels themselves.

Other Pull Requests

Not created by releaser-pleaser.

Release Notes

Code Blocks:

  • rp-commits

If specified, releaser-pleaser will consider each line in the code block as a commit message and add all of them to the Release Notes. Learn more in the Release Notes guide.

The types of commits (feat, fix, ...) are also considered for the next version.

Examples:

```rp-commits
feat(api): add movie endpoints
fix(db): invalid schema for actor model
```

GitHub Action

Reference

The action is available as apricote/releaser-pleaser on GitHub.com.

Versions

The apricote/releaser-pleaser action is released together with releaser-pleaser and they share the version number.

The action does not support floating tags (e.g. v1) right now (#31). You have to use the full version or commit SHA instead: apricote/releaser-pleaser@v0.2.0.

Inputs

The following inputs are supported by the apricote/releaser-pleaser GitHub Action.

InputDescriptionDefaultExample
branchThis branch is used as the target for releases.mainmaster
tokenGitHub token for creating and updating release PRs$GITHUB_TOKEN${{secrets.RELEASER_PLEASER_TOKEN}}
extra-filesList of files that are scanned for version references.""
version/version.go
deploy/deployment.yaml

Outputs

The action does not define any outputs.

GitLab CI/CD Component

Reference

The CI/CD component is available as $CI_SERVER_FQDN/apricote/releaser-pleaser/run on gitlab.com.

It is being distributed through the CI/CD Catalog: apricote/releaser-pleaser.

Versions

The apricote/releaser-pleaser action is released together with releaser-pleaser and they share the version number.

The component does not support floating tags (e.g. v1) right now (#31). You have to use the full version or commit SHA instead: apricote/releaser-pleaser@v0.4.0.

Inputs

The following inputs are supported by the component.

InputDescriptionDefaultExample
branchThis branch is used as the target for releases.mainmaster
token (required)GitLab access token for creating and updating release PRs$RELEASER_PLEASER_TOKEN
extra-filesList of files that are scanned for version references.""
version/version.go
deploy/deployment.yaml
stageStage the job runs in. Must exists.buildtest
needsOther jobs the releaser-pleaser job depends on.[]
- validate-foo
- prepare-bar

Changelog

v0.5.0

Features

  • gitlab: make job dependencies configurable and run immediately (#101)
  • github: mark pre-releases correctly (#110)

Bug Fixes

  • use commits with slightly invalid messages in release notes (#105)
  • create CHANGELOG.md if it does not exist (#108)

v0.4.2

Bug Fixes

  • action: container image reference used wrong syntax (#96)

v0.4.1

Bug Fixes

  • gitlab: release not created when release pr was squashed (#86)

v0.4.0

✨ Highlights

GitLab Support

You can now use releaser-pleaser with projects hosted on GitLab.com and self-managed GitLab installations. Check out the new tutorial to get started.

Features

  • add support for GitLab repositories (#49)
  • add shell to container image (#59)
  • gitlab: add CI/CD component (#55)
  • changelog: omit version heading in forge release notes
  • gitlab: support self-managed instances (#75)

Bug Fixes

  • parser: continue on unparsable commit message (#48)
  • cli: command name in help output (#52)
  • parser: invalid handling of empty lines (#53)
  • multiple extra-files are not evaluated properly (#61)

v0.4.0-beta.1

Features

  • add shell to container image (#59)
  • gitlab: add CI/CD component (#55)

Bug Fixes

  • multiple extra-files are not evaluated properly (#61)

v0.4.0-beta.0

Features

  • add support for GitLab repositories (#49)

Bug Fixes

  • parser: continue on unparsable commit message (#48)
  • cli: command name in help output (#52)
  • parser: invalid handling of empty lines (#53)

v0.3.0

:sparkles: Highlights

Cleaner pre-release Release Notes

From now on if you create multiple pre-releases in a row, the release notes will only include changes since the last pre-release. Once you decide to create a stable release, the release notes will be in comparison to the last stable release.

Edit pull request after merging.

You can now edit the message for a pull request after merging by adding a ```rp-commits code block into the pull request body. Learn more in the Release Notes Guide.

Features

  • less repetitive entries for prerelease changelogs #37
  • format markdown in changelog entry (#41)
  • edit commit message after merging through PR (#43)
  • cli: show release PR url in log messages (#44)

v0.2.0

Features

  • update version references in any files (#14)
  • cli: add --version flag (#29)

Bug Fixes

  • ci: building release image fails (#21)
  • ci: ko pipeline permissions (#23)
  • action: invalid quoting for extra-files arg (#25)

v0.2.0-beta.2

Features

  • update version references in any files (#14)

Bug Fixes

  • ci: building release image fails (#21)
  • ci: ko pipeline permissions (#23)

v0.2.0-beta.1

Features

  • update version references in any files (#14)

Bug Fixes

  • ci: building release image fails (#21)

v0.2.0-beta.0

Features

  • update version references in any files (#14)

v0.1.0

This is the first release ever, so it also includes a lot of other functionality.

Features

  • add github action (#1)