diff --git a/.github/scripts/publish.sh b/.github/scripts/publish.sh new file mode 100755 index 00000000000..9e5c9b4ed3f --- /dev/null +++ b/.github/scripts/publish.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -x + +# Ideally Snapshots could use mill.javalib.SonatypeCentralPublishModule/ too +# but it does not work for them on 1.0.1. It seems to publish to the wrong place. +IS_SNAPSHOT=$(./mill show unipublish.isSnapshot) +PLUGIN_VERSIONS=$(./mill show plugin.publishableVersions) +PLUGIN_MODULES=$(jq -r 'map("plugin.cross[" + . + "]")' <<< "${PLUGIN_VERSIONS}") +MODULES=$(jq -r '. + ["unipublish"]' <<< "${PLUGIN_MODULES}") +if [[ "${IS_SNAPSHOT}" = "true" ]]; then + for mod in $(jq -r '.[]' <<< "$MODULES"); do + ./mill ${mod}.publish + done +else + VERSION=$(./mill show unipublish.publishVersion | tr -d \") + BUNDLE_NAME=$(./mill show unipublish.artifactMetadata | jq -r '.group + "." + .id + "-" + .version') + MODULES_LIST=$(jq -r 'join(",")' <<< "${MODULES}") + ./mill mill.javalib.SonatypeCentralPublishModule/ \ + --shouldRelease "false" \ + --bundleName "$BUNDLE_NAME" \ + --publishArtifacts "{${MODULES_LIST}}.publishArtifacts" +fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 696efc56be5..e769fd89a2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,9 +71,7 @@ jobs: publish: needs: [all_tests_passed] runs-on: ubuntu-24.04 - # Only publish on release until Mill supports publishing snapshots to Maven Central - # https://github.com/com-lihaoyi/mill/issues/4421 - if: startsWith(github.ref, 'refs/tags/') + if: github.event_name == 'push' steps: - name: Checkout @@ -87,12 +85,12 @@ jobs: with: jvm: temurin:11 - name: Publish - run: ./mill publish.publishAll + run: .github/scripts/publish.sh env: - PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} - PGP_SECRET: ${{ secrets.PGP_SECRET }} - MAVEN_CENTRAL_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }} - MAVEN_CENTRAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} + MILL_PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} + MILL_PGP_SECRET_BASE64: ${{ secrets.PGP_SECRET }} + MILL_SONATYPE_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }} + MILL_SONATYPE_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} - run: | VERSION=$(./mill show unipublish.publishVersion | tr -d \") echo "Published version: $VERSION" >> $GITHUB_STEP_SUMMARY diff --git a/build.mill b/build.mill index e6137f83c9e..0f5ac4b0089 100644 --- a/build.mill +++ b/build.mill @@ -7,11 +7,8 @@ package build import mill._ import mill.api.{BuildCtx, Result} -import mill.javalib.SonatypeCentralPublishModule import mill.scalalib._ import mill.scalalib.scalafmt._ -import mill.scalalib.publish.{Artifact, SonatypePublisher} -import com.lumidion.sonatype.central.client.core.{PublishingType, SonatypeCredentials} object v extends Module { @@ -69,10 +66,6 @@ object v extends Module { } } - // Projects that we publish to Maven - def publishedProjects: Seq[SonatypeCentralPublishModule] = - pluginScalaCrossVersions.filterNot(isScala3).map(plugin.cross(_)) ++ Seq(unipublish) - val scalaVersion = scalaCrossVersions.head val jmhVersion = "1.37" val osLib = mvn"com.lihaoyi::os-lib:0.10.7" // 0.11 requires Java 11 @@ -363,63 +356,3 @@ trait Chisel extends CrossSbtModule with HasScala2MacroAnno with HasScalaPlugin } object unipublish extends Unipublish - -/** Tasks for publishing to Sonatype */ -object publish extends Module { - - def getEnvVar(name: String) = Task.Command { - Task.env.get(name) match { - case Some(value) => Result.Success(value) - case None => Result.Failure(s"Must define environment variable $name") - } - } - - def sonatypeCredentials: Task[SonatypeCredentials] = Task.Anon { - val username = getEnvVar("MAVEN_CENTRAL_USERNAME")() - val password = getEnvVar("MAVEN_CENTRAL_PASSWORD")() - SonatypeCredentials(username, password) - } - - def importPgp = Task.Anon { - val secret = getEnvVar("PGP_SECRET")() - os.call( - ("gpg", "--import", "--no-tty", "--batch", "--yes"), - stdin = java.util.Base64.getDecoder.decode(secret) - ) - } - - // We can't directly use mill.scalalib.SonatypeCentralPublishModule.publishAll because - // there's no easy way to programmatically pick which Modules to publish, and - // we don't want to publish everything. - // We aren't yet publishing Scala 3 cross-builds nor the CIRCT bindings. - def publishAll(): Command[Unit] = Task.Command { - val artifacts: Seq[(Seq[(os.Path, String)], Artifact)] = - Task.traverse(v.publishedProjects)(_.publishArtifacts)().map { case PublishModule.PublishData(a, s) => - (s.map { case (p, f) => (p.path, f) }, a) - } - // unipublish is the main Chisel artifact, use it to make bundle name - val PublishModule.PublishData(Artifact(group, id, version), _) = unipublish.publishArtifacts() - val bundleName = Some(s"$group.$id-$version") - - val sonatypeCreds = sonatypeCredentials() - // Import GPG, this is mutating the environment - importPgp() - val pgpPass = getEnvVar("PGP_PASSPHRASE")() - val gpgArgs = PublishModule.defaultGpgArgsForPassphrase(Some(pgpPass)) - - new SonatypeCentralPublisher( - sonatypeCreds, - gpgArgs, - readTimeout = 10 * 60 * 1000, - connectTimeout = 10 * 1000, - Task.log, - BuildCtx.workspaceRoot, - Task.env, - awaitTimeout = 10 * 60 * 1000 - ).publishAll( - publishingType = PublishingType.USER_MANAGED, // confirm in UI - singleBundleName = bundleName, - artifacts* - ) - } -} diff --git a/plugin/package.mill b/plugin/package.mill index 231d820656f..8514b2a0163 100644 --- a/plugin/package.mill +++ b/plugin/package.mill @@ -10,6 +10,10 @@ import build._ object `package` extends Module { // https://github.com/com-lihaoyi/mill/issues/3693 object cross extends Cross[Plugin](v.pluginScalaCrossVersions) + + def publishableVersions = Task { + v.pluginScalaCrossVersions.filter(!v.isScala3(_)) + } } trait Plugin extends CrossSbtModule with ScalafmtModule with ChiselPublishModule { diff --git a/release.mill b/release.mill index bdff83d668f..ce622f1de0d 100644 --- a/release.mill +++ b/release.mill @@ -3,7 +3,6 @@ package build import mill._ import mill.api.{BuildCtx, Result} import mill.javalib.SonatypeCentralPublishModule -import mill.javalib.api.JvmWorkerUtil.matchingVersions import mill.scalalib._ import mill.scalalib.scalafmt._ import mill.scalalib.publish._ @@ -38,6 +37,9 @@ trait Unipublish extends ScalaModule with ChiselPublishModule { def scalaVersion = v.scalaVersion + /** Is this a SNAPSHOT release? */ + def isSnapshot = Task { publishVersion().endsWith("-SNAPSHOT") } + // This is published as chisel override def artifactName = "chisel"