Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adopt gha-scala-library-release process #32

Merged
merged 5 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: CI
on:
workflow_dispatch:
pull_request:

# triggering CI default branch improves caching
# see https://docs.github.com/en/free-pro-team@latest/actions/guides/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache
push:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup JDK
uses: actions/setup-java@v4
with:
distribution: corretto
java-version: 11
cache: sbt
- name: Build and Test
run: sbt compile
- name: Test Summary
uses: test-summary/action@v2
with:
paths: "test-results/**/TEST-*.xml"
if: always()
36 changes: 36 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Release

on:
workflow_dispatch:

jobs:
scala-maven-release:
name: Maven Release
uses: guardian/gha-scala-library-release-workflow/.github/workflows/reusable-release.yml@main
permissions: { contents: write, pull-requests: write }
secrets:
SONATYPE_PASSWORD: ${{ secrets.AUTOMATED_MAVEN_RELEASE_SONATYPE_PASSWORD }}
PGP_PRIVATE_KEY: ${{ secrets.AUTOMATED_MAVEN_RELEASE_PGP_SECRET }}
GITHUB_APP_PRIVATE_KEY: ${{ secrets.AUTOMATED_MAVEN_RELEASE_GITHUB_APP_PRIVATE_KEY }}

typescript-npm-release:
name: NPM Release
needs: scala-maven-release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: corretto
java-version: 11
cache: sbt
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
registry-url: https://registry.npmjs.org
- name: Release Typescript to NPM
run: |
sbt "project typescriptClasses" "releaseNpm ${{ needs.scala-maven-release.outputs.RELEASE_VERSION }}"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
RELEASE_TYPE: ${{ needs.scala-maven-release.outputs.RELEASE_TYPE }}
14 changes: 0 additions & 14 deletions .travis.yml

This file was deleted.

159 changes: 31 additions & 128 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,133 +1,47 @@
import sbtrelease._
import ReleaseStateTransformations._
import sbtrelease.ReleaseStateTransformations._
import sbtversionpolicy.withsbtrelease.ReleaseVersion

val scroogeVersion = "22.1.0"
val thriftVersion = "0.15.0"
val betaReleaseType = "beta"
val betaReleaseSuffix = "-beta.0"
val thriftVersion = "0.19.0"

lazy val versionSettingsMaybe = {
sys.props.get("RELEASE_TYPE").map {
case v if v == betaReleaseType => betaReleaseSuffix
}.map { suffix =>
releaseVersion := {
ver => Version(ver).map(_.withoutQualifier.string).map(_.concat(suffix)).getOrElse(versionFormatError(ver))
}
}.toSeq
}

lazy val mavenSettings = Seq(
pomExtra := (
<url>https://github.com/guardian/content-entity</url>
<developers>
<developer>
<id>LATaylor-guardian</id>
<name>Luke Taylor</name>
<url>https://github.com/LATaylor-guardian</url>
</developer>
<developer>
<id>tomrf1</id>
<name>Tom Forbes</name>
<url>https://github.com/tomrf1</url>
</developer>
<developer>
<id>justinpinner</id>
<name>Justin Pinner</name>
<url>https://github.com/justinpinner</url>
</developer>
</developers>
),
licenses := Seq("Apache V2" -> url("http://www.apache.org/licenses/LICENSE-2.0.html")),
publishTo := sonatypePublishToBundle.value,
publishConfiguration := publishConfiguration.value.withOverwrite(true)
)

lazy val checkReleaseType: ReleaseStep = ReleaseStep({ st: State =>
val releaseType = sys.props.get("RELEASE_TYPE").map {
case v if v == betaReleaseType => betaReleaseType.toUpperCase
}.getOrElse("PRODUCTION")

SimpleReader.readLine(s"This will be a $releaseType release. Continue? [y/N]: ") match {
case Some(v) if Seq("Y", "YES").contains(v.toUpperCase) => // we don't care about the value - it's a flow control mechanism
case _ => sys.error(s"Release aborted by user!")
}
// we haven't changed state, just pass it on if we haven't thrown an error from above
st
})

lazy val releaseProcessSteps: Seq[ReleaseStep] = {
val commonSteps = Seq(
checkReleaseType,
checkSnapshotDependencies,
inquireVersions,
runClean,
runTest
)

val prodSteps: Seq[ReleaseStep] = Seq(
setReleaseVersion,
commitReleaseVersion,
tagRelease,
publishArtifacts,
releaseStepCommandAndRemaining("+publishSigned"),
releaseStepCommand("sonatypeBundleRelease"),
setNextVersion,
commitNextVersion,
pushChanges
)

/*
Beta assemblies can be published to Sonatype and Maven.

To make this work, start SBT with the candidate RELEASE_TYPE variable set;
sbt -DRELEASE_TYPE=beta

This gets around the "problem" of sbt-sonatype assuming that a -SNAPSHOT build should not be delivered to Maven.

In this mode, the version number will be presented as e.g. 1.2.3.beta.n, but the git tagging and version-updating
steps are not triggered, so it's up to the developer to keep track of what was released and manipulate subsequent
release and next versions appropriately.
*/
val betaSteps: Seq[ReleaseStep] = Seq(
setReleaseVersion,
releaseStepCommandAndRemaining("+publishSigned"),
releaseStepCommand("sonatypeBundleRelease"),
setNextVersion
)

commonSteps ++ (sys.props.get("RELEASE_TYPE") match {
case Some(v) if v == betaReleaseType => betaSteps // this enables a beta build to sonatype and Maven
case None => prodSteps // our normal deploy route
})

}

val commonSettings = Seq(
val artifactProductionSettings = Seq(
organization := "com.gu",
scalaVersion := "2.13.2",
scalaVersion := "2.13.12",
// scrooge 21.3.0: Builds are now only supported for Scala 2.12+
// https://twitter.github.io/scrooge/changelog.html#id11
crossScalaVersions := Seq("2.12.11", scalaVersion.value),
releaseCrossBuild := true,
scmInfo := Some(ScmInfo(url("https://github.com/guardian/content-entity"),
"scm:git:git@github.com:guardian/content-entity.git")),
releasePublishArtifactsAction := PgpKeys.publishSigned.value
) ++ mavenSettings ++ versionSettingsMaybe
crossScalaVersions := Seq("2.12.18", scalaVersion.value),
scalacOptions ++= Seq("-release:11"),// going ahead with release option only. We might add more options if any implementation comes in future : ("-feature", "-deprecation", "-unchecked", "-Xfatal-warnings")
licenses := Seq(License.Apache2),
Test / testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-u", s"test-results/scala-${scalaVersion.value}", "-o")
)

lazy val root = (project in file("."))
.settings(commonSettings)
.settings(artifactProductionSettings)
.aggregate(thrift, scalaClasses)
.settings(
publishArtifact := false,
releaseProcess := releaseProcessSteps
publish / skip := true,
releaseVersion := ReleaseVersion.fromAggregatedAssessedCompatibilityWithLatestRelease().value,
releaseCrossBuild := true,
releaseProcess := Seq[ReleaseStep](
checkSnapshotDependencies,
inquireVersions,
runClean,
runTest,
setReleaseVersion,
commitReleaseVersion,
tagRelease,
setNextVersion,
commitNextVersion
)
)

lazy val scalaClasses = (project in file("scala"))
.settings(commonSettings)
.settings(artifactProductionSettings)
.settings(
name := "content-entity-model",
description := "Scala library built from Content-entity thrift definition",

Compile / scroogeThriftSourceFolder := baseDirectory.value / "../thrift/src/main/thrift",
Compile / scroogeThriftOutputFolder := sourceManaged.value,
Compile / scroogePublishThrift := true,
Expand All @@ -136,37 +50,26 @@ lazy val scalaClasses = (project in file("scala"))
libraryDependencies ++= Seq(
"org.apache.thrift" % "libthrift" % thriftVersion,
"com.twitter" %% "scrooge-core" % scroogeVersion,
"org.scalacheck" %% "scalacheck" % "1.14.0" % "test"
"org.scalacheck" %% "scalacheck" % "1.17.0" % "test"
)
)

lazy val thrift = (project in file("thrift"))
.settings(commonSettings)
.settings(artifactProductionSettings)
.disablePlugins(ScroogeSBT)
.settings(
name := "content-entity-thrift",
description := "Content entity model Thrift files",
crossPaths := false,
packageDoc / publishArtifact := false,
packageSrc / publishArtifact := false,
publish / skip := true,
Comment on lines -150 to +64
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah whoops, I see what happened here! Yep, we didn't want to add publish / skip := true here, because we do want an artifact. I think we probably want the original configuration (packageDoc / publishArtifact := false & packageSrc / publishArtifact := false) to stay as it is - they are only blocking the publishing of src & doc, not attempting to stop all artifacts for this module altogetherm as publishArtifact := false would have been.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @rtyley for confirming, yeah I didn't realise I restricted its publish.
I will revert to old changes on this section now 👍

Compile / unmanagedResourceDirectories += { baseDirectory.value / "src/main/thrift" }
)

lazy val npmBetaReleaseTagMaybe =
sys.props.get("RELEASE_TYPE").map {
case v if v == betaReleaseType =>
// Why hard-code "beta" instead of using the value of the variable? That's to ensure it's always presented as
// --tag beta to the npm release process provided by the ScroogeTypescriptGen plugin regardless of how we identify
// a beta release here
scroogeTypescriptPublishTag := "beta"
}.toSeq

lazy val typescriptClasses = (project in file("ts"))
.enablePlugins(ScroogeTypescriptGen)
.settings(commonSettings)
.settings(npmBetaReleaseTagMaybe)
.settings(artifactProductionSettings)
.settings(
publishArtifact := false,
publish / skip := true,
name := "content-entity-typescript",
scroogeTypescriptNpmPackageName := "@guardian/content-entity-model",
Compile / scroogeDefaultJavaNamespace := scroogeTypescriptNpmPackageName.value,
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.5.7
sbt.version=1.9.8
7 changes: 3 additions & 4 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
addSbtPlugin("com.gu" % "sbt-scrooge-typescript" % "1.6.0")

addSbtPlugin("com.github.sbt" % "sbt-release" % "1.1.0")
addSbtPlugin("com.github.sbt" % "sbt-release" % "1.4.0")

addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.1")

addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.10")
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.10.0")

addSbtPlugin("ch.epfl.scala" % "sbt-version-policy" % "3.2.0")