What is the recommendation for versioning multiple...
# multiplatform
n
What is the recommendation for versioning multiple published modules in a KMP project? We currently are setting separate versions for each module and incrementing them as needed, but are experiencing a lot of pain points with manually publishing each module. I’d like to use a single version to simplify the development flow of writing KMP code, publishing, then updating the version in the android app. For iOS we are using the umbrella framework.
d
Perhaps you are in need of a Bill of Materials?
c
My opinion is that if you want the modules to have separate versions, it’s best to keep them in separate repos and maintain them independently. Unless you’re managing a very project like Spring or Androidx, it’s going to be more trouble than its worth for both you and your library consumers. The BOM is probably more useful when you have lots of semi-related libraries that aren’t managed in the same repo, to help maintain compatibility when Gradle is changing version numbers on you that you might not be fully aware of. I think it’s just easier to keep everything in one repo, give everything the same version number, and release all modules at the same time, even ones that don’t have changes, so the consumer only needs to keep 1 version number in mind
n
@dewildte We thought of BOMs, but the team is small doesn’t have the capacity to maintain it right now.
I think it’s just easier to keep everything in one repo, give everything the same version number, and release all modules at the same time, even ones that don’t have changes, so the consumer only needs to keep 1 version number in mind
@Casey Brooks This is what we are thinking of doing as well. I’m currently struggling with the implementation of that strategy. I tried to add a build.gradle extra, however gradle isn’t finding the property I defined in the root.
We currently have a KMP monorepo, an android monorepo and an iOS one
d
manually publishing each module
Is there a script or another tool you can use to automatically update the values in the modules for you? Provided you keep them all different versions that is.
Sorry I do not do SDK/library development so I probably sound a bit ignorant…because I am.
c
Rather than putting in project extras, you can set a property in the root
gradle.properties
, which should be available to all subprojects as well through
project.properties["customVersion"]
. Alternatively, I use Git tags and some custom code to compute the version number in my libraries. You can see how I do it here
🙌 1
n
@Casey Brooks how do you use the
ProductVersion
code to then set the version of each KMP module?
c
I’ve got some convention scripts which make it a bit more complex, but essentially just adding this into your project’s
build.gradle.kts
file will do
Copy code
version = ProjectVersion.get(project = project, logChanges = false)
It’s mostly just something I threw together for my own use, so it’s not documented or anything, but the basic workflow is this: • Create a Git tag with a Semantic version number (for example, 1.0.0) • Any commits after that that will bump the version in accordance with the commit message and the latest tag. For example,
[major] My commit message
will bump a major version (to 2.0.0), and
[minor] My commit message
will do a minor bump (1.1.0). Absent any of those, it will give you a patch version bump (1.0.1). • When you run a release build, add
-Prelease
to the Gradle command, otherwise the version will include the
-SNAPSHOT
suffix • After releasing, make sure to create a Git tag with the version number that just released
n
And then in the modules’
build.grade.kts
files you don’t specify a version? Only the project’s
build.gradle.kts
has a version?
c
A “module” and “project” are the same thing (or rather, Gradle doesn’t really use the term “module”). Are you referring the the “root project” vs a “subproject”?
version = ProjectVersion.get
is not shared among projects, so it should be added to every subproject that wants to use the computed value
n
Yeah that makes sense, got it! If I were to include the script in the same repo, would it go in a
BuildSrc
folder?
c
yup!
n
Thanks for your help!
r
I bookmarked this earlier to add my 2 cents: I tend to prefer to keep version numbers in git tags, and as part of the build process inject them into gradle as the "version". I wrote a few plugins to make that easier. For my multiplatform libraries I use those to generate the version numbers for the build, and they all get tagged with the same number if they're in the same repository
Those plugins are open source if you're looking for some solutions / suggestions that align with that fairly opinionated angle
s
I am also following the same approach as mentioned by @Rob Murdock .. Using this nice gradle plugin to auto versioning all modules- https://github.com/JavierSegoviaCordoba/semver-gradle-plugin
👏 1
r
Looks like I forgot to link my plugin - could be better documented but if anyone's interested its here! https://github.com/robertfmurdock/ze-great-tools/blob/main/tools/tagger-plugin/README.md
👍 1
(its basically a rewrite of https://github.com/tschulte/gradle-semantic-release-plugin which I used for a number of years for the same purposes)
s
@Nicole Paprocki i have a sample kmp project which publishes all modules with same version ..check this if you are interested - https://github.com/sureshg/kotlin-mpp-playground#module-dependency (https://github.com/sureshg?tab=packages&repo_name=kotlin-mpp-playground) . Played a lot of time with gradle to come up something like this 🙂
n
Thank you! Much appreciated, I have also sunk a lot of time into battling with gradle 😅