SBT does not allow re-publishing artifacts with the same version unless it is a snapshot version. A snapshot version ends with the -SNAPSHOT
suffix, such as 0.1.0-SNAPSHOT
.
Re-publishing, which involves running the sbt publish
or sbt publishLocal
command for the second time or more, is standard, especially for snapshot versions.
If you attempt to re-publish a non-snapshot version, SBT will warn you with the following message and not publish the artifact.
[warn] You need to remove it from the cache manually to take effect.
[warn] Attempting to overwrite <ivy2-path-to>/<your>_2.12.jar (non-SNAPSHOT)
As you can see, SBT highlights that the version is non-SNAPSHOT.
What do we do when your snapshot version is of non-standard format, such as <version>-<git_branch_name>
? For example, 0.1.0-feature-gtm
where trailing feature-gtm
is equivalent to SNAPSHOT
.
For release and local publishing, SBT has publishConfiguration
and publishLocalConfiguration
, which surprisingly are Task s and not Setting s.
inspect publishLocalConfiguration
[info] Task: sbt.librarymanagement.PublishConfiguration
[info] Description:
[info] Configuration for publishing to the local Ivy repository.
[info] Provided by:
[info] ProjectRef(uri("...")) / publishLocalConfiguration
...
The publish configuration tasks above have a withOverwrite
function that you can use to set to true
to re-publish artifacts.
publishConfiguration ~= { _.withOverwrite(true) }
publishLocalConfiguration ~= { _.withOverwrite(true) }
The above code updates the task’s overwrite flag. But you must ensure that the publishConfiguration.withOverwrite
is set to true
only for snapshot versions and not release ones. It may be fine for local publishing, but it is better to watch which versions you use and when you are overwriting.
While you can update publish[Local]Configuration
, it may not work as desired, mainly because of the scopes/axes of the Task s. Configuring using ThisBuild
will not work. Also, in a multi-module project, I had to apply the configuration explicitly to each sub-project. Centralizing the configuration in a plugin also did not help. I suspect the order of loading plugins is not deterministic. I don’t know if there is a way to make it work.
There is a short and straightforward way to configure the publish configuration to overwrite snapshot versions. Enter
ThisBuild / isSnapshot := true
.
It is nice that isSnapshot
is a Setting
.
In my case, I had another property that determines the version depending on the branch name and also tells if it is not a release version. So, I used that to set the value of isSnapshot
. No more fiddling with publish[Local]Configuration
.