From 9bc0eb5cf8aabe9aedba71e5fefe13e0f02a4172 Mon Sep 17 00:00:00 2001 From: austek Date: Wed, 21 Aug 2024 13:59:34 +0100 Subject: [PATCH] Add Windows to CI/CD --- .github/workflows/ci.yml | 74 +++++++++++++++---- CODEOWNERS | 6 -- build.sbt | 41 +++++++--- docker-compose.yml | 6 +- github-actions.sbt | 51 +++++++++---- .../src/main/resources/avro/order-v1.avsc | 4 +- .../pulsar/avro/OrderConsumerController.scala | 1 - .../pulsar/avro/OrderV1ConsumerTest.java | 16 +++- .../pulsar/avro/PactPulsarConsumerTest.java | 16 +++- .../src/main/resources/application.conf | 2 +- .../pulsar/avro/PactPulsarProducerTest.java | 4 +- .../plugin/avro/PactAvroPluginServer.scala | 2 +- .../avro/implicits/SchemaTypeImplicits.scala | 2 +- .../plugin/avro/PactPluginServiceTest.scala | 32 ++++---- project/BuildSettings.scala | 5 +- project/Dependencies.scala | 11 +-- project/builds.sbt | 2 +- project/plugins.sbt | 2 +- scripts/pact-publish.sh | 8 +- 19 files changed, 192 insertions(+), 93 deletions(-) delete mode 100644 CODEOWNERS diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae78441..6782990 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,18 +15,35 @@ on: tags: [v*] env: + PACT_BROKER_BASE_URL: 'https://test.pactflow.io' + PACT_BROKER_USERNAME: dXfltyFMgNOFZAxr8io9wJ37iUpY42M + PACT_BROKER_PASSWORD: O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} jobs: build: name: Build and Test strategy: + fail-fast: false matrix: - os: [ubuntu-latest] - scala: [3.3.4-RC1] + os: [ubuntu-latest, macos-latest, windows-2019] + scala: [3.5.0] java: [zulu@17, zulu@20] runs-on: ${{ matrix.os }} steps: + - name: Ignore line ending differences in git + if: contains(runner.os, 'windows') + shell: bash + run: git config --global core.autocrlf false + + - name: Configure pagefile for Windows + if: contains(runner.os, 'windows') + uses: al-cheb/configure-pagefile-action@v1.4 + with: + minimum-size: 2GB + maximum-size: 8GB + disk-root: 'C:' + - name: Checkout current branch (full) uses: actions/checkout@v4 with: @@ -52,28 +69,45 @@ jobs: uses: sbt/setup-sbt@v1 - name: Check that workflows are up to date + shell: bash run: sbt '++ ${{ matrix.scala }}' githubWorkflowCheck - - name: Start containers - run: docker compose -f docker-compose.yml up -d + - name: Set outputs + id: vars + shell: bash + run: | + echo "sha_short=$(git rev-parse --short ${{ github.sha }})" >> $GITHUB_OUTPUT + echo "git_tag=$(git describe --tags)" >> $GITHUB_OUTPUT + + - name: Pactflow Setup + uses: pactflow/actions@main - name: Build project + shell: bash run: sbt '++ ${{ matrix.scala }}' compile scalafmtCheckAll javafmtCheckAll plugin/test - name: Test Consumer + shell: bash run: sbt '++ ${{ matrix.scala }}' consumer/test - - name: Upload Consumer Pact - run: ./scripts/pact-publish.sh + - name: Pact publish Windows + if: contains(runner.os, 'windows') + shell: bash + run: pact-broker.bat publish "modules/examples/consumer/target/pacts" --consumer-app-version=${{ steps.vars.outputs.git_tag }}-${{ runner.os }} --tag=${{ steps.vars.outputs.git_tag }}-${{ runner.os }} + + - name: Pact publish *nix + if: '!contains(runner.os, ''windows'')' + shell: bash + run: pact-broker publish "modules/examples/consumer/target/pacts" --consumer-app-version=${{ steps.vars.outputs.git_tag }}-${{ runner.os }} --tag=${{ steps.vars.outputs.git_tag }}-${{ runner.os }} - name: Test Provider + env: + PACT_BROKER_TAG: ${{ steps.vars.outputs.git_tag }}-${{ runner.os }} + shell: bash run: sbt '++ ${{ matrix.scala }}' provider/test - - name: Stop containers - if: always() - run: docker compose -f docker-compose.yml down - - name: Compress target directories + shell: bash run: tar cf targets.tar target modules/plugin/target modules/examples/provider/target modules/examples/consumer/target project/target - name: Upload target directories @@ -89,10 +123,22 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [3.3.4-RC1] + scala: [3.5.0] java: [zulu@17] runs-on: ${{ matrix.os }} steps: + - name: Ignore line ending differences in git + if: contains(runner.os, 'windows') + run: git config --global core.autocrlf false + + - name: Configure pagefile for Windows + if: contains(runner.os, 'windows') + uses: al-cheb/configure-pagefile-action@v1.4 + with: + minimum-size: 2GB + maximum-size: 8GB + disk-root: 'C:' + - name: Checkout current branch (full) uses: actions/checkout@v4 with: @@ -117,12 +163,12 @@ jobs: - name: Setup sbt uses: sbt/setup-sbt@v1 - - name: Download target directories (3.3.4-RC1) + - name: Download target directories (3.5.0) uses: actions/download-artifact@v4 with: - name: target-${{ matrix.os }}-3.3.4-RC1-${{ matrix.java }} + name: target-${{ matrix.os }}-3.5.0-${{ matrix.java }} - - name: Inflate target directories (3.3.4-RC1) + - name: Inflate target directories (3.5.0) run: | tar xf targets.tar rm targets.tar diff --git a/CODEOWNERS b/CODEOWNERS deleted file mode 100644 index 8778caa..0000000 --- a/CODEOWNERS +++ /dev/null @@ -1,6 +0,0 @@ -# This file defines individuals or teams that are responsible for code in the repository. -# -# https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners -# - -* ali.ustek@collibra.com diff --git a/build.sbt b/build.sbt index 65a5d0f..07d9330 100644 --- a/build.sbt +++ b/build.sbt @@ -4,20 +4,26 @@ import PublishSettings.* import TestEnvironment.* ThisBuild / scalaVersion := scalaV +//ThisBuild / conflictManager := ConflictManager.strict -lazy val plugin = project - .in(file("modules/plugin")) +lazy val pactOptions: Seq[Tests.Argument] = Seq( + Some(sys.env.getOrElse("PACT_BROKER_BASE_URL", "http://localhost:9292")).map(s => s"-Dpactbroker.url=$s"), + sys.env.get("PACT_BROKER_USERNAME").map(s => s"-Dpactbroker.auth.username=$s"), + sys.env.get("PACT_BROKER_PASSWORD").map(s => s"-Dpactbroker.auth.password=$s"), + sys.env.get("PACT_BROKER_TAG").map(s => s"-Dpactbroker.consumerversionselectors.tags=$s"), +).flatten.map(o => Tests.Argument(jupiterTestFramework, o)) + +lazy val plugin = moduleProject("plugin", "plugin") .enablePlugins( GitHubPagesPlugin, - GitVersioning, JavaAppPackaging, // https://sbt-native-packager.readthedocs.io/en/stable/recipes/longclasspath.html#long-classpaths LauncherJarPlugin ) .settings( + git.useGitDescribe := true, name := "plugin", maintainer := "aliustek@gmail.com", - basicSettings, publishSettings, testEnvSettings, gitHubPagesOrgName := "austek", @@ -28,29 +34,26 @@ lazy val plugin = project scalapb.gen() -> (Compile / sourceManaged).value / "scalapb" ), libraryDependencies ++= - Dependencies.compile(apacheAvro, auPactMatchers, logback, pactCore, scalaLogging, scalaPBRuntime) ++ + Dependencies.compile(apacheAvro, auPactMatchers, logback, scalaLogging, scalaPBRuntime) ++ Dependencies.protobuf(scalaPB) ++ Dependencies.test(scalaTest), dependencyOverrides ++= Seq(grpcApi, grpcCore, grpcNetty) ) lazy val pluginRef = LocalProject("plugin") -lazy val provider = project - .in(file("modules/examples/provider")) +lazy val provider = moduleProject("provider", "examples/provider") .settings( - basicSettings, Test / sbt.Keys.test := (Test / sbt.Keys.test).dependsOn(pluginRef / buildTestPluginDir).value, Test / envVars := Map("PACT_PLUGIN_DIR" -> ((pluginRef / target).value / "plugin").absolutePath), + testOptions ++= pactOptions, libraryDependencies ++= Dependencies.compile(avroCompiler, logback, pulsar4sCore, pulsar4sAvro, scalacheck) ++ Dependencies.test(assertJCore, jUnitInterface, pactProviderJunit), publish / skip := false ) -lazy val consumer = project - .in(file("modules/examples/consumer")) +lazy val consumer = moduleProject("consumer", "examples/consumer") .settings( - basicSettings, Compile / avroSource := (Compile / resourceDirectory).value / "avro", Test / sbt.Keys.test := (Test / sbt.Keys.test).dependsOn(pluginRef / buildTestPluginDir).value, Test / envVars := Map("PACT_PLUGIN_DIR" -> ((pluginRef / target).value / "plugin").absolutePath), @@ -70,3 +73,19 @@ lazy val `pact-avro-plugin` = (project in file(".")) basicSettings, publish / skip := false ) + +def moduleProject(name: String, path: String): Project = { + Project(name, file(s"modules/$path")) + .enablePlugins(GitVersioning, ScalafmtPlugin) + .settings( + basicSettings, + moduleName := name, + git.useGitDescribe := true, + git.gitTagToVersionNumber := { tag: String => + if(tag matches "v[0-9].*") { + Some(tag.drop(1).replaceAll("-[0-9]+-.+", "")) + } + else None + } + ) +} diff --git a/docker-compose.yml b/docker-compose.yml index 15c6420..d51584e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,7 @@ services: postgres: - image: postgres:15.2-alpine + image: postgres:16.4-alpine + platform: linux/amd64 healthcheck: test: psql postgres --command "select 1" -U postgres environment: @@ -9,7 +10,8 @@ services: POSTGRES_DB: postgres pact-broker: - image: pactfoundation/pact-broker:2.113.0-pactbroker2.107.1-multi + image: pactfoundation/pact-broker + platform: linux/amd64 ports: - "9292:9292" depends_on: diff --git a/github-actions.sbt b/github-actions.sbt index 3a5d8c6..fcfc62a 100644 --- a/github-actions.sbt +++ b/github-actions.sbt @@ -1,8 +1,6 @@ // sbt-github-actions -// Add windows-latest when https://github.com/sbt/sbt/issues/7082 is resolved -// Add macos-latest when step to install docker on it is done -ThisBuild / githubWorkflowOSes := Seq("ubuntu-latest") +ThisBuild / githubWorkflowOSes := Seq("ubuntu-latest", "macos-latest", "windows-2019") ThisBuild / githubWorkflowJavaVersions := Seq( JavaSpec.zulu("17"), JavaSpec.zulu("20") @@ -10,10 +8,25 @@ ThisBuild / githubWorkflowJavaVersions := Seq( ThisBuild / githubWorkflowTargetBranches := Seq("main") ThisBuild / githubWorkflowTargetTags := Seq("v*") +ThisBuild / githubWorkflowEnv := Map( + "PACT_BROKER_BASE_URL" -> "https://test.pactflow.io", + "PACT_BROKER_USERNAME" -> "dXfltyFMgNOFZAxr8io9wJ37iUpY42M", + "PACT_BROKER_PASSWORD" -> "O5AIZWxelWbLvqMd8PkAVycBJh2Psyg1", + "GITHUB_TOKEN" -> "${{ secrets.GITHUB_TOKEN }}" +) +ThisBuild / githubWorkflowBuildMatrixFailFast := Some(false) ThisBuild / githubWorkflowBuild := Seq( WorkflowStep.Run( - name = Some("Start containers"), - commands = List("docker compose -f docker-compose.yml up -d") + name = Some("Set outputs"), + id = Some("vars"), + commands = List( + """echo "sha_short=$(git rev-parse --short ${{ github.sha }})" >> $GITHUB_OUTPUT""", + """echo "git_tag=$(git describe --tags)" >> $GITHUB_OUTPUT""" + ) + ), + WorkflowStep.Use( + UseRef.Public("pactflow", "actions", "main"), + name = Some("Pactflow Setup") ), WorkflowStep.Sbt( name = Some("Build project"), @@ -24,17 +37,29 @@ ThisBuild / githubWorkflowBuild := Seq( commands = List("consumer/test") ), WorkflowStep.Run( - name = Some("Upload Consumer Pact"), - commands = List("./scripts/pact-publish.sh") + name = Some("Pact publish Windows"), + commands = List("""pact-broker.bat publish + | "modules/examples/consumer/target/pacts" + | --consumer-app-version=${{ steps.vars.outputs.git_tag }}-${{ runner.os }} + | --tag=${{ steps.vars.outputs.git_tag }}-${{ runner.os }} + | """.stripMargin.replaceAll("\n", "")), + cond = Some("contains(runner.os, 'windows')") + ), + WorkflowStep.Run( + name = Some("Pact publish *nix"), + commands = List("""pact-broker publish + | "modules/examples/consumer/target/pacts" + | --consumer-app-version=${{ steps.vars.outputs.git_tag }}-${{ runner.os }} + | --tag=${{ steps.vars.outputs.git_tag }}-${{ runner.os }} + | """.stripMargin.replaceAll("\n", "")), + cond = Some("!contains(runner.os, 'windows')") ), WorkflowStep.Sbt( name = Some("Test Provider"), - commands = List("provider/test") - ), - WorkflowStep.Run( - cond = Some("always()"), - name = Some("Stop containers"), - commands = List("docker compose -f docker-compose.yml down") + commands = List("provider/test"), + env = Map( + "PACT_BROKER_TAG" -> "${{ steps.vars.outputs.git_tag }}-${{ runner.os }}", + ) ) ) diff --git a/modules/examples/consumer/src/main/resources/avro/order-v1.avsc b/modules/examples/consumer/src/main/resources/avro/order-v1.avsc index 47a47fa..b43208b 100644 --- a/modules/examples/consumer/src/main/resources/avro/order-v1.avsc +++ b/modules/examples/consumer/src/main/resources/avro/order-v1.avsc @@ -2,7 +2,7 @@ { "type": "record", "name": "OrderNewEvent", - "namespace": "com.collibra.event.client.examples.showcase.schema", + "namespace": "com.github.austek.event.client.examples.showcase.schema", "fields": [ { "name": "createdOn", @@ -23,7 +23,7 @@ "items": { "type": "record", "name": "OrderItem", - "namespace": "com.collibra.event.client.examples.showcase.domain", + "namespace": "com.github.austek.event.client.examples.showcase.domain", "fields": [ { "name": "itemId", diff --git a/modules/examples/consumer/src/main/scala/com/github/austek/example/pulsar/avro/OrderConsumerController.scala b/modules/examples/consumer/src/main/scala/com/github/austek/example/pulsar/avro/OrderConsumerController.scala index 8df3494..a51b044 100644 --- a/modules/examples/consumer/src/main/scala/com/github/austek/example/pulsar/avro/OrderConsumerController.scala +++ b/modules/examples/consumer/src/main/scala/com/github/austek/example/pulsar/avro/OrderConsumerController.scala @@ -42,5 +42,4 @@ class OrderConsumerController(config: ConsumerAppConfig) extends StrictLogging { processOrderMessages(totalMessageCount + 1, f) } } - } diff --git a/modules/examples/consumer/src/test/java/com/github/austek/example/pulsar/avro/OrderV1ConsumerTest.java b/modules/examples/consumer/src/test/java/com/github/austek/example/pulsar/avro/OrderV1ConsumerTest.java index db04164..4664083 100644 --- a/modules/examples/consumer/src/test/java/com/github/austek/example/pulsar/avro/OrderV1ConsumerTest.java +++ b/modules/examples/consumer/src/test/java/com/github/austek/example/pulsar/avro/OrderV1ConsumerTest.java @@ -17,9 +17,11 @@ import au.com.dius.pact.core.model.matchingrules.MatchingRuleGroup; import au.com.dius.pact.core.model.matchingrules.MatchingRulesImpl; import au.com.dius.pact.core.model.v4.MessageContents; -import com.collibra.event.client.examples.showcase.domain.OrderItem; -import com.collibra.event.client.examples.showcase.schema.OrderNewEvent; +import com.github.austek.event.client.examples.showcase.domain.OrderItem; +import com.github.austek.event.client.examples.showcase.schema.OrderNewEvent; import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Paths; import java.util.List; import java.util.Map; import java.util.Objects; @@ -32,8 +34,14 @@ providerType = ProviderType.ASYNCH, providerName = "OrderTopicV1") class OrderV1ConsumerTest { - private final String schemasPath = - Objects.requireNonNull(getClass().getResource("/avro/order-v1.avsc")).getPath(); + private final String schemasPath; + + OrderV1ConsumerTest() throws URISyntaxException { + schemasPath = + Paths.get(Objects.requireNonNull(getClass().getResource("/avro/order-v1.avsc")).toURI()) + .toFile() + .getAbsolutePath(); + } @Pact(consumer = "OrderTopicConsumer") V4Pact configureRecordWithDependantRecord(PactBuilder builder) { diff --git a/modules/examples/consumer/src/test/java/com/github/austek/example/pulsar/avro/PactPulsarConsumerTest.java b/modules/examples/consumer/src/test/java/com/github/austek/example/pulsar/avro/PactPulsarConsumerTest.java index 4be3b6c..03673ed 100644 --- a/modules/examples/consumer/src/test/java/com/github/austek/example/pulsar/avro/PactPulsarConsumerTest.java +++ b/modules/examples/consumer/src/test/java/com/github/austek/example/pulsar/avro/PactPulsarConsumerTest.java @@ -22,6 +22,8 @@ import com.github.austek.example.Status; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Paths; import java.util.*; import org.apache.avro.io.BinaryDecoder; import org.apache.avro.io.DecoderFactory; @@ -31,15 +33,21 @@ @ExtendWith(PactConsumerTestExt.class) @PactTestFor( - providerName = "order-provider", + providerName = "avro-plugin-provider", providerType = ProviderType.ASYNCH, pactVersion = PactSpecVersion.V4) class PactPulsarConsumerTest { - private final String schemasPath = - Objects.requireNonNull(getClass().getResource("/avro/orders.avsc")).getPath(); + private final String schemasPath; private final OrderService orderService = new OrderService(); - @Pact(consumer = "avro-consumer") + PactPulsarConsumerTest() throws URISyntaxException { + schemasPath = + Paths.get(Objects.requireNonNull(getClass().getResource("/avro/orders.avsc")).toURI()) + .toFile() + .getAbsolutePath(); + } + + @Pact(consumer = "avro-plugin-consumer") V4Pact configureRecordWithDependantRecord(PactBuilder builder) { // tag::configuration[] return builder diff --git a/modules/examples/provider/src/main/resources/application.conf b/modules/examples/provider/src/main/resources/application.conf index 9ca3094..5d8cef5 100644 --- a/modules/examples/provider/src/main/resources/application.conf +++ b/modules/examples/provider/src/main/resources/application.conf @@ -2,7 +2,7 @@ pulsar-url: "pulsar://localhost:6650" order-producer { topic: "orders" - producer-name: "order-provider" + producer-name: "avro-plugin-provider" enable-batching: true block-if-queue-full: true number-of-orders: 100 diff --git a/modules/examples/provider/src/test/java/com/github/austek/example/pulsar/avro/PactPulsarProducerTest.java b/modules/examples/provider/src/test/java/com/github/austek/example/pulsar/avro/PactPulsarProducerTest.java index 5c1b467..f847b6e 100644 --- a/modules/examples/provider/src/test/java/com/github/austek/example/pulsar/avro/PactPulsarProducerTest.java +++ b/modules/examples/provider/src/test/java/com/github/austek/example/pulsar/avro/PactPulsarProducerTest.java @@ -24,8 +24,8 @@ import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; -@Provider("order-provider") -@PactBroker(url = "http://localhost:9292") +@Provider("avro-plugin-provider") +@PactBroker class PactPulsarProducerTest { private static final String AVRO_CONTENT_TYPE = "avro/binary; record=Order"; private static final String KEY_CONTENT_TYPE = "contentType"; diff --git a/modules/plugin/src/main/scala/com/github/austek/plugin/avro/PactAvroPluginServer.scala b/modules/plugin/src/main/scala/com/github/austek/plugin/avro/PactAvroPluginServer.scala index 7a64159..553c5f6 100644 --- a/modules/plugin/src/main/scala/com/github/austek/plugin/avro/PactAvroPluginServer.scala +++ b/modules/plugin/src/main/scala/com/github/austek/plugin/avro/PactAvroPluginServer.scala @@ -21,7 +21,7 @@ class PactAvroPluginServer( private val serverKey: UUID = randomUUID() ) { self => - private[this] var server: Option[Server] = None + private var server: Option[Server] = None private def start(): Unit = { server = Option( diff --git a/modules/plugin/src/main/scala/com/github/austek/plugin/avro/implicits/SchemaTypeImplicits.scala b/modules/plugin/src/main/scala/com/github/austek/plugin/avro/implicits/SchemaTypeImplicits.scala index 9f7bdb2..55c45dc 100644 --- a/modules/plugin/src/main/scala/com/github/austek/plugin/avro/implicits/SchemaTypeImplicits.scala +++ b/modules/plugin/src/main/scala/com/github/austek/plugin/avro/implicits/SchemaTypeImplicits.scala @@ -18,7 +18,7 @@ object SchemaTypeImplicits { case ENUM => classOf[String] case FIXED => classOf[Array[Byte]] case ARRAY => classOf[List[?]] - case MAP => classOf[Map[_, _]] + case MAP => classOf[Map[?, ?]] case RECORD => classOf[GenericRecord] case _ => classOf[Object] } diff --git a/modules/plugin/src/test/scala/com/github/austek/plugin/avro/PactPluginServiceTest.scala b/modules/plugin/src/test/scala/com/github/austek/plugin/avro/PactPluginServiceTest.scala index bafee92..fa588eb 100644 --- a/modules/plugin/src/test/scala/com/github/austek/plugin/avro/PactPluginServiceTest.scala +++ b/modules/plugin/src/test/scala/com/github/austek/plugin/avro/PactPluginServiceTest.scala @@ -1,18 +1,18 @@ package com.github.austek.plugin.avro -import Avro.* -import com.github.austek.plugin.avro.utils.StringUtils.* +import com.github.austek.plugin.avro.Avro.* import com.github.austek.plugin.avro.utils.AvroUtils +import com.github.austek.plugin.avro.utils.StringUtils.* import com.google.protobuf.struct.Value.Kind.* -import com.google.protobuf.struct.{ListValue => StructListValue, Struct, Value} -import io.pact.plugin.pact_plugin.Body.ContentTypeHint.BINARY +import com.google.protobuf.struct.{ListValue as StructListValue, Struct, Value} import io.pact.plugin.pact_plugin.* +import io.pact.plugin.pact_plugin.Body.ContentTypeHint.BINARY import org.scalatest.concurrent.ScalaFutures import org.scalatest.flatspec.AsyncFlatSpecLike import org.scalatest.matchers.should.Matchers import org.scalatest.{EitherValues, OptionValues} -import java.nio.file.Path +import java.nio.file.Paths import scala.jdk.CollectionConverters.* class PactPluginServiceTest extends AsyncFlatSpecLike with Matchers with OptionValues with ScalaFutures with EitherValues { @@ -78,7 +78,7 @@ class PactPluginServiceTest extends AsyncFlatSpecLike with Matchers with OptionV } it should "require a valid avro schema file" in { - val schemasPath = getClass.getResource("/invalid.avsc").getPath + val schemasPath = Paths.get(getClass.getResource("/invalid.avsc").toURI).toFile.getAbsolutePath new PactAvroPluginService() .configureInteraction( ConfigureInteractionRequest( @@ -99,7 +99,7 @@ class PactPluginServiceTest extends AsyncFlatSpecLike with Matchers with OptionV } it should "require record-name to be defined" in { - val schemasPath = getClass.getResource("/schemas.avsc").getPath + val schemasPath = Paths.get(getClass.getResource("/schemas.avsc").toURI).toFile.getAbsolutePath new PactAvroPluginService() .configureInteraction( ConfigureInteractionRequest( @@ -119,7 +119,8 @@ class PactPluginServiceTest extends AsyncFlatSpecLike with Matchers with OptionV } it should "return Interaction Response for a single record" in { - val url = getClass.getResource("/item.avsc") + val schemaFile = Paths.get(getClass.getResource("/item.avsc").toURI).toFile + val schemaPath = schemaFile.getAbsolutePath val eventualResponse = new PactAvroPluginService() .configureInteraction( ConfigureInteractionRequest( @@ -127,7 +128,7 @@ class PactPluginServiceTest extends AsyncFlatSpecLike with Matchers with OptionV Some( Struct( Map( - "pact:avro" -> Value(StringValue(url.getPath)), + "pact:avro" -> Value(StringValue(schemaPath)), "pact:record-name" -> Value(StringValue("Item")), "pact:content-type" -> Value(StringValue("avro/binary")), "name" -> Value(StringValue("notEmpty('Item-41')")), @@ -144,7 +145,7 @@ class PactPluginServiceTest extends AsyncFlatSpecLike with Matchers with OptionV content.contentTypeHint shouldBe Body.ContentTypeHint.BINARY content.contentType shouldBe "avro/binary;record=Item" - val schema = AvroUtils.parseSchema(Path.of(url.getPath).toFile).value + val schema = AvroUtils.parseSchema(schemaFile).value val bytes = AvroRecord( "$".toPactPath, @@ -160,7 +161,8 @@ class PactPluginServiceTest extends AsyncFlatSpecLike with Matchers with OptionV } it should "return Interaction Response for a record with other record in field" in { - val url = getClass.getResource("/schemas.avsc") + val schemaFile = Paths.get(getClass.getResource("/schemas.avsc").toURI).toFile + val schemaPath = schemaFile.getAbsolutePath val eventualResponse = new PactAvroPluginService() .configureInteraction( ConfigureInteractionRequest( @@ -168,7 +170,7 @@ class PactPluginServiceTest extends AsyncFlatSpecLike with Matchers with OptionV Some( Struct( Map( - "pact:avro" -> Value(StringValue(url.getPath)), + "pact:avro" -> Value(StringValue(schemaPath)), "pact:record-name" -> Value(StringValue("Complex")), "pact:content-type" -> Value(StringValue("avro/binary")), "id" -> Value(StringValue("notEmpty('100')")), @@ -220,7 +222,7 @@ class PactPluginServiceTest extends AsyncFlatSpecLike with Matchers with OptionV val content = interaction.contents.value content.contentTypeHint shouldBe Body.ContentTypeHint.BINARY content.contentType shouldBe "avro/binary;record=Complex" - val schema = AvroUtils.parseSchema(Path.of(url.getPath).toFile).value.getTypes.asScala.find(_.getName == "Complex").get + val schema = AvroUtils.parseSchema(schemaFile).value.getTypes.asScala.find(_.getName == "Complex").get val avroRecord = AvroRecord( "$".toPactPath, ".".toFieldName, @@ -287,8 +289,8 @@ class PactPluginServiceTest extends AsyncFlatSpecLike with Matchers with OptionV } it should "return successful result when comparing to matching content" in { - val url = getClass.getResource("/item.avsc") - val schema = AvroUtils.parseSchema(Path.of(url.getPath).toFile).value + val schemaFile = Paths.get(getClass.getResource("/item.avsc").toURI).toFile + val schema = AvroUtils.parseSchema(schemaFile).value val expectedBytes = AvroRecord( "$".toPactPath, diff --git a/project/BuildSettings.scala b/project/BuildSettings.scala index 5dcc1c3..7a3cd2a 100644 --- a/project/BuildSettings.scala +++ b/project/BuildSettings.scala @@ -9,7 +9,7 @@ import java.util object BuildSettings { private val javaVersion = 17 private val env: util.Map[String, String] = System.getenv() - val scalaV = "3.3.4-RC1" // Using version as `Wconf:src` option is not available in released 3.3.*, 3.4.* or 3.5.* versions + val scalaV = "3.5.0" lazy val basicSettings: Seq[Def.Setting[?]] = Seq( homepage := Some(URI.create("https://github.com/austek/pact-avro-plugin").toURL), @@ -34,10 +34,9 @@ object BuildSettings { Seq("-Xfatal-warnings") }, scalacOptions ++= Seq( - "-Wconf:id=E175:silent", "-Wconf:src=src_managed/.*:silent" ), - Test / tpolecatExcludeOptions += ScalacOptions.warnNonUnitStatement, + tpolecatExcludeOptions += ScalacOptions.warnNonUnitStatement, initialize := { val _ = initialize.value val javaVersionFound = sys.props("java.specification.version").toDouble diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 41075cd..d53ab30 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -8,9 +8,9 @@ object Dependencies extends DependencyUtils { val avro = "1.12.0" val jupiterInterface = "0.13.0" val logback = "1.5.7" - val pact = "4.6.13" - val pactDriverCore = "0.4.2" - val pulsar4sVersion = "2.9.1" + val pact = "4.6.14" + val pactDriverCore = "0.5.1" + val pulsar4sVersion = "2.10.0" val scalacheck = "1.18.0" val scalaLogging = "3.9.5" val scalaTest = "3.2.19" @@ -24,14 +24,9 @@ object Dependencies extends DependencyUtils { val apacheAvro: ModuleID = "org.apache.avro" % "avro" % Versions.avro excludeAll ExclusionRule("org.slf4j") val auPactMatchers: ModuleID = "au.com.dius.pact.core" % "matchers" % Versions.pact excludeAll ( ExclusionRule("com.google.guava"), - ExclusionRule("io.pact.plugin.driver"), ExclusionRule("org.slf4j") ) val logback: ModuleID = "ch.qos.logback" % "logback-classic" % Versions.logback - val pactCore: ModuleID = "io.pact.plugin.driver" % "core" % Versions.pactDriverCore excludeAll ( - ExclusionRule("au.com.dius.pact.core"), - ExclusionRule("org.slf4j") - ) val scalaLogging: ModuleID = "com.typesafe.scala-logging" %% "scala-logging" % Versions.scalaLogging excludeAll ExclusionRule("org.slf4j") val scalaPBRuntime = "com.thesamet.scalapb" %% "scalapb-runtime-grpc" % scalapb.compiler.Version.scalapbVersion val slf4jApi: ModuleID = "org.slf4j" %% "slf4j-api" % Versions.slf4jApi diff --git a/project/builds.sbt b/project/builds.sbt index 2e6ad91..948ea9b 100644 --- a/project/builds.sbt +++ b/project/builds.sbt @@ -1,3 +1,3 @@ libraryDependencies ++= List( - "com.lihaoyi" %% "upickle" % "4.0.0" + "com.lihaoyi" %% "upickle" % "4.0.1" ) diff --git a/project/plugins.sbt b/project/plugins.sbt index 20cd9b9..0a7c64f 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,4 +4,4 @@ addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.10.4") addSbtPlugin("com.github.sbt.junit" % "sbt-jupiter-interface" % "0.13.0") addSbtPlugin("com.lightbend.sbt" % "sbt-java-formatter" % "0.8.0") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") -addSbtPlugin("org.typelevel" % "sbt-tpolecat" % "0.5.0") +addSbtPlugin("org.typelevel" % "sbt-tpolecat" % "0.5.2") diff --git a/scripts/pact-publish.sh b/scripts/pact-publish.sh index b6f0c1d..59311a4 100755 --- a/scripts/pact-publish.sh +++ b/scripts/pact-publish.sh @@ -18,7 +18,9 @@ docker run --rm \ --network="host" \ pactfoundation/pact-cli \ publish /pacts \ - --broker-base-url=http://localhost:9292 \ - --consumer-app-version=$LATEST_COMMIT \ - --tag=production \ + --broker-base-url ${PACT_BROKER_BASE_URL} \ + --broker-username ${PACT_BROKER_USERNAME} \ + --broker-password ${PACT_BROKER_PASSWORD} \ + --consumer-app-version=${LATEST_COMMIT} \ + --tag=${LATEST_COMMIT} \ --branch=main