Release workflow
Record changes, stamp the next version, tag the release, and produce Play Store release notes with one command.
Every production release follows the same loop: record what changed, pick the next version, stamp it into the project, tag it, and build. BowlerKit turns that loop into a single command — bowler changelog release — so the version in pubspec.yaml, the changelog, git history, and your bowlerShip dashboard never drift apart.
Version convention
BowlerKit uses the Flutter convention x.y.z+N: a semantic version name plus a monotonically increasing integer code.
| Surface | Where | Example |
|---|---|---|
| Version name | mobile-app/pubspec.yaml → version:, before the + | 1.2.4 |
| Android versionCode / iOS build number | same line, after the + | 8 |
The full string 1.2.4+8 also labels the changelog block and the git tag (v1.2.4+8), so one identifier traces a release from source to store. Flutter derives the iOS CFBundleVersion from the same build number automatically.
Google Play rejects an upload whose versionCode is not higher than the previous one. The release command enforces the store rules before touching any file: the code must rise on every release and the version name must never go down.
Record what changed
Changelog entries live in .bowlerkit/changelog.md (Keep a Changelog format, committed with the project):
bowler changelog add # interactive: pick a section + one-line summary
bowler changelog draft # propose entries from commits since the last v* tag
bowler changelog list # show the changelogdraft maps conventional-commit prefixes to sections (feat → Added, fix → Fixed, remove/revert → Removed, anything else → Changed), skips merge commits, and records commit hashes for traceability. Re-running is safe: commits already recorded are skipped. Entries stay close to the commit subjects on purpose — release notes that read well for end users are produced on bowlerShip, which the changelog mirrors to on every bowler changelog release.
Run the release
From the generated project root:
bowler changelog releaseWithout flags the command is interactive — it proposes the next patch bump and asks you to confirm:
Versi baru? (sekarang 1.0.0+3)
1.0.1+4 Patch (usulan)
1.1.0+4 Minor
2.0.0+4 Major
1.0.0+4 Code only
> Custom…After you choose, the command stamps the version, releases the changelog, commits, tags, and prints the store notes:
✓ mobile-app/pubspec.yaml → 1.2.4+8
✓ .bowlerkit/project.json → 1.2.4+8
✓ .bowlerkit/changelog.md → ## [1.2.4+8] - 2026-09-12
✓ commit chore(release): v1.2.4+8
✓ tag v1.2.4+8
What's new untuk Play Console (versi 1.2.4+8):
- Crash saat refresh
- Mesin kalender Bali
✓ 42 karakter — aman (batas 500 per bahasa).Flags
| Flag | Effect |
|---|---|
| (none) | Interactive prompt with the patch proposal as default |
--patch / --minor / --major | Bump the corresponding segment; code +1 |
--code-only | Keep the version name, raise only the code |
--version x.y.z | Explicit version name (code defaults to current + 1) |
--code N | Override the version code |
--yes | Accept the patch proposal without prompting |
--date YYYY-MM-DD | Override the changelog date (default: today) |
--allow-empty | Release with an empty [Unreleased] (code-only re-release) |
--no-commit / --no-tag / --no-sync | Opt out of the automatic commit / tag / bowlerShip push |
--dir <path> | Run against another project directory |
What gets written
| File | Change |
|---|---|
mobile-app/pubspec.yaml | The version: line is rewritten to x.y.z+N (a trailing comment is preserved) |
.bowlerkit/project.json | The app.version block follows the new release |
.bowlerkit/changelog.md | [Unreleased] entries move into a ## [x.y.z+N] - date block |
Git commit and tag
The command commits exactly the release-touched files — anything else you have modified or staged stays untouched — with the message chore(release): v<x.y.z+N>, then creates the matching git tag. The tag is the anchor the next bowler changelog draft counts commits from.
If a tag v<x.y.z+N> already exists, the release aborts before any file is modified — that exact version was already released, so pick another. Use --no-commit/--no-tag to manage git yourself; with --no-commit the tag (if any) points at HEAD, which does not yet contain the release.
Sync to bowlerShip
When the project is bound (bowler ship connect), the release pushes a snapshot automatically: the new version appears on the bowlerShip dashboard and the released changelog shows up on its Changelog page. Without a binding the command prints the manual follow-up (bowler ship sync). Skip the push with --no-sync.
Code-only re-release
Sometimes the store rejects an upload, or a build fix does not merit a changelog line. Re-release the same version name with a fresh code:
bowler changelog release --code-only --allow-empty--allow-empty permits an empty [Unreleased]; the resulting version block carries no entries and stays invisible on the bowlerShip changelog page.
After the release
Build the production artifacts:
flutter build appbundle --release # Google Play
flutter build apk --release # sideloading / internal testing
flutter build ipa --release # App Store (macOS/Xcode only)For the surrounding checklist (signing, store listing, assets), see Play Store Assets & Publishing Checklist. For the rest of the CLI, see CLI Reference.
