A reusable GitHub Action for bumping semantic versions in project files. Supports XML files (.csproj, Directory.Build.props, etc.), JSON files (package.json, etc.), CMake files (CMakeLists.txt), and plain text files (VERSION, .version, etc.).
See CHANGELOG.md for migration notes and release history.
- Reads the current version from the specified file
- Bumps the version according to the selected bump type
- Writes the updated version back to the file
- Applies the calculated version to any additional files
- Optionally commits, tags, and pushes the change
The action auto-detects file type based on extension:
- XML files (
.xml,.csproj,.props,.targets,.vbproj,.fsproj): Reads/writes using XPath - JSON files (
.json): Reads/writes a JSON key (default:version) - CMakeLists.txt: Reads/writes the single
project(... VERSION ...)value - Everything else (
.version,.txt, no extension): Reads/writes as plain text
| Input | Description |
|---|---|
version_file |
Path to the file containing the version, relative to the repository root (e.g. src/Directory.Build.props, VERSION) |
bump |
Version bump type. One of: major, minor, patch, preview, or custom |
| Input | Description | Default |
|---|---|---|
custom_version |
Exact version string to set. Only used when bump is custom. Must match format X.Y.Z or X.Y.Z-preview.N |
'' |
version_element |
XPath expression for XML files, or dot-separated JSON key path (for example metadata.version). Ignored for plain text files |
.//Version for XML, version for JSON |
additional_version_files |
Newline-separated repository-relative files to update to the calculated version. Uses each handler's default location; version_element applies only to version_file. |
'' |
commit |
Whether to commit the version change to the current branch | false |
tag |
Whether to create a git tag in the format {tag_prefix}{version} |
false |
tag_prefix |
Prefix for the git tag. The tag will be {tag_prefix}{version} |
v |
commit_message |
Template for the commit message. Supports {version} and {tag} placeholders |
VersionBump : {tag} |
push |
Whether to push the commit and tag to the remote origin | false |
floating_major_version |
Create/update a floating major version tag (e.g. v1 for v1.2.0). Requires tag to be true. |
false |
floating_minor_version |
Create/update a floating minor version tag (e.g. v1.2 for v1.2.0). Requires tag to be true. |
false |
preview_label |
Label for preview versions. E.g. BETA for 1.0.1-BETA-1 |
preview |
preview_separator |
Separator between label and number. E.g. - for 1.0.1-BETA-1 |
. |
| Output | Description | Example |
|---|---|---|
version |
The new version string after bumping | 1.2.0 |
old_version |
The previous version string before bumping | 1.1.3 |
tag |
The full git tag name (prefix + version) | v1.2.0 |
floating_major_tag |
The floating major version tag name, if enabled | v1 |
floating_minor_tag |
The floating minor version tag name, if enabled | v1.2 |
The action supports semantic versioning with an optional preview suffix:
- Stable:
X.Y.Z(e.g.1.2.3) - Preview:
X.Y.Z-{label}{separator}N(e.g.1.2.3-preview.1,1.0.1-BETA-1)
The preview label defaults to preview and separator to ., both customizable via preview_label and preview_separator inputs.
| Bump Type | From | To | Description |
|---|---|---|---|
major |
1.2.3 |
2.0.0 |
Increments major, resets minor and patch to 0 |
minor |
1.2.3 |
1.3.0 |
Increments minor, resets patch to 0 |
patch |
1.2.3 |
1.2.4 |
Increments patch by 1 |
preview |
1.2.3 |
1.2.3-preview.1 |
Adds preview suffix (or increments if already preview) |
custom |
1.2.3 |
(user-specified) | Sets to the exact version provided in custom_version |
When bumping a version that already has a preview suffix:
| Bump Type | From | To | Description |
|---|---|---|---|
major |
1.2.3-preview.5 |
2.0.0 |
Bumps major and produces a stable version |
minor |
1.2.3-preview.5 |
1.3.0 |
Bumps minor and produces a stable version |
patch |
1.2.3-preview.5 |
1.2.4 |
Bumps patch and produces a stable version |
preview |
1.2.3-preview.5 |
1.2.3-preview.6 |
Increments preview number by 1 |
- uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: VERSION
bump: minorGiven a VERSION file containing 1.0.0, this produces 1.1.0.
- uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: src/Directory.Build.props
bump: minor- uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: package.json
bump: minorThe version_element input specifies the JSON key path to update. It defaults to version for JSON files, so it can be omitted for package.json. For nested values, use a dot-separated path such as metadata.version.
- uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: src/InfiniFrame.NativeBridge/Native/CMakeLists.txt
bump: patchThe CMake handler updates the single project(... VERSION X.Y.Z ...) declaration and preserves all other file content, including whitespace and line endings. It fails if the declaration is missing or more than one matching declaration exists.
The required version_file is the canonical source: its version is read and bumped exactly once. Additional files receive that exact resulting version and are not bumped independently. Paths are relative to GITHUB_WORKSPACE (the repository root), and blank lines are ignored.
- uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: src/Directory.Build.props
bump: minor
additional_version_files: |
src/InfiniFrame.NativeBridge/Native/CMakeLists.txt
src/frontend/package.json
apps/web/package.json
packages/shared/package.jsonAdditional XML files use .//Version, JSON files use version, CMakeLists.txt files use project(... VERSION ...), and plain-text files use their complete contents. Per-file element overrides are intentionally not supported; use the file type defaults or make that file the canonical version_file when a custom element is required. All files are staged in one commit when commit is enabled. If any additional file cannot be read or updated, the action stops before commit, tagging, or pushing.
- uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: VERSION
bump: minor
commit: 'true'
tag: 'true'
push: 'true'- uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: VERSION
bump: custom
custom_version: 2.0.0-preview.1
commit: 'true'
tag: 'true'If your version is stored in a non-standard element:
- uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: src/MyProject.csproj
bump: patch
version_element: './/PackageVersion'- uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: VERSION
bump: patch
tag: 'true'
tag_prefix: 'release-'This creates tags like release-1.2.3 instead of v1.2.3.
Use a custom label and separator for preview versions (e.g. for Obsidian beta releases):
- uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: VERSION
bump: preview
preview_label: 'BETA'
preview_separator: '-'This produces versions like 1.0.0-BETA-1 instead of 1.0.0-preview.1.
- uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: VERSION
bump: patch
commit: 'true'
commit_message: 'chore: bump version to {version}'Automatically maintain a floating major version tag (e.g. v1) that always points to the latest v1.x.x release:
- uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: VERSION
bump: minor
commit: 'true'
tag: 'true'
push: 'true'
floating_major_version: 'true'
floating_minor_version: 'true'When releasing v1.2.0, this also updates v1 to point to the same commit. Users can then reference @v1 in their workflows to always get the latest v1.x.x release.
Use floating_minor_version to maintain a floating minor tag (e.g. v1.2) that points to the latest v1.2.x release:
- uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: VERSION
bump: patch
commit: 'true'
tag: 'true'
push: 'true'
floating_minor_version: 'true'When releasing v1.2.1, this also updates v1.2 to point to the same commit. Both floating options can be enabled together to update both tags.
- name: Bump version
id: version
uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: VERSION
bump: minor
commit: 'true'
tag: 'true'
push: 'true'
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.version.outputs.tag }}
name: Release ${{ steps.version.outputs.version }}name: Release
on:
workflow_dispatch:
inputs:
bump:
description: 'Version bump type'
required: true
type: choice
options:
- major
- minor
- patch
- preview
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.RELEASE_TOKEN }}
- name: Bump version
id: version
uses: Code-Of-Chaos/action-version-bumper@v2
with:
version_file: VERSION
bump: ${{ inputs.bump }}
commit: 'true'
tag: 'true'
push: 'true'
floating_major_version: 'true'
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.version.outputs.tag }}
name: Release ${{ steps.version.outputs.version }}
generate_release_notes: trueThe Python script can be used directly without the GitHub Action:
# Bump patch in a VERSION file
python src/bump_version.py patch VERSION
# Bump minor in an XML file
python src/bump_version.py minor src/Directory.Build.props
# Bump patch in a package.json
python src/bump_version.py patch package.json version
# Apply an already-calculated version to an additional file
python src/bump_version.py --set-version CMakeLists.txt 1.2.4
# Set a custom version with custom xpath
python src/bump_version.py custom src/Directory.Build.props .//Version 2.0.0-preview.1
# Bump using a custom xpath element
python src/bump_version.py patch src/MyProject.csproj .//PackageVersion
# Bump preview with custom label
python src/bump_version.py preview VERSION .//Version "" BETA -
# Bump preview with custom label and dot separator
python src/bump_version.py preview VERSION .//Version "" RC .bump_version.py <bump> <version_file> [version_element] [custom_version] [preview_label] [preview_separator]
| Argument | Description |
|---|---|
bump |
Bump type: major, minor, patch, preview, or custom |
version_file |
Path to the file containing the version |
version_element |
XPath to the version element (XML) or dot-separated JSON key path (JSON). Defaults to .//Version/version by file type |
custom_version |
Version string when bump type is custom |
preview_label |
Label for preview versions. Default: preview |
preview_separator |
Separator between label and number. Default: . |
The action uses file extension to determine how to read/write the version:
| Extension | Mode | Example Files |
|---|---|---|
.xml, .csproj, .props, .targets, .vbproj, .fsproj |
XML (XPath) | Directory.Build.props, MyProject.csproj |
.json |
JSON (key) | package.json, app-version.json |
filename CMakeLists.txt |
CMake | CMakeLists.txt |
| Anything else | Plain text | VERSION, .version, version.txt |
For plain text files, the file must contain only the version string (with optional trailing newline).
For JSON files, the version_element input specifies which key path to read/write. For package.json, it defaults to version; nested paths such as metadata.version are also supported.
For CMake files, the handler finds the single project(... VERSION ...) declaration. The --set-version CLI mode is used internally for additional files and does not calculate another bump.
pip install pytest
pytest tests/ -vGPL v3