Accessing the Coursier executable from SBT in a GitHub build

Advice required, this is an involved question mixing GitHub up with Coursier and SBT:

I’m moving a release build using sbt release away from running it on my personal laptop with local secrets, to running it on GitHub with secrets parked in the project configuration.

There is a nice workflow that supports this, gha-scala-library-release-workflow and it has been working well for the Americium project. It publishes to Sonatype and also builds GitHub releases (ie. tags the commit, then generates the release page for that tag).

So far, so good. It’s all very slick and reliable.

The wrinkle I’m getting is trying to do the same thing for the Kinetic Merge project - the subtlety is that the release doesn’t just publish JARs to Sonatype, it also builds executables using Coursier; so far, I have been manually uploading them into the corresponding release, doing all the publishing to Sonatype via sbt-release augmented with sbt-sonatype + sbt-pgp etc.

So what I want to do is to be able to run the Coursier executable cs within SBT, but in the context of a GitHub workflow job’s action, one that I don’t have access to (it’s a reused workflow).

Now there is an action available to set up Coursier on the GitHub marketplace, but it has to run as a step in a job, and that can’t be mixed with reusable workflows, because That’s The Way It Is.

It is possible to park the setup action in a separate job prior to the one invoking the reusable workflow, but as far as I can tell, that loses the installation of Coursier because each job runs on its own isolated virtual machine or container or whatever it is that GitHub runs jobs on.

So I’m casting around trying to find an approach that works.

Things I’m considering include:

  1. Raising a pull request to the author of gha-scala-library-release-workflow to include the Coursier setup action (or cutting and pasting the entire workflow myself). I don’t think this is a good way of proceeding, but if needs must…
  2. Hoping there is some way of forcing affinity between jobs so that the second job can run on the same machine as the first, and thus pick up Coursier. Hmm.
  3. Programmatically invoking Coursier from SBT; I presume the API is available to any code running in build.sbt, because Coursier is already used by SBT.
  4. Writing an extra job that installs Coursier, checks out the Kinetic Merge repository to the transient commit made in the middle of the build, then rebuilds and packages the executable, then uploads to the release via the GitHub REST API.

I’m leaning to the third option, but would be interested in hearing from others if they’ve been down this path already.

(As an aside, Kinetic Merge is also on the Coursier contrib application channel, so folks who use it already can simply do cs install --contrib kinetic-merge, but I’m trying to support those who are reduced to having to download off Github).

1 Like

It turned out that the third option was pretty easy to do, as Coursier ships a CLI JAR that can be referenced in the SBT meta-build.

So all I have to do now is figure out how to reference the executables generated by Coursier in the middle of the build and push them into the GitHub REST API - and that’s just down to being familiar with GitHub workflows, so no need to worry.

2 Likes