Wondering how to SemVer-bump your Unity stuff without manual file editing? Look no further.
Created on February 21, 2020. Last updated on February 22, 2020.
I created a SemVer-bumping tool for Unity projects, UPM packages and monorepos. It's called
ubump. Running it is as simple as typing
npx ubump, and pressing enter. Go check out the GitHub page for more information, but here I'll explain why I made this hybrid CLI-API utility.
When I started building a collection of Unity DOTS demos for your viewing pleasure, I began to wonder how other people bump versions for their Unity projects in general. As my code evolved into a UPM monorepo, it was increasingly evident that I needed some kind of automated SemVer-bumping solution. Strictly for UPM packages, since they have the same
version field as NPM packages, one solution would be to wire up semantic-release in CI, and use commitizen locally, automating the process of version bumping through zealous commit linting.
Here are some examples:
docs(configuration): fix CLI usage with --branches option (#1465)
feat: require Node.js >=10.13
revert: fix: allow plugins to set environment variables to be used by other plugins
Is anyone else unnerved by the lack of human-readability in these commit messages? I pulled these directly from the
semantic-release GitHub repository. I don't know what
docs(configuration) fix so-and-so actually means. Also, is requiring a specific version of Node.js really a feature? And why say
revert: fix: so-and-so? A revert is inherently obvious in Git. While nobody's commit messages will ever be perfect, these are consistently... strange. Is the goal for commit messages themselves to eventually be Turing complete? I will say these messages are better than what an old coworker regularly used:
auto commit message.
Thanks, [REDACTED], your auto-commit script still haunts me.
Now, with all that said, the Unity project version itself is a bit of a problem. The project version is a field called
productVersion, and it's in
ProjectSettings/ProjectSettings.asset, which is actually a YAML file that can't be processed by a conventional YAML parser without throwing errors since it uses some weird custom tag in the header. Awesome.
And if you've got multiple packages, effectively as a UPM monorepo, say in the
Packages directory, good luck bumping them. The Node community seems to still be struggling to figure that out, especially since the bumping should be accompanied by Git tagging—and those tags have to be unique! In other words, we can't tag one package with
v1.0.5 and another with the same tag in the same repository.
I had to do something. I had to act. Versioning some packages shouldn't be difficult.
Again, I made ubump. It can be used as:
ubump. You would run this instead of committing, pushing, and tagging your own bumps, as inspired by release-it and np of the Node world.
ubumpfrom CI. If you've many collaborators, and you want to automate version bumping with a branching strategy like GitLab Flow, then my tool should work great for you.
ubumpis built with. You'd just import
ubumpinto your file and off you go.
The feature set will grow, so I leave you to peruse the GitHub page. Still,
ubump's interactive CLI sanity-checks your project for unstaged and staged changes. It also lets you know when you're not in the
master branch. Not to mention, when you select a
pre bump type, you will be further prompted for a specific prerelease identifier—the default is the existing one if it exists—otherwise it's just
ubump has no problem updating that pesky
ProjectSettings.asset file. And no matter how many packages you have, and no matter where the
package.json files are located (although they should be in the
Packages directory if you read Unity's docs),
ubump will find those files, and
kill update them at your instruction. It just globs through your project's entire directory tree.
And what about tagging? Don't worry about that.
ubump tags the main project (or if there's just one package defined at the root) with
v is just a default that you can override, by the way). As for tagging multiple packages,
ubump creates Git subtree branches for them so that they can be distributed separately from the main project. The commits on those branches are tagged accordingly.
So, if, for instance, you have a subpackage called
ubump will create a branch called
nav, and furthermore version it like
nav/v*.*.*. No colliding version tags! And all the tags
ubump creates are annotated, meaning they include automated changelog messages based on past commits!
I should mention that there's a plethora of commands and options you can pass to
ubump to tailor it for your needs. I implore you to give it a shot, at the very least trying it on a test project to see if it's right for you. If you have any concerns or suggestions, please let me know on GitHub Issues. I hope
ubump makes things easier!