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

refactor: migrate to zio-json + update all #438

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

ThijsBroersen
Copy link

Why circe if we have zio-json? 😏

I think main is broken because some PR's got merged which did not pass CI. Like circe-yaml 0.16.0 which is not available for Scala 2.12 anymore.

This PR updates all dependencies and migrates to zio-json. I see some other areas where improvements can be made but will target that in separate PR's.

I ran sbt prepare as in the Contributing guide but not sbt testPlugin that seems broken. I could not find any reference to the testPlugin task. I also could not find any tests in the repo... how is this project tested? Manually?

With zio-json I created codecs (both encoders and decoders) so perhaps validations can now also be done by parsing the yaml and decoding back to the model and then create a set of rules for it. Perhaps even allow manual tweaks and on each new generate-run first load the existing flow and then update this flow.

@ThijsBroersen ThijsBroersen changed the title refactor: migrate to zio-json refactor: migrate to zio-json + update all Oct 17, 2024
@ThijsBroersen ThijsBroersen force-pushed the refactor/migrate-to-zio-json branch from 7a9a6c8 to b2a7d1a Compare October 17, 2024 20:27
@ThijsBroersen
Copy link
Author

ThijsBroersen commented Oct 17, 2024

The PR is btw breaking because it changes the model so the codecs become easier because they match the GHA model more closely. Any opinions?
I think it helps to migrate and not have to remember different views on the same thing.

--update--
I restored the existing model and added a new one. With toNative methods to convert. I tested it on a few zio projects and the required changes are quite small.

@@ -190,7 +190,7 @@ trait ScalaCompilerSettings {
)
} else Seq.empty
},
Test / parallelExecution := scalaBinaryVersion.value != "3",
Test / parallelExecution := scalaBinaryVersion.value != "3", // why not parallel execution for Scala 3?
Copy link
Author

Choose a reason for hiding this comment

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

Discovered this setting.. why was this set? I would prefer to not have this set.

Copy link
Member

Choose a reason for hiding this comment

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

It's good to remove it! However, I don't remember why this line was included. Can you check to ensure it's okay to remove it?

@@ -233,8 +233,7 @@ trait ScalaCompilerSettings {
libraryDependencies ++= Seq(
"dev.zio" %%% "zio-test" % ZioSbtEcosystemPlugin.autoImport.zioVersion.value % Test,
"dev.zio" %%% "zio-test-sbt" % ZioSbtEcosystemPlugin.autoImport.zioVersion.value % Test
),
testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")
)
Copy link
Author

Choose a reason for hiding this comment

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

For quite some time ZTestFramework is added to testFrameworks in sbt by default.

@ThijsBroersen ThijsBroersen force-pushed the refactor/migrate-to-zio-json branch from ba39433 to eb7e7a8 Compare October 18, 2024 21:38
val Scala212 = "2.12.20"
val Scala213 = "2.13.15"
val Scala3 = "3.3.4"
val zio = "2.1.9"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
val zio = "2.1.9"
val zio = "2.1.11"

libraryDependencies += "dev.zio" %% "zio" % "2.1.8"
libraryDependencies += "io.circe" %% "circe-yaml" % "0.16.0"
libraryDependencies += "org.snakeyaml" % "snakeyaml-engine" % "2.8"
libraryDependencies += "dev.zio" %% "zio" % "2.1.9"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
libraryDependencies += "dev.zio" %% "zio" % "2.1.9"
libraryDependencies += "dev.zio" %% "zio" % "2.1.11"

@@ -1,2 +1,3 @@
libraryDependencies += "dev.zio" %% "zio" % "2.1.8"
libraryDependencies += "io.circe" %% "circe-yaml" % "0.16.0"
libraryDependencies += "dev.zio" %% "zio" % "2.1.9"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
libraryDependencies += "dev.zio" %% "zio" % "2.1.9"
libraryDependencies += "dev.zio" %% "zio" % "2.1.11"

libraryDependencies += "org.snakeyaml" % "snakeyaml-engine" % "2.7"
libraryDependencies += "dev.zio" %% "zio" % "2.1.8"
libraryDependencies += "io.circe" %% "circe-yaml" % "0.16.0"
libraryDependencies += "dev.zio" %% "zio" % "2.1.9"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
libraryDependencies += "dev.zio" %% "zio" % "2.1.9"
libraryDependencies += "dev.zio" %% "zio" % "2.1.11"


val zioVersion = "2.0.21"
val zioVersion = "2.1.9"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
val zioVersion = "2.1.9"
val zioVersion = "2.1.11"

@@ -1,2 +1,3 @@
libraryDependencies += "dev.zio" %% "zio" % "2.1.8"
libraryDependencies += "io.circe" %% "circe-yaml" % "0.16.0"
libraryDependencies += "dev.zio" %% "zio" % "2.1.9"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
libraryDependencies += "dev.zio" %% "zio" % "2.1.9"
libraryDependencies += "dev.zio" %% "zio" % "2.1.11"


// The original code of the githubactions package was originally copied from the zio-aws-codegen project:
// https://github.com/zio/zio-aws/tree/master/zio-aws-codegen/src/main/scala/zio/aws/codegen/githubactions
object ScalaWorkflow {
Copy link
Member

@guizmaii guizmaii Oct 19, 2024

Choose a reason for hiding this comment

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

What's the need to rewrite this code from scratch?

Copy link
Author

Choose a reason for hiding this comment

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

I added the new solution next to the existing. But I think in the end result the old model and workflow are not used anymore in the other modules.
Perhaps the question should be: should we use the new model, stick with the old or somehow support both?
My reasons for the new model is that it is closer to writing direct GHA yaml and less of a cognitive load (no need to learn another DSL). It also simplifies the codecs because we reduce the amount of codec adjustments or required DTO's.

Copy link
Author

Choose a reason for hiding this comment

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

I would love to contribute some more but I really think a model which is as much 1:1 with GHA model as possible, helps to build better workflows. It is predictable and the codecs are easier.

@ThijsBroersen ThijsBroersen reopened this Nov 27, 2024
@ThijsBroersen ThijsBroersen force-pushed the refactor/migrate-to-zio-json branch from 97f3900 to 3fe9f88 Compare November 27, 2024 20:10
@ThijsBroersen
Copy link
Author

The ScalaWorkflow now only has a single version.

@@ -5,7 +5,7 @@ object V {
Map(
"peter-evans/create-pull-request" -> "v6",
"zio/generate-github-app-token" -> "v1.0.0",
"pierotofy/set-swap-space" -> "master",
"pierotofy/set-swap-space" -> "49819abfb41bd9b44fb781159c033dba90353a7c", // 1.0,
Copy link
Member

Choose a reason for hiding this comment

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

maybe it is better to mention the version here: "v1.0"

Copy link
Author

Choose a reason for hiding this comment

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

I was not sure about the correct tagging. The github tag is 1.0 and the marketplace says v1.0. I just wanted to prevent the action from changing. I can try and make it v1.0 or 1.0.

run: Option[String] = None,
env: Map[String, String] = Map.empty
env: Option[ListMap[String, String]] = None
Copy link
Member

Choose a reason for hiding this comment

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

Why not env: ListMap[String, String] = ListMap.empty?

Copy link
Author

Choose a reason for hiding this comment

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

Optional keys are automatically left out of the json object. An empty map will be encoded as {}. I do not think zio-json has the option to exclude keys with empty objects yet.

Copy link
Author

Choose a reason for hiding this comment

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

Perhaps in zio-json this could be fixed with a default value. Dropping the key when the value is the default value.

Copy link
Member

Choose a reason for hiding this comment

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

I prefer to make it as simple as possible! So probably it should be fixed on zio-json side.

Copy link
Author

Choose a reason for hiding this comment

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


case object UbuntuLatest extends OS("ubuntu-latest")
case object Ubuntu2404 extends OS("ubuntu-24.04")
case object Ubuntu2204 extends OS("ubuntu-22.04")
Copy link
Member

Choose a reason for hiding this comment

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

👍

) ++ checkAllCodeCompiles ++ checkArtifactBuildProcess ++ checkWebsiteBuildProcess
) ++ checkAllCodeCompiles.flatMap(_.flatten) ++ checkArtifactBuildProcess.flatMap(
_.flatten
) ++ checkWebsiteBuildProcess.flatMap(_.flatten)
Copy link
Member

Choose a reason for hiding this comment

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

Why this boilerplate change is needed? Can you keep it as simple as it is?

Copy link
Author

Choose a reason for hiding this comment

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

yes, I made a custom codec for Seq[Step] in Job

@@ -177,7 +178,7 @@ object ZioSbtCiPlugin extends AutoPlugin {
scalaVersionMatrix.values.toSeq.flatten.distinct.map { scalaVersion: String =>
Step.SingleStep(
name = "Test",
condition = Some(Condition.Expression(s"matrix.scala == '$scalaVersion'")),
`if` = Some(Condition.Expression(s"matrix.scala == '$scalaVersion'")),
Copy link
Member

Choose a reason for hiding this comment

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

Can we preserve the previous syntax? We can deprecate it, but make it possible to compile old codes.

Copy link
Author

Choose a reason for hiding this comment

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

I tried but because of all the default values there are already issues with overloaded constructors. If the zio-json PR will get merged I could transform a lot of optional sequences to plain sequences with the explicitEmptyCollections set to false.

}
)
)

val DefaultTestStrategy =
Job(
id = "test",
Copy link
Member

Choose a reason for hiding this comment

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

Why the id is removed?

Copy link
Author

Choose a reason for hiding this comment

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

The name is used, transformed to an id. This way we do not have to exclude the id field from the json. Do you prefer the explicit id field?

sealed trait JavaVersion {
def distribution: String
def version: String
def asString: String = s"$distribution:$version"
Copy link
Member

Choose a reason for hiding this comment

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

👍

Comment on lines +550 to +551
val yaml: String = zio.json.ast.Json.decoder
.decodeJson(workflow.toJson)
Copy link
Author

@ThijsBroersen ThijsBroersen Dec 13, 2024

Choose a reason for hiding this comment

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

this is a bit dirty but the toJsonAST does not perform the excludeEmptyCollections , will investigate this later in zio-json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants