A GitHub Action to bump versions based on pull request (PR) labels.
This action follows the principles of semantic versioning, incrementing the version number based on the labels applied to the PR.
- Automatically determines the version bump type based on PR labels.
- Supports manual workflow dispatch with an explicitly selected bump type.
- Uses bump-my-version to increment the version according to semantic versioning.
- Creates a new branch and a PR for the version bump.
- Optionally enables auto-merge on that PR.
- Generates a corresponding Git tag once the version bump PR is merged.
- Optionally creates a GitHub release for the new tag.
The action requires gh, which the GitHub-hosted runner images provide.
Below are example workflows you can add to your repository to automatically bump the version when a PR is merged.
You can save them in a file such as .github/workflows/bump-version.yaml.
Make sure your workflow includes the following:
- The
pull_requesttrigger with theclosedtype to run the workflow whenever a PR is closed. - The job-level
ifcondition to skip PRs that are closed without being merged.
name: Bump version
on:
pull_request:
types:
- closed
jobs:
bump-version:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Bump version
uses: conjikidow/bump-version-action@v4.2.0
with:
label-major: major update
label-minor: minor update
label-patch: patch update
labels-to-add: automated,version-bump
create-release: trueThe examples reference actions by tag for readability.
For production workflows, consider pinning each action to a full-length commit SHA,
as GitHub recommends.
Releases of this action are immutable, so its full version tags (vX.Y.Z) are already locked to a single commit.
Important
Workflows do not run automatically on a PR created with the default ${{ github.token }}.
They wait for approval from a user with write access to the repository.
See Example with a GitHub App Token to avoid that approval.
The following example generates a GitHub App installation token and passes it to github-token,
so that the workflows triggered by the version bump PR run without approval.
name: Bump version
on:
pull_request:
types:
- closed
jobs:
bump-version:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
permissions: {}
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v3
with:
client-id: ${{ vars.GH_APP_CLIENT_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
permission-contents: write
permission-pull-requests: write
- name: Bump version
uses: conjikidow/bump-version-action@v4.2.0
with:
label-major: major update
label-minor: minor update
label-patch: patch update
labels-to-add: automated,version-bump
create-release: true
github-token: ${{ steps.app-token.outputs.token }}You can also use this action with manual workflow dispatch. The following example adds a manual trigger that lets you choose the bump type when starting the workflow.
name: Bump version
on:
pull_request:
types:
- closed
workflow_dispatch:
inputs:
bump-type:
description: 'Version bump type'
required: true
type: choice
options:
- major
- minor
- patch
jobs:
bump-version:
if: >-
github.event_name == 'workflow_dispatch'
|| github.event.pull_request.merged == true
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Bump version
uses: conjikidow/bump-version-action@v4.2.0
with:
label-major: major update
label-minor: minor update
label-patch: patch update
manual-bump-type: ${{ inputs.bump-type }}
labels-to-add: automated,version-bump
create-release: trueYou can also integrate this action with external tools or actions by using the outputs provided.
The following example uses softprops/action-gh-release
to create a GitHub release when the version has actually been bumped:
name: Bump version with external release
on:
pull_request:
types:
- closed
jobs:
bump-version:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Bump version
id: bump-version
uses: conjikidow/bump-version-action@v4.2.0
# This step is just a placeholder. You can replace it with your own script or external tools.
- name: Create release notes
if: steps.bump-version.outputs.version-bumped == 'true'
run: |
cat <<EOF > custom-release-notes.md
## What's Changed
...
EOF
- name: Create GitHub release
if: steps.bump-version.outputs.version-bumped == 'true'
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.bump-version.outputs.new-version }}
body_path: custom-release-notes.mdThe token passed to github-token needs contents: write to push the version bump branch and the tag,
and pull-requests: write to open the version bump PR and, with auto-merge, to merge it.
The default ${{ github.token }} carries whatever the workflow grants it,
so grant those scopes in the job, as the examples that keep it do.
GITHUB_TOKEN also needs the repository itself to allow it to open PRs:
- Go to the Settings tab of your repository.
- On the left-hand menu, select Actions/General.
- Under the Workflow permissions section, enable
Allow GitHub Actions to create and approve pull requests. - Save the changes.
Neither the permissions: block nor that setting reaches a token you pass yourself.
A GitHub App installation token, as in the second example above, needs the same access granted to the app itself.
None of the steps that act on your repository use the job's own GITHUB_TOKEN,
which is why that example zeroes it with permissions: {}.
| Name | Description | Required | Default |
|---|---|---|---|
version-of-bump-my-version |
Version of bump-my-version to use. |
No | 'latest' |
label-major |
Label that triggers a major version bump. | No | major |
label-minor |
Label that triggers a minor version bump. | No | minor |
label-patch |
Label that triggers a patch version bump. | No | patch |
manual-bump-type |
Bump type used for manual workflow dispatch runs: major, minor, or patch. |
No | '' |
branch-prefix |
Prefix of the version bump branch name. | No | workflow |
labels-to-add |
Labels to add to the version bump PR, separated by commas. | No | '' |
auto-merge |
Merge method used to enable auto-merge on the version bump PR: merge, squash, or rebase. Empty disables auto-merge. |
No | '' |
update-major-minor-tags |
Whether to create or update the major (vX) and minor (vX.Y) tags. |
No | false |
create-release |
Whether to create a GitHub release for the new tag. | No | false |
github-token |
Token used to authenticate with GitHub. Needs contents: write and pull-requests: write. |
No | ${{ github.token }} |
- Set any of
label-major,label-minor, orlabel-patchto an empty string ('') to disable that bump type. manual-bump-typeis required forworkflow_dispatchruns; the action fails when it is empty.- Any labels specified in
labels-to-addmust already exist in your repository; the action fails if they do not. auto-mergeneeds Allow auto-merge enabled in the repository settings, and the merge method it names must be allowed there as well. Leave it empty to merge the version bump PR yourself.- Auto-merge waits only for the merge requirements the base branch defines, so set it up on a base branch that requires status checks or reviews. With nothing left to wait for, the action merges the PR right away instead of arming it.
- Enable auto-merge with a GitHub App installation token,
as in Example with a GitHub App Token.
With the default
${{ github.token }}, the workflows on the version bump PR wait for approval, so its required checks do not pass unattended, and a merge performed byGITHUB_TOKENdoes not trigger the run that creates the tag.
| Name | Description |
|---|---|
version-bumped |
true when the version was bumped and a new tag was created; otherwise false. |
new-version |
New version number (e.g. 1.2.4). Empty when version-bumped is false. |
pull-request-number |
Number of the version bump PR. Empty when no PR was created. |
pull-request-url |
URL of the version bump PR. Empty when no PR was created. |
The pull-request-* outputs are set in the run that opens the version bump PR,
while version-bumped becomes true only in the later run triggered by merging it.
To use this action, ensure that your project is configured to work with bump-my-version.
Below is an example .bumpversion.toml configuration file:
[tool.bumpversion]
current_version = "0.1.0"
commit = false
tag = false
[[tool.bumpversion.files]]
filename = "pyproject.toml"
search = 'version = "{current_version}"'
replace = 'version = "{new_version}"'
[[tool.bumpversion.files]]
filename = "CMakeLists.txt"
search = "VERSION {current_version}"
replace = "VERSION {new_version}"Important
commit and tag should be set to false because this action handles these tasks automatically.
To generate a default configuration file, run the following command:
uvx bump-my-version sample-config --no-prompt --destination .bumpversion.tomlFor more details, refer to the official bump-my-version documentation.
-
Determines whether to run
- Runs for merged PRs and manual workflow dispatches.
- For other cases, the action skips execution.
-
Determines the bump type
- For manual workflow dispatches, uses
manual-bump-type. - Otherwise, extracts PR labels and determines whether a major, minor, or patch bump is required, in accordance with semantic versioning.
- If no matching labels are found, the process stops.
- For manual workflow dispatches, uses
-
Runs
bump-my-versionto bump the version- Uses
bump-my-version@latest(or specified version). - Checks if the version was actually updated.
- Uses
-
Creates a new branch and PR for the version bump
- If the version is updated, a new branch (
${branch-prefix}/bump-version-from-X.Y.W-to-X.Y.Z) is created. - A PR is automatically opened to merge the version bump.
- If
auto-mergenames a merge method, auto-merge is enabled on that PR, or the PR is merged right away when nothing blocks it.
- If the version is updated, a new branch (
-
After merging, creates a Git tag
- The branch name is parsed to extract the new version number.
- A Git tag (
vX.Y.Z) is pushed to mark the new release.
-
Optionally creates a GitHub release
- If
create-releaseistrue, a GitHub release is created for the new tag with automatically generated release notes.
- If
By default, this action only creates the full version tag (vX.Y.Z), which is never overwritten on subsequent releases.
This default is compatible with GitHub's immutable releases
setting and aligns with the recommendation to pin actions to specific versions
(ideally to a commit SHA) for supply chain security.
True immutability of tags and releases requires enabling Enable release immutability in your repository's Settings → General → Releases. This action's default behavior is designed to be compatible with that setting.
If update-major-minor-tags is set to true, the action also creates or updates
the major (vX) and minor (vX.Y) tags based on the following rules:
- If
vX.Yexists → update tovX.Y.Z. - If
vX.Ydoes not exist but a previous minor tag (vX.Ybefore the update) exists → createvX.Yand set it tovX.Y.Z. - If
vXexists → update tovX.Y.Z. - If
vXdoes not exist but a previous major tag (vXbefore the update) exists → createvXand set it tovX.Y.Z. - If neither
vXnorvX.Yexist, they are not created.
Examples:
v1.2.3 → v1.2.4: Updatev1.2andv1if they exist.v1.2.3 → v1.3.0: Createv1.3ifv1.2exists, updatev1if it exists.v1.2.3 → v2.0.0: Createv2.0ifv1.2exists, createv2ifv1exists.
Caution
Updating major and minor tags requires force-pushing them, which is incompatible with the Enable release immutability repository setting. Enabling this option is discouraged for projects that prioritize supply chain security.
Licensed under either of MIT license or Apache License, Version 2.0 at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this software by you, as defined in the Apache-2.0 license, shall be dually licensed as above, without any additional terms or conditions.
Contributions, bug reports, and feedback are always welcome! Thank you for helping improve this project for everyone!