easy_semver 1.2.0 copy "easy_semver: ^1.2.0" to clipboard
easy_semver: ^1.2.0 copied to clipboard

Bump and sync a Flutter app's semantic version across pubspec.yaml, the iOS Xcode project and Android Gradle files, and repair drift between them.

easy_semver #

Bump a Flutter app's version everywhere it is written, in one command.

A Flutter app's version lives in more than one file, and those copies drift. bumpv updates them together and tells you exactly what moved.

$ bumpv minor
1.2.1+1  ->  1.3.0+1

  pubspec.yaml               1.2.1+1 -> 1.3.0+1
  ios/…/project.pbxproj      FLUTTER_BUILD_NAME: 1.2.1 -> 1.3.0, MARKETING_VERSION: 1.2.1 -> 1.3.0  (Debug, Release, Profile)
  android                    no edit needed — versionName/versionCode come from pubspec.yaml

Done. Review with:  git diff

Why this exists #

Bumping pubspec.yaml is usually enough — Flutter feeds versionName/ versionCode on Android and $(FLUTTER_BUILD_NAME)/$(FLUTTER_BUILD_NUMBER) on iOS from it.

Usually. If ios/Runner.xcodeproj/project.pbxproj pins FLUTTER_BUILD_NAME in its build settings — and plenty of projects do, often without anyone noticing — that target-level value overrides the one Flutter generates into Generated.xcconfig. Bump only pubspec.yaml and your pubspec says 1.3.0 while the build you ship to TestFlight is stamped 1.2.1.

bumpv keeps all of it in agreement, and re-running it repairs drift that has already happened.

Install #

dart pub global activate easy_semver

If you get bumpv: command not found, add pub's bin directory to your PATH:

export PATH="$HOME/.pub-cache/bin:$PATH"    # add to ~/.zshrc or ~/.bashrc

Or skip PATH entirely: dart pub global run easy_semver:bumpv minor.

Usage #

Run it anywhere inside a Flutter project — it walks up to find pubspec.yaml.

bumpv patch                 # 1.2.1 -> 1.2.2
bumpv minor                 # 1.2.1 -> 1.3.0
bumpv major                 # 1.2.1 -> 2.0.0
bumpv 2.4.0                 # set the version exactly
bumpv 2.4.0+7               # set version and build number
Option Effect
--build N Set the build number explicitly
--bump-build Increment the build number
--commit, -c Commit the updated files (Git projects)
--tag, -t Tag the bump commit — --tag=NAME to name it yourself
--dry-run Print what would change, write nothing
--project DIR Target another directory

The build number is preserved unless you pass --build or --bump-build. App stores reject a repeated build number, so use --bump-build for a release:

bumpv minor --bump-build    # 1.2.1+1 -> 1.3.0+2

Committing the bump #

--commit (or -c) commits the files it just wrote:

$ bumpv patch --commit
1.2.1+1  ->  1.2.2+1

  pubspec.yaml               1.2.1+1 -> 1.2.2+1
  ios/…/project.pbxproj      FLUTTER_BUILD_NAME: 1.2.1 -> 1.2.2  (Debug, Release, Profile)
  android                    no edit needed — versionName/versionCode come from pubspec.yaml

Done. Committed:  chore: bump version to 1.2.2

Only the files bumpv wrote go into the commit, so whatever else you have in progress stays exactly where it was — staged or not. If the project isn't a Git repository you get a warning and the bump still stands, and --dry-run wins: nothing is written and nothing is committed.

Tagging the release #

--tag (or -t) puts an annotated tag on that commit, named after the new version:

$ bumpv minor --tag
1.2.1+1  ->  1.3.0+1

  pubspec.yaml               1.2.1+1 -> 1.3.0+1
  ios/…/project.pbxproj      FLUTTER_BUILD_NAME: 1.2.1 -> 1.3.0  (Debug, Release, Profile)
  android                    no edit needed — versionName/versionCode come from pubspec.yaml

Done. Committed:  chore: bump version to 1.3.0
Tagged:           1.3.0

To choose the name yourself, attach it — --tag=NAME or -tNAME:

bumpv minor --tag=v1.3.0     # tag it v1.3.0
bumpv minor -tv1.3.0         # same, short form

The value has to be attached because it is optional: in bumpv --tag minor there would be no way to tell a tag name from the bump type, so a detached name is rejected with a hint rather than quietly doing the wrong thing.

--tag implies --commit — a tag is only worth having on the commit that carries the bump. The exceptions behave the way you would expect: --dry-run creates no tag, a project without Git warns, and if the version is already current there is nothing to commit, so the tag simply goes on HEAD. Should the tag name already exist, Git says so and bumpv exits non-zero with the bump itself intact — re-running with the version you just set tags it without touching anything else.

Repairing drift #

Run bumpv with the version you already have. It won't change the version, but it will re-sync the native files and report anything that was out of step:

$ bumpv 1.3.0
1.3.0+1 (unchanged)

  pubspec.yaml               unchanged
  ios/…/project.pbxproj      FLUTTER_BUILD_NAME: 1.2.1 -> 1.3.0  (Debug, Release, Profile)

What it touches #

File Behaviour
pubspec.yaml version: is rewritten
ios/Runner.xcodeproj/project.pbxproj FLUTTER_BUILD_NAME, FLUTTER_BUILD_NUMBER, MARKETING_VERSION and CURRENT_PROJECT_VERSION are synced in the app target only — settings the project doesn't declare are left absent, and test targets keep their own version
android/app/build.gradle[.kts] Hardcoded versionName/versionCode are rewritten (Kotlin DSL and Groovy). When they defer to flutter.versionName/flutter.versionCode, nothing is written and that is reported

Nothing else in those files is altered.

Use it as a library #

The updaters are pure functions from file content to file content, so you can drive them from your own release script without inheriting any filesystem assumptions:

import 'package:easy_semver/easy_semver.dart';

final next = Version.tryParse('1.4.0+2')!;

final yaml = updatePubspec(pubspecText, next);

final ios = updateXcodeProject(pbxprojText, next);
print(describeChanges(ios.changes));   // FLUTTER_BUILD_NAME: 1.2.1 -> 1.4.0, …
print(ios.configurations);             // [Debug, Release, Profile]

Not handled #

macOS, Windows and Linux desktop targets keep their own version files and are out of scope for now.

License #

MIT

1
likes
150
points
144
downloads

Documentation

API reference

Publisher

verified publishermassinissamouhoub.com

Weekly Downloads

Bump and sync a Flutter app's semantic version across pubspec.yaml, the iOS Xcode project and Android Gradle files, and repair drift between them.

Repository (GitHub)
View/report issues

Topics

#flutter #versioning #cli #release

License

MIT (license)

Dependencies

args

More

Packages that depend on easy_semver