eliashaeussler / version-bumper
Composer plugin to bump project versions during release preparations
Installs: 23 895
Dependents: 7
Suggesters: 0
Security: 0
Stars: 2
Watchers: 1
Forks: 0
Open Issues: 2
Type:composer-plugin
Requires
- php: ~8.1.0 || ~8.2.0 || ~8.3.0
- composer-plugin-api: ^2.0
- cuyz/valinor: ^1.0
- cypresslab/gitelephant: ^4.5
- symfony/console: ^5.4 || ^6.4 || ^7.0
- symfony/filesystem: ^5.4 || ^6.4 || ^7.0
- symfony/yaml: ^5.4 || ^6.4 || ^7.0
Requires (Dev)
- armin/editorconfig-cli: ^1.8 || ^2.0
- composer/composer: ^2.2
- eliashaeussler/php-cs-fixer-config: ^2.0
- eliashaeussler/phpstan-config: ^2.0
- eliashaeussler/rector-config: ^3.0
- ergebnis/composer-normalize: ^2.30
- phpstan/extension-installer: ^1.2
- phpstan/phpstan-phpunit: ^1.1
- phpstan/phpstan-symfony: ^1.4
- phpunit/phpunit: ^10.2 || ^11.0
This package is auto-updated.
Last update: 2024-11-20 02:31:45 UTC
README
Version Bumper
A Composer plugin to bump project versions during release preparations.
Provides a Composer command bump-version
and offers an easy-to-use PHP
API for integration in other frameworks.
🔥 Installation
composer require --dev eliashaeussler/version-bumper
⚡ Usage
Console command bump-version
Tip
The <range>
command option can be omitted if
version range auto-detection
is properly configured.
$ composer bump-version [<range>] [-c|--config CONFIG] [-r|--release] [--dry-run] [--strict]
Pass the following options to the console command:
<range>
: Version range to be bumped, can be one of:major
/maj
: Bump version to next major version (1.2.3
->2.0.0
)minor
/min
: Bump version to next minor version (1.2.3
->1.3.0
)next
/n
/patch
/p
: Bump version to next patch version (1.2.3
->1.2.4
)- Explicit version, e.g.
1.3.0
-c
/--config
: Path to config file, defaults to auto-detection in current working directory, can be configured incomposer.json
as well (see config section below).-r
/--release
: Create a new Git tag after versions are bumped.--dry-run
: Do not perform any write operations, just calculate and display version bumps.--strict
: Fail if any unmatched file pattern is reported.
Version range auto-detection
Normally, an explicit version range or version is passed to
the bump-version
command. However, it may become handy if
a version range is auto-detected, based on the Git history.
This sort of auto-detection is automatically triggered if the
<range>
command option is omitted.
Important
Auto-detection is only possible if versionRangeIndicators
are configured in the config file.
To use the auto-detection feature, make sure to add version range indicators to your config file:
versionRangeIndicators: # 1️⃣ Bump major version on breaking changes, determined by commit message - range: major patterns: - type: commitMessage pattern: '/^\[!!!]/' # 2️⃣ Bump major version if controllers are deleted and API schema changes - range: major # All configured patterns must match to use this indicator strategy: matchAll patterns: - type: fileDeleted pattern: '/^src\/Controller\/.+Controller\.php$/' - type: fileModified pattern: '/^res\/api\.schema\.json$/' # 3️⃣ Bump minor version when new features are added - range: minor patterns: - type: commitMessage pattern: '/^\[FEATURE]/' # 4️⃣ Bump patch version if maintenance or documentation tasks were performed - range: patch patterns: - type: commitMessage pattern: '/^\[TASK]/' - type: commitMessage pattern: '/^\[BUGFIX]/' - type: commitMessage pattern: '/^\[DOCS]/' # 5️⃣ Bump patch version if no sources have changed - range: patch # No configured patterns must match to use this indicator strategy: matchNone patterns: - type: fileAdded pattern: '/^src\//' - type: fileDeleted pattern: '/^src\//' - type: fileModified pattern: '/^src\//'
Note
The matching version range with the highest priority will be
used as final version range (major
receives the highest priority).
If no version range indicator matches, the bump-version
command will fail.
Strategies
The strategy
config option (see second indicator in the above example)
defines how matching (or non-matching) patterns are treated to
mark the whole indicator as "matching".
By default, an indicator matches if any of the configured
patterns matches (matchAny
). If all patterns must match,
matchAll
can be used.
In some cases, it may be useful to define a version range if
no pattern matches. This can be achieved by the matchNone
strategy.
Examples
Using the above example, the following version range would result if given preconditions are met:
Notes:
1) Even if both indicators 2️⃣ and 4️⃣ match, indicator 2️⃣ takes precedence because of the higher version range.
2) Indicator 2️⃣ does not match, because only one
pattern matches, and the indicator's strategy is configured
to match all patterns (matchAll
).
3) No indicator contains patterns for either the commit message or modified file, hence no version range is detected.
PHP API
Tip
You can use the method argument $dryRun
in both
VersionBumper
and VersionReleaser
classes to skip any
write operations (dry-run mode).
Bump versions
The main entrypoint of the plugin is the
Version\VersionBumper
class:
use EliasHaeussler\VersionBumper; // Define files and patterns in which to bump new versions $filesToModify = [ new VersionBumper\Config\FileToModify( 'package.json', [ '"version": "{%version%}"', ], ), new VersionBumper\Config\FileToModify( 'src/Version.php', [ 'public const VERSION = \'{%version%}\';', ], ), ]; // Define package root path and version range $rootPath = dirname(__DIR__); $versionRange = VersionBumper\Enum\VersionRange::Minor; // Bump versions within configured files $versionBumper = new VersionBumper\Version\VersionBumper(); $results = $versionBumper->bump( $filesToModify, $rootPath, $versionRange, ); // Display results foreach ($results as $result) { // File: package.json echo sprintf('File: %s', $result->file()->path()); echo PHP_EOL; foreach ($result->groupedOperations() as $operations) { foreach ($operations as $operation) { // Modified: 1.2.3 => 1.3.0 echo sprintf( '%s: %s => %s', $operation->state()->name, $operation->source(), $operation->target(), ); echo PHP_EOL; } } }
Create release
A release can be created by the
Version\VersionReleaser
class:
use EliasHaeussler\VersionBumper; $options = new VersionBumper\Config\ReleaseOptions( tagName: 'v{%version%}', // Create tag with "v" prefix signTag: true, // Sign new tags ); $versionReleaser = new VersionBumper\Version\VersionReleaser(); $result = $versionReleaser->release($results, $rootPath, $options); echo sprintf( 'Committed "%s" and tagged "%s" with %d file(s).', $result->commitMessage(), $result->tagName(), count($result->committedFiles()), ); echo PHP_EOL;
Auto-detect version range
When bumping files, a respective version range or explicit version
must be provided (see above). The library provides a
Version\VersionRangeDetector
class to automate this step and auto-detect a version range, based
on a set of Config\VersionRangeIndicator
objects:
use EliasHaeussler\VersionBumper; $indicators = [ new VersionBumper\Config\VersionRangeIndicator( // Bump major version if any commit contains breaking changes // (commit message starts with "[!!!]") VersionBumper\Enum\VersionRange::Major, [ new VersionBumper\Config\VersionRangePattern( VersionBumper\Enum\VersionRangeIndicatorType::CommitMessage, '/^\[!!!]/', ), ], ), ]; $versionRangeDetector = new VersionBumper\Version\VersionRangeDetector(); $versionRange = $versionRangeDetector->detect($rootPath, $indicators); echo sprintf('Auto-detected version range is "%s".', $versionRange->value); echo PHP_EOL;
📝 Configuration
When using the console command, it is required to configure the write operations which are to be performed by the version bumper.
Formats
The following file formats are supported currently:
json
yaml
,yml
Schema
The config file must follow a given schema:
filesToModify: - path: relative/or/absolute/path/to/file patterns: # Each pattern must contain a {%version%} placeholder - '"version": "{%version%}"' reportUnmatched: true releaseOptions: commitMessage: '[RELEASE] Release of my-fancy-library {%version%}' overwriteExistingTag: true signTag: true tagName: 'v{%version%}' # Relative (to config file) or absolute path to project root rootPath: ../ versionRangeIndicators: - range: major strategy: matchAll patterns: - type: fileDeleted pattern: '/^src\/Controller\/.+Controller\.php$/' - type: fileModified pattern: '/^res\/api\.schema\.json$/' - type: commitMessage pattern: '/^\[!!!]/'
Tip
Have a look at the shipped JSON schema.
Files to modify
Release options
Root path
Version range indicators
Configuration in composer.json
The config file path can be passed as -c
/--config
command
option or, alternatively, as configuration in composer.json
:
{ "extra": { "version-bumper": { "config-file": "path/to/version-bumper.json" } } }
When configured as relative path, the config file path is
calculated based on the location of the composer.json
file.
Auto-detection
If no config file is explicitly configured, the config reader tries to auto-detect its location. The following order is taken into account during auto-detection:
version-bumper.json
version-bumper.yaml
version-bumper.yml
🧑💻 Contributing
Please have a look at CONTRIBUTING.md
.
⭐ License
This project is licensed under GNU General Public License 3.0 (or later).