Skip to content

SBT may publish to Maven Central lot more efficiently #4958

@pshirshov

Description

@pshirshov

Many people are experiencing issues publishing their projects to Maven Central with SBT.

Typical complaints are:

  1. It takes a lot of time
  2. Many staging repositories may be open (see Found multiple staging repositories xerial/sbt-sonatype#83) and it may be impossible to promote a release in case, for example, a jar and it's signature file got into separate repositories.

Many projects (ZIO, for example) suffer from these problems.

I've investigated the issue a bit and found that just using Nexus-specific APIs may drastically improve user experience. So, in our case I got a 40x speedup - from 80 minutes with SBT to 2 minutes with Nexus publisher.

The following simple ANT script does the job:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:staging="antlib:org.sonatype.nexus.ant.staging">
    <property environment="env"/>
    <!-- https://oss.sonatype.org/ -->
    <property name="nexus.uri" value="${env.NEXUS_URI}" />
    <property name="nexus.user" value="${env.NEXUS_USER}" />
    <property name="nexus.pass" value="${env.NEXUS_PASS}" />
    <property name="dir.repo" value="${env.DIR_REPO}" />
    <property name="nexus.profile" value="${env.NEXUS_PROFILE}" />

    <taskdef uri="antlib:org.sonatype.nexus.ant.staging"
            resource="org/sonatype/nexus/ant/staging/antlib.xml">
    <classpath>
        <fileset dir="tasks" includes="nexus-staging-ant-tasks-*uber.jar" />
    </classpath>
    </taskdef>

    <staging:nexusStagingInfo id="target-nexus" stagingDirectory="target/staging">
        <staging:projectInfo
                groupId="org.sonatype.nexus.ant"
                artifactId="nexus-staging-ant-tasks"
                stagingProfileId="${nexus.profile}"
                version="1.0" />
        <staging:connectionInfo
            baseUrl="${nexus.uri}">
            <staging:authentication
            username="${nexus.user}"
            password="${nexus.pass}" />
        </staging:connectionInfo>
    </staging:nexusStagingInfo>

    <target name="deploy" description="Deploy: Local and Remote Staging">
        <staging:stageLocally>
            <staging:nexusStagingInfo refid="target-nexus" />
            <fileset dir="${dir.repo}" includes="**/*.*" />
        </staging:stageLocally>

        <staging:stageRemotely>
            <staging:nexusStagingInfo refid="target-nexus" />
        </staging:stageRemotely>

        <staging:releaseStagingRepository>
            <staging:nexusStagingInfo refid="target-nexus" />
        </staging:releaseStagingRepository>

        <staging:dropStagingRepository>
            <staging:nexusStagingInfo refid="target-nexus" />
        </staging:dropStagingRepository>
    </target>

</project>

More details may be found here

In order to prepare input for the script you have to publish to a local directory first with publishTo := Some(Resolver.file("file", new File("/path/to/repo")))

I think that SBT must support Nexus APIs and be able to publish to Central efficiently in transactional manner. Countless hours are being wasted because everyone publishes the usual way. And it should be relatively easy to do it.

Also it worths investigating if the same can be done for Artifactory.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions