Skip to content

Commit

Permalink
Merge pull request #24 from daddykotex/dfrancoeur/dep-improvement
Browse files Browse the repository at this point in the history
Tweak the deployment to improve local dev experience
  • Loading branch information
daddykotex authored Jan 5, 2024
2 parents 5c17fe1 + cfe376b commit 1e6efb8
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 80 deletions.
163 changes: 89 additions & 74 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import org.scalajs.linker.interface.ModuleSplitStyle
import com.typesafe.sbt.packager.docker._
import smithy4s_codegen._

ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / organization := "com.example"
ThisBuild / organizationName := "example"
ThisBuild / scalaVersion := "2.13.10"
ThisBuild / dynverSeparator := "-"

val http4sVersion = "0.23.24"
val smithyVersion = "1.41.1"
Expand All @@ -30,9 +30,15 @@ lazy val smithyClasspath = settingKey[Seq[ModuleID]](
lazy val smithyClasspathDir = settingKey[String](
"""Path of the smithy classpath directory (where we mount the config and the jars)"""
)
lazy val resolveSmithyClasspath = taskKey[Seq[SmithyClasspathEntry]](
"""Resolve the smithy classpath so it can be bundled in the docker image, or made available to run"""
)
lazy val dockerTagOverride = settingKey[Option[String]](
"""Override for the docker image tag."""
)

lazy val root = (project in file("."))
.aggregate(api, frontend, backend, backendDependencies)
.aggregate(api, frontend, backend)

lazy val api = (project in file("modules/api"))

Expand Down Expand Up @@ -73,10 +79,10 @@ lazy val frontend = (project in file("modules/frontend"))
)

lazy val smithyClasspathSettings = Def.settings(
Universal / mappings ++= {
resolveSmithyClasspath := {
val depRes = dependencyResolution.value
val artifacts = smithyClasspath.value
val smithyClasspathOutput = target.value / "smithy-classpath"
val smithyClasspathValue = smithyClasspathDir.value
val logger = sLog.value
val resolved = artifacts.flatMap { module =>
depRes.retrieve(module, None, target.value, logger) match {
Expand All @@ -85,38 +91,63 @@ lazy val smithyClasspathSettings = Def.settings(
case Right(value) => value.headOption.map(f => module -> f)
}
}
val smithyClasspathValue = smithyClasspathDir.value

val entries: Seq[SmithyClasspathEntry] =
resolved.map { case (module, file) =>
SmithyClasspathEntry(
module,
file,
s"$smithyClasspathValue/${file.name}"
)
}
val entriesMapping =
entries.map { case SmithyClasspathEntry(_, file, pathInImage) =>
file -> pathInImage
}

val smithyClasspathFile = target.value / "smithy-classpath.json"
SmithyClasspath.toFile(
resolved.map { case (module, file) =>
SmithyClasspathEntry(
module,
file
)
}
},
Universal / mappings ++= {
val smithyClasspathValue = smithyClasspathDir.value
val entries = resolveSmithyClasspath.value
entries.map { case SmithyClasspathEntry(_, file) =>
file -> s"$smithyClasspathValue/${file.name}"
}
},
Docker / mappings ++= {
val smithyClasspathValue = smithyClasspathDir.value
val entries = resolveSmithyClasspath.value
val smithyClasspathFile =
target.value / smithyClasspathValue / "docker" / "smithy-classpath.json"
val inDockerPath = (Docker / defaultLinuxInstallLocation).value
SmithyClasspath.jsonConfig(
smithyClasspathFile,
entries,
(Docker / defaultLinuxInstallLocation).value
entries.map(sce =>
sce.module -> s"$inDockerPath/$smithyClasspathValue/${sce.file.name}"
)
)
val configMapping = Seq(
smithyClasspathFile -> s"$smithyClasspathValue/smithy-classpath.json"
Seq(
smithyClasspathFile -> s"$inDockerPath/$smithyClasspathValue/smithy-classpath.json"
)
entriesMapping ++ configMapping
},
dockerEnvVars ++= {
val inDockerPath = (Docker / defaultLinuxInstallLocation).value
val smithyClasspathValue = smithyClasspathDir.value
Map(
"SMITHY_CLASSPATH_CONFIG" -> s"$inDockerPath/$smithyClasspathValue/smithy-classpath.json"
)
},
reStart := {
val entries = resolveSmithyClasspath.value

val smithyClasspathValue = smithyClasspathDir.value
val smithyClasspathFile =
target.value / smithyClasspathValue / "reStart" / "smithy-classpath.json"
SmithyClasspath.jsonConfig(
smithyClasspathFile,
entries.map(sce => sce.module -> sce.file.getAbsolutePath())
)
reStart.evaluated
},
reStart / envVars ++= {
val smithyClasspathValue = smithyClasspathDir.value
val smithyClasspathFile =
target.value / smithyClasspathValue / "reStart" / "smithy-classpath.json"
Map(
"SMITHY_CLASSPATH_CONFIG" -> smithyClasspathFile.getAbsolutePath()
)
}
)

Expand All @@ -142,8 +173,10 @@ lazy val backend = (project in file("modules/backend"))
"software.amazon.smithy" % "smithy-model" % smithyVersion,
"org.http4s" %% "http4s-ember-server" % http4sVersion
),
smithyClasspath := Seq.empty,
smithyClasspathDir := "smithy-classpath",
smithyClasspath := Seq(
"com.disneystreaming.smithy4s" % "smithy4s-protocol" % smithy4sVersion.value
),
Compile / resourceGenerators += Def.task {
val dir = frontend.base
val distDir = dir / "dist"
Expand All @@ -167,58 +200,40 @@ lazy val backend = (project in file("modules/backend"))
Docker / dockerExposedPorts := List(9000),
Docker / packageName := "smithy4s-code-generation",
Docker / dockerRepository := Some("daddykotex"),
dockerAliases ++= {
val sha = sys.env.get("GITHUB_SHA").map(_.take(10))
val latests = Seq(
dockerTagOverride := None,
dockerUpdateLatest := true,
dockerLabels ++= {
Map("smithy4s.version" -> smithy4sVersion.value)
},
dockerAliases := {
val flyAlias =
dockerAlias.value
.withName("morning-bird-7081")
.withRegistryHost(Option("registry.fly.io"))
)
val shas = sha.toSeq.flatMap { s =>
Seq(
dockerAlias.value.withTag(Some(s)),
dockerAlias.value
.withTag(Some(s))
.withName("morning-bird-7081")
.withRegistryHost(Option("registry.fly.io"))
)
}

latests ++ shas
},
Docker / version := "latest",
dockerBaseImage := "eclipse-temurin:17.0.6_10-jre"
)

/** This is a project that's only intented to be a copy of backend but that
* builds in an image with some dependencies for the smithy-classpath.
*/
lazy val backendDependencies = project
.enablePlugins(DockerPlugin)
.settings(smithyClasspathSettings)
.settings(
smithyClasspath := Seq(
"com.disneystreaming.alloy" % "alloy-core" % "0.2.8",
"com.disneystreaming.smithy4s" % "smithy4s-protocol" % smithy4sVersion.value
),
smithyClasspathDir := "smithy-classpath",
Docker / packageName := "smithy4s-code-generation",
Docker / dockerRepository := Some("daddykotex"),
dockerAliases := {
val beAlias = (backend / dockerAlias).value
val sha = sys.env.get("GITHUB_SHA").map(_.take(10))
val tags =
sha.map(s => s"with-dependencies-$s").toSeq ++ Seq("with-dependencies")
tags.flatMap { t =>
Seq(
dockerAlias.value.withTag(Some(t)),
dockerAlias.value
.withTag(Some(t))
.withName("morning-bird-7081")
.withRegistryHost(Option("registry.fly.io"))
)
dockerTagOverride.value match {
case Some(tagOverride) =>
val v = version.value
val preciseTag = s"$tagOverride-$v"
val allTags =
if (dockerUpdateLatest.value) Seq(preciseTag, tagOverride)
else Seq(preciseTag)
allTags.flatMap(tag =>
Seq(
dockerAlias.value.withTag(Some(tag)),
flyAlias.withTag(Some(tag))
)
)
case None =>
val latests =
if (dockerUpdateLatest.value)
Seq(
dockerAlias.value.withTag(Some("latest")),
flyAlias.withTag(Some("latest"))
)
else Seq.empty
Seq(dockerAlias.value, flyAlias) ++ latests
}
},
dockerEntrypoint := (backend / dockerEntrypoint).value,
dockerBaseImage := (backend / dockerAlias).value.toString
dockerBaseImage := "eclipse-temurin:17.0.6_10-jre"
)
13 changes: 8 additions & 5 deletions project/SmithyClasspath.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@ import java.io.File
import sbt.io.IO

final case class SmithyClasspathEntry(
module: sbt.ModuleID,
file: File
)
final case class SmithyClasspathDockerEntry(
module: sbt.ModuleID,
file: File,
relativePath: String
)
object SmithyClasspath {
def toFile(
def jsonConfig(
target: File,
all: Seq[SmithyClasspathEntry],
dockerPath: String
all: Seq[(ModuleID, String)]
): Unit = {
val entries = all.map { sce =>
encodeModule(sce.module) -> ujson.Str(s"$dockerPath/${sce.relativePath}")
val entries = all.map { case (module, location) =>
encodeModule(module) -> ujson.Str(location)
}.toMap
val content = ujson.Obj(
"entries" -> ujson.Obj.from(entries)
Expand Down
1 change: 1 addition & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ addSbtPlugin(
addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.16")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.13.1")
addSbtPlugin("io.spray" % "sbt-revolver" % "0.10.0")
addSbtPlugin("com.github.sbt" % "sbt-dynver" % "5.0.1")
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0")
11 changes: 10 additions & 1 deletion scripts/build-image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,14 @@ fi

set -u

# build frontend so it's available to be bundled
(cd modules/frontend; npm i && npm run build)
sbt "backend / Docker / $BACKEND_PUBLISH; backendDependencies / Docker / $BACKEND_PUBLISH"

# build backend w/ default dependencies
publish_backend="backend / Docker / $BACKEND_PUBLISH"
sbt "$publish_backend"

# build backend w/ additional dependencies
tag_override="set backend / dockerTagOverride := Some(\"with-dependencies\")"
smithy_classpath="set backend / smithyClasspath ++= Seq(\"com.disneystreaming.alloy\" % \"alloy-core\" % \"0.2.8\")"
sbt "$tag_override; $smithy_classpath; $publish_backend"

0 comments on commit 1e6efb8

Please sign in to comment.