diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..65e41bb --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,55 @@ +name: PerfIO CI + +on: +# push: +# branches: [ "master" ] +# pull_request: +# branches: [ "master" ] + workflow_dispatch: + +permissions: + contents: read + +defaults: + run: + shell: bash + +jobs: + build: + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + java: 21 + - os: ubuntu-latest + java: 23 + - os: macos-latest + java: 23 + runs-on: ${{matrix.os}} + name: Test + steps: + - uses: actions/checkout@v4 + - name: Set up Java + uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.java }} + distribution: 'temurin' + cache: 'sbt' + - name: Set up sbt + uses: sbt/setup-sbt@v1 + - name: Set up protobuf + run: | + mkdir ~/protobuf + if [[ "$RUNNER_OS" = "macOS" ]]; then + PB_URL=https://github.com/protocolbuffers/protobuf/releases/download/v29.0-rc3/protoc-29.0-rc-3-osx-aarch_64.zip + else + PB_URL=https://github.com/protocolbuffers/protobuf/releases/download/v29.0-rc3/protoc-29.0-rc-3-linux-x86_64.zip + fi + (cd ~/protobuf && curl -Lo pb.zip $PB_URL && unzip pb.zip) + - name: Run tests + run: | + if [[ "${{ matrix.java }}" = "21" ]]; then + export JAVA_OPTS=--enable-preview + fi + sbt test bootstrapProto proto/test diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..1cfe2f7 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,57 @@ +name: PerfIO Release + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + workflow_dispatch: + +permissions: + contents: read + +defaults: + run: + shell: bash + +jobs: + build: + runs-on: ubuntu-latest + name: Release + steps: + - uses: actions/checkout@v4 + - name: Set up Java + uses: actions/setup-java@v4 + with: + java-version: | + 21 + 23 + distribution: 'temurin' + cache: 'sbt' + - name: Set up sbt + uses: sbt/setup-sbt@v1 + - name: Set up GPG keys + env: + SIGNING_KEY_PRIVATE: ${{ secrets.SIGNING_KEY_PRIVATE }} + SIGNING_KEY_PUBLIC: ${{ secrets.SIGNING_KEY_PUBLIC }} + run: | + echo "$SIGNING_KEY_PUBLIC" | gpg --import + mkdir -p ~/.gnupg/private-keys-v1.d # workaround for a gpg bug + echo "$SIGNING_KEY_PRIVATE" | gpg --passphrase=${{ secrets.SIGNING_KEY_PASSPHRASE }} --pinentry-mode=loopback --batch --import + - name: Publish + env: + PGP_PASSPHRASE: ${{ secrets.SIGNING_KEY_PASSPHRASE }} + SONATYPE_USER: ${{ secrets.SONATYPE_USER }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + run: | + # Publish binaries with Java 21 (because we can't use --enable-preview for 21 from 23) + JAVA_HOME=$JAVA_HOME_21_X64 JAVA_OPTS=--enable-preview sbt \ + "set core/Compile/packageDoc/publishArtifact := false" \ + core/publishSigned + # Publish javadoc with Java 23 (because we need Markdown support) + JAVA_HOME=$JAVA_HOME_23_X64 sbt \ + "set core/Compile/packageSrc/publishArtifact := false" \ + "set core/Compile/packageBin/publishArtifact := false" \ + core/publishSigned + ls -lR target/sonatype-staging + JAVA_HOME=$JAVA_HOME_23_X64 sbt sonatypeCentralUpload diff --git a/build.sbt b/build.sbt index b804933..d71cb1d 100644 --- a/build.sbt +++ b/build.sbt @@ -2,33 +2,60 @@ import java.nio.file.{Files, Path} import scala.jdk.CollectionConverters._ val PROTOBUF_HOME = sys.env.getOrElse("PROTOBUF_HOME", s"${sys.props("user.home")}/protobuf") +val protobufVersion = "4.29.0-RC2" -Global / organization := "com.novocode" - -Global / version := "0.1-SNAPSHOT" - -//cancelable in Global := false - -val release = "22" +val javaVersion = sys.props("java.specification.version").toInt +val release = if(javaVersion >= 22) 22 else javaVersion val runtimeOpts = Seq( "--add-modules", "jdk.incubator.vector", "--add-opens", "java.base/jdk.internal.misc=ALL-UNNAMED", "--add-opens", "java.base/java.lang=ALL-UNNAMED", -) +) ++ (if(release >= 22) Nil else Seq( + "--enable-preview", +)) + val compileOpts = Seq( "--add-modules", "jdk.incubator.vector", - "--release", release, -) +) ++ (if(release >= 22) Seq( + "--release", release.toString, +) else Seq( + "--release", javaVersion.toString, + "--enable-preview", +)) javaOptions in Global ++= runtimeOpts javacOptions in Global ++= compileOpts -scalacOptions in Global ++= Seq("-java-output-version", release) +scalacOptions in Global ++= Seq("-java-output-version", release.toString) // javaOptions in Global += "-Djmh.blackhole.autoDetect=false" scalacOptions ++= Seq("-feature") +val baseVersion = "0.1.0" +val releaseVersion: String = { + import scala.sys.process._ + lazy val hash = "git rev-parse HEAD".!!.substring(0, 10) + sys.env.get("GITHUB_REF") match { + case Some(ref) if ref.startsWith("refs/tags/v") && ref.length >= 14 => ref.substring(11) + case Some(_) => s"$baseVersion-$hash" + case None => s"$baseVersion-$hash-SNAPSHOT" + } +} + +ThisBuild / publishTo := sonatypePublishToBundle.value +ThisBuild / sonatypeCredentialHost := xerial.sbt.Sonatype.sonatypeCentralHost +ThisBuild / credentials += + Credentials("Sonatype Nexus Repository Manager", (ThisBuild / sonatypeCredentialHost).value, + sys.env.getOrElse("SONATYPE_USER", ""), sys.env.getOrElse("SONATYPE_PASSWORD", "")) +ThisBuild / versionScheme := Some("semver-spec") +ThisBuild / version := releaseVersion +ThisBuild / organization := "com.novocode" +ThisBuild / licenses += ("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0.html")) +ThisBuild / homepage := Some(url("http://github.com/szeiger/perfio/")) +ThisBuild / scmInfo := Some(ScmInfo(url("https://github.com/szeiger/perfio"), "scm:git@github.com:szeiger/perfio.git")) +ThisBuild / developers := List(Developer("szeiger", "Stefan Zeiger", "szeiger@novocode.com", url("http://szeiger.de"))) + ThisBuild / Test / fork := true ThisBuild / run / fork := true ThisBuild / run / connectInput := true @@ -98,7 +125,7 @@ lazy val protoRuntime = (project in file("proto-runtime")) lazy val proto = (project in file("proto")) .dependsOn(protoRuntime, scalaApi) .settings( - libraryDependencies += "com.google.protobuf" % "protobuf-java" % "4.29.0-RC2" % "test", + libraryDependencies += "com.google.protobuf" % "protobuf-java" % "4.29.0-RC3" % "test", libraryDependencies += "com.github.sbt" % "junit-interface" % "0.13.2" % "test", testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-v"), name := "perfio-proto", @@ -124,7 +151,7 @@ lazy val protoBench = (project in file("proto-bench")) .enablePlugins(JmhPlugin) .settings( scalacOptions ++= Seq("-feature", "-opt:l:inline"), - libraryDependencies += "com.google.protobuf" % "protobuf-java" % "4.29.0-RC2", + libraryDependencies += "com.google.protobuf" % "protobuf-java" % protobufVersion, name := "perfio-proto-bench", publish / skip := true, ) diff --git a/project/plugins.sbt b/project/plugins.sbt index 514aeb2..f1fcbb1 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1 +1,3 @@ addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.6") +addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.3.0") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.12.2") diff --git a/proto/protoc-gen-perfio b/proto/protoc-gen-perfio old mode 100644 new mode 100755 index 6c0ad85..b3134c6 --- a/proto/protoc-gen-perfio +++ b/proto/protoc-gen-perfio @@ -1,3 +1,3 @@ #!/bin/bash -java -Xlog:disable -XX:+DisplayVMOutputToStderr -cp "$PERFIO_CLASSPATH" perfio.proto.Main +java $JAVA_OPTS -Xlog:disable -XX:+DisplayVMOutputToStderr -cp "$PERFIO_CLASSPATH" perfio.proto.Main diff --git a/test/src/test/scala/perfio/AbstractLineTokenizerSpec.scala b/test/src/test/scala/perfio/AbstractLineTokenizerSpec.scala index 3a6123d..bc2f73d 100644 --- a/test/src/test/scala/perfio/AbstractLineTokenizerSpec.scala +++ b/test/src/test/scala/perfio/AbstractLineTokenizerSpec.scala @@ -82,11 +82,11 @@ abstract class SimpleLineTokenizerSpec[T] extends AbstractLineTokenizerSpec[T]: object HeapScalarLineTokenizerSpec extends SimpleLineTokenizerSpec[Int]: val base: List[(String, Int, Int, Int, Int)] = List( - ("small.aligned", 64, 64, 4096, 2000), - ("large.aligned", 128, 128, 64, 2000), - ("small.unligned", 0, 63, 4096, 2000), - ("large.unaligned", 65, 127, 64, 2000), - ("mixed", 0, 513, 128, 10000), + ("small.aligned", 64, 64, 4096, 200), + ("large.aligned", 128, 128, 64, 200), + ("small.unligned", 0, 63, 4096, 200), + ("large.unaligned", 65, 127, 64, 200), + ("mixed", 0, 513, 128, 1000), ) def createBI(s: String, cs: Charset, ib: Int): BufferedInput = @@ -96,19 +96,19 @@ object HeapScalarLineTokenizerSpec extends SimpleLineTokenizerSpec[Int]: object HeapVectorizedLineTokenizerSpec extends SimpleLineTokenizerSpec[(Int, Int)]: val base: List[(String, Int, Int, (Int, Int), Int)] = List( - ("small.aligned", 64, 64, (4096, Int.MaxValue), 2000), - ("large.aligned", 128, 128, (64, Int.MaxValue), 2000), - ("small.unaligned", 0, 63, (4096, Int.MaxValue), 2000), - ("large.unaligned", 65, 127, (64, Int.MaxValue), 2000), - ("small.aligned.limited1", 64, 64, (4096, 1), 2000), - ("large.aligned.limited1", 128, 128, (64, 1), 2000), - ("small.unaligned.limited1", 0, 63, (4096, 1), 2000), - ("large.unaligned.limited1", 65, 127, (64, 1), 2000), - ("small.aligned.limited16", 64, 64, (4096, 16), 2000), - ("large.aligned.limited16", 128, 128, (64, 16), 2000), - ("small.unaligned.limited16", 0, 63, (4096, 16), 2000), - ("large.unaligned.limited16", 65, 127, (64, 16), 2000), - ("mixed", 0, 513, (128, Int.MaxValue), 10000), + ("small.aligned", 64, 64, (4096, Int.MaxValue), 200), + ("large.aligned", 128, 128, (64, Int.MaxValue), 200), + ("small.unaligned", 0, 63, (4096, Int.MaxValue), 200), + ("large.unaligned", 65, 127, (64, Int.MaxValue), 200), + ("small.aligned.limited1", 64, 64, (4096, 1), 200), + ("large.aligned.limited1", 128, 128, (64, 1), 200), + ("small.unaligned.limited1", 0, 63, (4096, 1), 200), + ("large.unaligned.limited1", 65, 127, (64, 1), 200), + ("small.aligned.limited16", 64, 64, (4096, 16), 200), + ("large.aligned.limited16", 128, 128, (64, 16), 200), + ("small.unaligned.limited16", 0, 63, (4096, 16), 200), + ("large.unaligned.limited16", 65, 127, (64, 16), 200), + ("mixed", 0, 513, (128, Int.MaxValue), 1000), ) def createBI(s: String, cs: Charset, params: (Int, Int)): BufferedInput = @@ -119,14 +119,14 @@ object HeapVectorizedLineTokenizerSpec extends SimpleLineTokenizerSpec[(Int, Int abstract class FromArraySpec extends AbstractLineTokenizerSpec[(Int, Int)]: val base: List[(String, Int, Int, (Int, Int), Int)] = List( - ("small.aligned", 64, 64, (0, 0), 2000), - ("large.aligned", 128, 128, (0, 0), 2000), - ("small.unligned", 0, 63, (0, 0), 2000), - ("large.unaligned", 65, 127, (0, 0), 2000), - ("padRight", 0, 65, (0, 33), 2000), - ("padLeft", 0, 65, (33, 0), 2000), - ("padBoth", 0, 65, (33, 33), 2000), - ("mixed", 0, 513, (0, 0), 2000), + ("small.aligned", 64, 64, (0, 0), 200), + ("large.aligned", 128, 128, (0, 0), 200), + ("small.unligned", 0, 63, (0, 0), 200), + ("large.unaligned", 65, 127, (0, 0), 200), + ("padRight", 0, 65, (0, 33), 200), + ("padLeft", 0, 65, (33, 0), 200), + ("padBoth", 0, 65, (33, 33), 200), + ("mixed", 0, 513, (0, 0), 200), ) def createProp(min: Int, max: Int, cs: Charset, split: Boolean, params: (Int, Int)): Property = @@ -150,11 +150,11 @@ abstract class FromArraySpec extends AbstractLineTokenizerSpec[(Int, Int)]: abstract class ForeignSpec extends FromArraySpec: override val base: List[(String, Int, Int, (Int, Int), Int)] = List( - ("small.aligned", 64, 64, (0, 0), 2000), - ("large.aligned", 128, 128, (0, 0), 2000), - ("small.unligned", 0, 63, (0, 0), 2000), - ("large.unaligned", 65, 127, (0, 0), 2000), - ("mixed", 0, 513, (0, 0), 10000), + ("small.aligned", 64, 64, (0, 0), 200), + ("large.aligned", 128, 128, (0, 0), 200), + ("small.unligned", 0, 63, (0, 0), 200), + ("large.unaligned", 65, 127, (0, 0), 200), + ("mixed", 0, 513, (0, 0), 1000), )