From dfb698f235004444316b8a5faf6f1d98fc4969ac Mon Sep 17 00:00:00 2001 From: Roberto Tyley Date: Wed, 13 Dec 2023 12:50:29 +0000 Subject: [PATCH] Adopt GHA Scala Library Release Workflow This replaces the old release process which had developers manually running `sbt release` on their own laptops - each developer had to obtain their own PGP key and Sonatype credentials, which was an elaborate & fiddly process. Now there's a single set of release credentials, available through GitHub Organisation Secrets, like we already have with NPM. ### Required changes The changes required to adopt the automated workflow: * No need to set these sbt configuration keys, as they're now taken care of by the workflow: * `sonatypeProfileName` * `publishTo` * `scmInfo` & `pomExtra` * Remove the sign, publish, release & push steps of sbt-release's `releaseProcess` configuration, because the workflow does those now, and the workflow only wants `sbt release` to create the versioning commits, and tag them appropriately. The workflow does the rest itself. * Remove `sbt-pgp` plugin because it's no longer used - the workflow does the signing using `gpg` directly. * Grant this repo access to the GitHub Organisation Secrets containing the Maven Release credentials with https://github.com/guardian/github-secret-access/pull/21 * Unusually, drop running the tests as part of the release for now, as the tests in this project require special credentials (see https://github.com/guardian/facia-scala-client/pull/272) Additionally, we add **automatic version numbering** based on compatibility assessment performed by `sbt-version-policy`: * Add the `sbt-version-policy` plugin, to allow it to do the compatibility assessment. This also sets the `versionScheme` for this library to `early-semver`, which is the recommended versioning for Scala libraries, and `sbt-version-policy` & correct sbt-eviction-issue-detection pretty much depend on the `versionScheme` being `early-semver`. Thus we also need to switch to using a new semver version number for our library version! * Add the `releaseVersion := fromAggregatedAssessedCompatibilityWithLatestRelease().value` sbt setting, which will intelligently set the release version based on `sbt-version-policy`'s compatibility assessment, thanks to https://github.com/scalacenter/sbt-version-policy/pull/187 . * Use `publish / skip := true`, rather than other hacks like `publish := {}` or `publishArtifact := false`, to tell sbt not to publish modules that we don't want published (typically, the 'root' module) - this is important because `sbt-version-policy` won't understand those hacks, but _will_ understand `publish / skip := true` means that it doesn't need to assess compatibility there. Recent prior example of adding `gha-scala-library-release-workflow` to a repo: https://github.com/guardian/play-googleauth/pull/208 --- .github/workflows/release.yml | 13 +++++++++++++ README.markdown | 23 ++++++++--------------- build.sbt | 33 +++++---------------------------- project/build.properties | 2 +- project/plugins.sbt | 3 +-- 5 files changed, 28 insertions(+), 46 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..8654cf6b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,13 @@ +name: Release + +on: + workflow_dispatch: + +jobs: + release: + uses: guardian/gha-scala-library-release-workflow/.github/workflows/reusable-release.yml@main + permissions: + contents: write + secrets: + AUTOMATED_MAVEN_RELEASE_PGP_SECRET: ${{ secrets.AUTOMATED_MAVEN_RELEASE_PGP_SECRET }} + AUTOMATED_MAVEN_RELEASE_SONATYPE_PASSWORD: ${{ secrets.AUTOMATED_MAVEN_RELEASE_SONATYPE_PASSWORD }} diff --git a/README.markdown b/README.markdown index 4e4f1ad4..ac3a0fa8 100644 --- a/README.markdown +++ b/README.markdown @@ -1,4 +1,4 @@ -Facia Scala Client [![fapi-client-play28 Scala version support](https://index.scala-lang.org/guardian/facia-scala-client/fapi-client-play28/latest-by-scala-version.svg)](https://index.scala-lang.org/guardian/facia-scala-client/fapi-client-play28) +Facia Scala Client [![fapi-client-play28 Scala version support](https://index.scala-lang.org/guardian/facia-scala-client/fapi-client-play28/latest-by-scala-version.svg)](https://index.scala-lang.org/guardian/facia-scala-client/fapi-client-play28) [![Release](https://github.com/guardian/facia-scala-client/actions/workflows/release.yml/badge.svg)](https://github.com/guardian/facia-scala-client/actions/workflows/release.yml) ================== Facia's Scala client is split into two parts. @@ -79,20 +79,13 @@ At the time of writing, Tools, CAPI, Dotcom, Mobile teams (Mapi) and Ophan all u ## Building a release -[This document](https://docs.google.com/document/d/1rNXjoZDqZMsQblOVXPAIIOMWuwUKe3KzTCttuqS7AcY/edit) is a good source of information about releasing Guardian artefacts generally. +This project uses the [`gha-scala-library-release-workflow`](https://github.com/guardian/gha-scala-library-release-workflow) +to release to Maven Central. To release a new version, execute the +[Release](https://github.com/guardian/facia-scala-client/actions/workflows/release.yml) +workflow in the Actions tab on GitHub: -To release a new version of the client: +![RunReleaseWorkflow](https://github.com/guardian/facia-scala-client/assets/52038/23920a58-80c6-4e6d-b5bc-6f58bf78f41d) -1. Ensure you have a GPG key listed on a public key server. -2. Ensure you are registered on Sonatype for Guardian projects. -3. Open sbt and run the [sbt release](https://github.com/sbt/sbt-release) task: +_You'll need to refresh the page to see the new workflow run._ -``` -$ sbt -sbt:facia-api-client> release -``` - -4. When the release process has completed successfully, document the new version with a GitHub Release note - ([guide](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository)) - describing the change (the `Generate release notes` button can give you a good start!): - https://github.com/guardian/facia-scala-client/releases/new \ No newline at end of file +https://github.com/guardian/facia-scala-client/assets/52038/dfc014d9-98f9-4d20-8977-0a20340083d1 diff --git a/build.sbt b/build.sbt index 59485010..0bd1f561 100644 --- a/build.sbt +++ b/build.sbt @@ -1,5 +1,6 @@ import Dependencies._ import sbtrelease.ReleaseStateTransformations._ +import sbtversionpolicy.withsbtrelease.ReleaseVersion.fromAggregatedAssessedCompatibilityWithLatestRelease organization := "com.gu" @@ -8,41 +9,18 @@ name := "facia-api-client" description := "Scala client for The Guardian's Facia JSON API" val sonatypeReleaseSettings = Seq( - licenses := Seq("Apache V2" -> url("http://www.apache.org/licenses/LICENSE-2.0.html")), - scmInfo := Some(ScmInfo( - url("https://github.com/guardian/facia-scala-client"), - "scm:git:git@github.com:guardian/facia-scala-client.git" - )), - pomExtra := ( - https://github.com/guardian/facia-scala-client - - - janua - Francis Carr - https://github.com/janua - - - adamnfish - Adam Fisher - https://github.com/adamnfish - - - ), + licenses := Seq("Apache V2" -> url("https://www.apache.org/licenses/LICENSE-2.0.html")), + releaseVersion := fromAggregatedAssessedCompatibilityWithLatestRelease().value, releaseCrossBuild := true, // true if you cross-build the project for multiple Scala versions releaseProcess := Seq[ReleaseStep]( checkSnapshotDependencies, inquireVersions, runClean, - runTest, setReleaseVersion, commitReleaseVersion, tagRelease, - // For non cross-build projects, use releaseStepCommand("publishSigned") - releaseStepCommandAndRemaining("+publishSigned"), - releaseStepCommand("sonatypeBundleRelease"), setNextVersion, - commitNextVersion, - pushChanges + commitNextVersion ) ) @@ -52,7 +30,6 @@ lazy val root = (project in file(".")).aggregate( fapiClient_play27, fapiClient_play28 ).settings( - publishArtifact := false, publish / skip := true, sonatypeReleaseSettings ) @@ -70,12 +47,12 @@ def baseProject(module: String, majorMinorVersion: String) = Project(s"$module-p scalaVersion := "2.13.11", crossScalaVersions := Seq(scalaVersion.value, "2.12.18"), scalacOptions := Seq( + "-release:11", "-feature", "-deprecation", "-Xfatal-warnings" ), libraryDependencies += scalaTest, - publishTo := sonatypePublishToBundle.value, sonatypeReleaseSettings ) diff --git a/project/build.properties b/project/build.properties index 52413ab7..e8a1e246 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.3 +sbt.version=1.9.7 diff --git a/project/plugins.sbt b/project/plugins.sbt index acbc3a13..fa479abb 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,5 @@ addSbtPlugin("com.github.sbt" % "sbt-release" % "1.1.0") -addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1") +addSbtPlugin("ch.epfl.scala" % "sbt-version-policy" % "3.2.0") addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.21") -