How to publish packages?

What’s a good way to get started with publishing packages for Scala?
All tutorials seem to point to issues.sonatype.org but things seem to have moved around.
Is there another way to achieve this?
I just want to publish a public package so my devs can use them without relying on the locally built packages.

3 Likes

Hi @saki-osive, I ran into this as well when I wanted to publish a package to Sonatype. I had to scramble the information from sbt-sonatype and Sonatype docs, but eventually got there. Edit: I also used these steps from the sbt documentation, but had to adapt them for the new Sonatype website. This is what I did:

credentials ++= Seq(
  Credentials("Sonatype Nexus Repository Manager",
    "central.sonatype.com",
    "<username>",
    "<password>"
  ),
  Credentials(Path.userHome / ".sbt" / "credentials" / "pgp"),
)
realm=GnuPG Key ID
host=<namespace e.g. io.github.agboom>
user=<GPG key ID>
password=ignored
  • The commands below are from the sbt-sonatype plugin:
  • Ran sbt publishSigned from the project (this will ask for the password of the GPG key you created)
  • Ran sbt sonatypeCentralUpload
  • Checked upload status in Maven Central: Publishing
  • If upload is passed, click on publish

The last steps can be done from sbt with sbt sonatypeCentralRelease instead of sbt sonatypeCentralUpload. But verifying takes such a long time that I prefer to click on the button on de website. That’s a matter of preference I guess.

You can check out my project for an example, however the global sbt configuration as described above is not included there.

Hope this helps :slight_smile:

8 Likes

A great many Scala OSS packages these days, including most of the ones I’m involved with, use GitHub - sbt/sbt-ci-release: sbt plugin to automate Sonatype releases from GitHub Actions . The repo readme has what I believe are good instructions.

5 Likes
  1. You’ve set up an account on Sonatype, and you’ve proved to them that you are a real, trustworthy person via DNS records or whatever. You’ve got some credentials off them as a result.

  2. Do you want to publish releases for your own computer, or have CI do it for you?

  3. If from your own computer, I find a combination of sbt-release, sbt-sonatype and sbt-pgp plugins does the trick. There is a well-known hack that folk use in the build.sbt file that disables the cross-building support from sbt-release, doing the cross build via core SBT. It is all documented across the various plugin GitHub sites; there are also various blog entries going through the whole slog from getting in touch with Sonatype to initiating a publishing build.
    Read them.
    There is some faffing around with GPG on your machine to set up, but you’ve probably done all this already.
    I notice that scala-cli can publish using GPG in power user mode, so you might want to try a throwaway build using that to confirm that your Sonatype and GPG settings work well, then move over to SBT (or Gradle, or whatever) for the big time.

  4. If you’re going down the road of publishing from CI, then there are several SBT plugins for this, including the one @SethTisue mentioned above, they are all variations on a theme. I was going to use this for Americium, but found another approach using GitHub actions, so if that’s where your code lives, try this out: GitHub - guardian/gha-scala-library-release-workflow: Publishing Scala libraries to Maven Central using GitHub Actions.
    Have to say, I prefer this approach - the GPG and Sonatype voodoo now lives on GitHub, so when that huge crowd of developers starts working on Americium, the privileged few can initiate builds for themselves rather than petition me (and hope I have my laptop to hand). I found the workflow configuration easier to set up than with the plugins, but that’s just my opinion. The maintainer is a friendly chap too.

Example using sbt-release: GitHub - sageserpent-open/kineticMerge: Merge a heavily refactored codebase and stay sane.

Look at the build and plugins file.

Example using gha-scala-library-release-workflow: americium/.github/workflows/release.yaml at master · sageserpent-open/americium · GitHub

Good luck, and hopefully we’ll hear about your magnum opus in this forum soon…

EDIT: I forgot to mention, if you consult older blog entries, they might not mention that Sonatype uses access tokens as part of authentication/ authorisation these days, so make sure you’ve generated one and put it in the right place. That’s caught a lot of people out, myself included.

3 Likes

Interesting - do ‘your devs’ consume stable releases that you author independently of them?

Are you all working in some firewalled organisation with its own internal shared local Maven repository, or are you a loose collaboration? It might be easier to use a monorepo - or just publish to the internal repository, rather than going out to Sonatype and back…

2 Likes

If it’s a private repo, I find it’s also quite easy to publish to GitHub packages.

AFAIK, you just need to set the following in SBT:

publishTo := Some(
  "GitHub Package Registry (<your_repo_name>)".at("https://maven.pkg.github.com/<your_org_name>/<your_repo_name>"))

credentials ++= {
  val githubToken = System.getenv("GITHUB_TOKEN")
  if (githubToken == null) Seq.empty
  else Seq(Credentials("GitHub Package Registry", "maven.pkg.github.com", "_", githubToken))
}

And then just add the new resolver to the consumer:

  resolvers ++=
    Seq("GitHub Package Registry" at "https://maven.pkg.github.com/<your_org_name>/_")

(I believe that is all, but I might be forgetting something)

1 Like

I didn’t pick up on that: so to clarify, are you already experienced with the whole publishing workflow and are simply saying, “What have Sonatype gone and changed this time round?”, or you starting ab-initio and need advice with the whole soup-to-nuts experience?

If the first case, then there is a link on that page you referenced that points to OSSRH registration: Register to Publish Via OSSRH - Documentation, which seems to have become a legacy concept.

You will have seen the health warning on that page you referenced about third-party articles, so you’ll have to use your initiative and map what the articles say on to the new way, which I guess is what @agboom was alluding to by ‘scramble the information’.

Here’s a motivational poster for you: impurepics - Deploy to sonatype

If it’s the second case, then there is whole load of stuff you’ll just have to wade through on the Sonatype site, SBT and the various plugins. Plus the fun of getting to step 1 on my check list above.

Again, if you’re actually working in a corporate environment, I’d consider short-circuiting this palaver by a monorepo, or internal publishing. Hard to know what to recommend as I don’t have the context, but you’ve got plenty of advice to work with…

2 Likes

Hi @sageserpent-open ,

Appreciate you taking the time to reply with a detailed explainer. I would walk through this over the course of the week.

  1. Do you want to publish releases for your own computer, or have CI do it for you?

Presently, I aim to publish packages myself because the package isn’t updated very frequently. But going ahead I would be using something like Jenkins or Github actions for that.

Thanks a lot!

1 Like

Interesting - do ‘your devs’ consume stable releases that you author independently of them?

I sometimes do it independently, but we collaborate on the packages if need be.

Are you all working in some firewalled organisation with its own internal shared local Maven repository, or are you a loose collaboration? It might be easier to use a monorepo - or just publish to the internal repository, rather than going out to Sonatype and back…

We are closer to being a loose collaboration. We are a distributed team, I have the basic know-how to self-host stuff privately and/or create a VPC on major clouds, but I mostly stick to my private OpenStack for self-hosting needs.

I notice that scala-cli can publish using GPG in power user mode, so you might want to try a throwaway build using that to confirm that your Sonatype and GPG settings work well, then move over to SBT (or Gradle, or whatever) for the big time.

I want to point out that if one can accept that scala-cli is limited to single-module projects, scala-cli is totaly fine for publishing (at least for publishing from a local machine) and so much simpler to set up than sbt - so no need to switch to sbt if scala-cli works for the project at hand.