Skip to content

Commit

Permalink
Merge branch 'release/0.7.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
usommerl committed Sep 10, 2021
2 parents 0212ab9 + 70fa2c6 commit a0e8030
Show file tree
Hide file tree
Showing 15 changed files with 106 additions and 105 deletions.
15 changes: 3 additions & 12 deletions .github/workflows/ci_cd.yaml → .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CI / CD
name: ci

on: [push, pull_request]

Expand All @@ -15,7 +15,7 @@ jobs:
java-version: 11
- name: Run tests
run: sbt testCovered
cd:
build-docker-images:
needs: [ci]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
Expand All @@ -28,7 +28,7 @@ jobs:
distribution: 'adopt'
java-version: 11
- name: Login to GitHub Container Registry
uses: docker/login-action@v1.9.0
uses: docker/login-action@v1.10.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
Expand All @@ -45,15 +45,6 @@ jobs:
export IMAGE_GCR=$(echo $IMAGE_GHCR | sed 's/ghcr.io/eu.gcr.io/')
docker tag $IMAGE_GHCR $IMAGE_GCR
echo "image_gcr=$IMAGE_GCR" >> $GITHUB_ENV
- name: Deploy to Cloud Run
uses: stefda/action-cloud-run@v1.4
with:
image: ${{ env.image_gcr }}
service: graalnative4s
project: ${{ github.repository_owner }}
region: europe-west1
env: .github/workflows/cloud_run_env_vars
service key: ${{ secrets.GCP_SA_KEY }}
- name: Create GitHub release
uses: release-drafter/release-drafter@v5
env:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/cloud_run_env_vars

This file was deleted.

5 changes: 3 additions & 2 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
version = 2.7.5
version = "3.0.2"

maxColumn = 140
align = most
align.preset = most
continuationIndent.defnSite = 2
rewrite.rules = [SortImports, AvoidInfix, PreferCurlyFors, RedundantBraces, RedundantParens]
runner.dialect = scala213source3
14 changes: 11 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
FROM ghcr.io/graalvm/graalvm-ce:java11-21.1.0 as builder
FROM ghcr.io/graalvm/graalvm-ce:java11-21.2.0 as builder

ARG upx_compression
ARG print_reports
RUN gu install native-image
RUN curl https://bintray.com/sbt/rpm/rpm | tee /etc/yum.repos.d/bintray-sbt-rpm.repo && microdnf install sbt git xz
RUN curl -L https://www.scala-sbt.org/sbt-rpm.repo | tee /etc/yum.repos.d/sbt-rpm.repo && microdnf install sbt git xz

# BEGIN INSTALL PRE-REQUISITES FOR STATIC NATIVE IMAGES WITH GRAAL >= 20.2.0
# See:
Expand Down Expand Up @@ -31,7 +32,14 @@ RUN curl -L -o zlib.tar.gz https://zlib.net/zlib-1.2.11.tar.gz && \
COPY . /build
WORKDIR /build
RUN sbt graalvm-native-image:packageBin
RUN for f in target/graalvm-native-image/reports/*.txt; do printf '#%.0s' {1..80}; printf "\n$f\n\n"; cat $f; done

RUN if [ -n "${print_reports}" ]; then \
for f in target/graalvm-native-image/reports/*.csv; do \
printf '#%.0s' {1..80}; \
printf "\n$f\n\n"; \
cat $f; \
done; \
fi

RUN if [ -n "${upx_compression}" ]; then \
curl -L -o upx-3.96-amd64_linux.tar.xz https://github.com/upx/upx/releases/download/v3.96/upx-3.96-amd64_linux.tar.xz && \
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ I have taken a lot of inspiration and knowledge from [this blog post by James Wa
[ciris]: https://github.com/vlovgr/ciris

[image]: https://github.com/users/usommerl/packages/container/package/graalnative4s
[workflow]: .github/workflows/ci_cd.yaml
[workflow]: https://github.com/usommerl/graalnative4s/blob/deploy-gcp/.github/workflows/deploy.yaml
[inspiration]: https://jamesward.com/2020/05/07/graalvm-native-image-tips-tricks/
[uzhttp]: https://github.com/jamesward/hello-uzhttp
[docker-stats-monitor]: https://github.com/vasilmkd/docker-stats-monitor
Expand Down
46 changes: 26 additions & 20 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
ThisBuild / scalaVersion := "2.13.5"
ThisBuild / organization := "dev.usommerl"
ThisBuild / scalaVersion := "2.13.6"
ThisBuild / organization := "dev.usommerl"
ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.5.0"

val v = new {
val http4s = "0.21.23"
val circe = "0.13.0"
val ciris = "1.2.1"
val tapir = "0.17.19"
val odin = "0.11.0"
val munit = "0.7.26"
val munitCE = "1.0.3"
val circe = "0.14.1"
val ciris = "2.1.1"
val http4s = "0.23.3"
val odin = "0.12.0"
val tapir = "0.19.0-M8"
val munit = "0.7.29"
val munitCE = "1.0.5"
}

val upx = "UPX_COMPRESSION"
Expand All @@ -18,6 +18,7 @@ lazy val graalnative4s = project
.in(file("."))
.enablePlugins(BuildInfoPlugin, sbtdocker.DockerPlugin, GraalVMNativeImagePlugin)
.settings(
scalacOptions ++= Seq("-Xsource:3"),
libraryDependencies ++= Seq(
compilerPlugin("com.olegpy" %% "better-monadic-for" % "0.3.1"),
"com.softwaremill.sttp.tapir" %% "tapir-core" % v.tapir,
Expand All @@ -26,32 +27,32 @@ lazy val graalnative4s = project
"com.softwaremill.sttp.tapir" %% "tapir-openapi-docs" % v.tapir,
"com.softwaremill.sttp.tapir" %% "tapir-openapi-circe-yaml" % v.tapir,
"com.softwaremill.sttp.tapir" %% "tapir-refined" % v.tapir,
"com.softwaremill.sttp.tapir" %% "tapir-swagger-ui-http4s" % v.tapir,
"com.softwaremill.sttp.tapir" %% "tapir-swagger-ui" % v.tapir,
"com.github.valskalla" %% "odin-core" % v.odin,
"com.github.valskalla" %% "odin-json" % v.odin,
"com.github.valskalla" %% "odin-slf4j" % v.odin,
"io.circe" %% "circe-core" % v.circe,
"io.circe" %% "circe-generic" % v.circe,
"io.circe" %% "circe-parser" % v.circe,
"io.circe" %% "circe-literal" % v.circe,
"io.circe" %% "circe-generic-extras" % v.circe,
"is.cir" %% "ciris" % v.ciris,
"is.cir" %% "ciris-refined" % v.ciris,
"org.http4s" %% "http4s-blaze-server" % v.http4s,
"org.http4s" %% "http4s-ember-server" % v.http4s,
"org.http4s" %% "http4s-circe" % v.http4s,
"org.http4s" %% "http4s-dsl" % v.http4s,
"org.scalameta" %% "munit" % v.munit % Test,
"org.typelevel" %% "munit-cats-effect-2" % v.munitCE % Test
"org.typelevel" %% "munit-cats-effect-3" % v.munitCE % Test
),
testFrameworks += new TestFramework("munit.Framework"),
buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion, Test / libraryDependencies),
buildInfoPackage := organization.value,
buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion, Test / libraryDependencies),
buildInfoPackage := organization.value,
buildInfoOptions ++= Seq[BuildInfoOption](BuildInfoOption.BuildTime),
semanticdbEnabled := true,
semanticdbVersion := scalafixSemanticdb.revision,
docker / dockerfile := NativeDockerfile(file("Dockerfile")),
docker / imageNames := Seq(ImageName(s"ghcr.io/usommerl/${name.value}:${dockerImageTag}")),
docker / dockerBuildArguments := sys.env.get(upx).map(s => Map("upx_compression" -> s)).getOrElse(Map.empty),
semanticdbEnabled := true,
semanticdbVersion := scalafixSemanticdb.revision,
docker / dockerfile := NativeDockerfile(file("Dockerfile")),
docker / imageNames := Seq(ImageName(s"ghcr.io/usommerl/${name.value}:$dockerImageTag")),
docker / dockerBuildArguments := dockerBuildArgs,
assembly / test := (Test / test).value,
assembly / assemblyMergeStrategy := {
case "META-INF/maven/org.webjars/swagger-ui/pom.properties" => MergeStrategy.singleOrError
case x if x.endsWith("module-info.class") => MergeStrategy.discard
Expand All @@ -67,3 +68,8 @@ def dockerImageTag: String = {
val upxSuffix = sys.env.get(upx).map(s => s"-upx${s.replace("--", "-")}").getOrElse("")
s"$version$upxSuffix"
}

def dockerBuildArgs: Map[String, String] =
sys.env.foldLeft(Map.empty[String, String]) { case (acc, (k, v)) =>
if (Set("UPX_COMPRESSION", "PRINT_REPORTS").contains(k)) acc + (k.toLowerCase -> v) else acc
}
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.2
sbt.version=1.5.5
10 changes: 5 additions & 5 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.27")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.30")
addSbtPlugin("com.alejandrohdezma" % "sbt-codecov" % "0.2.1")
addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.1.0")
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.10.0")
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.8.1")
addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.17")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.8.0")
addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.20")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.3")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.8.2")
addSbtPlugin("se.marcuslonnberg" % "sbt-docker" % "1.8.2")
10 changes: 4 additions & 6 deletions src/main/resources/META-INF/native-image/native-image.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@ Args = --verbose \
--enable-https \
--enable-all-security-services \
--report-unsupported-elements-at-runtime \
--initialize-at-build-time \
--initialize-at-run-time=org.http4s.multipart.Boundary$ \
--initialize-at-build-time=scala.Symbol$ \
--allow-incomplete-classpath \
--install-exit-handlers \
-H:+ReportExceptionStackTraces \
-H:+ReportUnsupportedElementsAtRuntime \
-H:+PrintClassInitialization \
-H:+StackTrace \
-H:+JNI \
-H:-SpawnIsolates \
-H:-UseServiceLoaderFeature \
-H:+RemoveSaturatedTypeFlows \
--install-exit-handlers \
--initialize-at-build-time=scala.runtime.Statics$VM
-H:-SpawnIsolates \
-H:-UseServiceLoaderFeature
12 changes: 0 additions & 12 deletions src/main/resources/META-INF/native-image/reflect-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -856,10 +856,6 @@
{
"name":"scala.reflect.internal.annotations.uncheckedBounds"
},
{
"name":"scala.reflect.internal.util.AlmostFinalValue$AlmostFinalCallSite",
"methods":[{"name":"fallback","parameterTypes":[] }]
},
{
"name":"scala.reflect.macros.blackbox.Context"
},
Expand Down Expand Up @@ -1112,14 +1108,6 @@
{
"name":"scala.xml.package"
},
{
"name":"server.app.package$$typecreator1$1",
"allDeclaredFields":true
},
{
"name":"server.app.package$$typecreator2$1",
"allDeclaredFields":true
},
{
"name":"sun.security.provider.MD5",
"methods":[{"name":"<init>","parameterTypes":[] }]
Expand Down
21 changes: 11 additions & 10 deletions src/main/scala/app/Api.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package app

import cats.Applicative
import cats.data.Kleisli
import cats.effect.{Concurrent, ContextShift, Timer}
import cats.effect.kernel.Async
import cats.implicits._
import dev.usommerl.BuildInfo
import eu.timepit.refined.api.Refined
Expand All @@ -24,32 +24,33 @@ import sttp.tapir.json.circe.jsonBody
import sttp.tapir.openapi.{OpenAPI, Server}
import sttp.tapir.openapi.circe.yaml._
import sttp.tapir.server.ServerEndpoint
import sttp.tapir.server.http4s._
import sttp.tapir.swagger.http4s.SwaggerHttp4s
import sttp.tapir.server.http4s.Http4sServerInterpreter
import sttp.tapir.swagger.SwaggerUI

object Api {
def apply[F[_]: Concurrent: ContextShift: Timer](config: ApiDocsConfig): Kleisli[F, Request[F], Response[F]] = {
def apply[F[_]: Async](config: ApiDocsConfig): Kleisli[F, Request[F], Response[F]] = {

val dsl = Http4sDsl[F]
import dsl._

val apis: List[TapirApi[F]] = List(Examples())

val docs: OpenAPI = OpenAPIDocsInterpreter
val docs: OpenAPI = OpenAPIDocsInterpreter()
.toOpenAPI(apis.flatMap(_.endpoints), openapi.Info(BuildInfo.name, BuildInfo.version, config.description))
.servers(List(Server(config.serverUrl)))
.tags(apis.map(_.tag))

val swaggerUi = Http4sServerInterpreter().toRoutes(SwaggerUI[F](docs.toYaml))
val redirectRootToDocs = HttpRoutes.of[F] { case path @ GET -> Root => PermanentRedirect(Location(path.uri / "docs")) }

val routes: List[HttpRoutes[F]] = apis.map(_.routes) ++ List(new SwaggerHttp4s(docs.toYaml).routes, redirectRootToDocs)
val routes: List[HttpRoutes[F]] = apis.map(_.routes) ++ List(swaggerUi, redirectRootToDocs)

CORS(routes.reduce(_ <+> _)).orNotFound
CORS.policy(routes.reduce(_ <+> _)).orNotFound
}
}

object Examples {
def apply[F[_]: Concurrent: ContextShift: Timer]()(implicit F: Applicative[F]) = new TapirApi[F] {
def apply[F[_]: Async]()(implicit F: Applicative[F]) = new TapirApi[F] {
override val tag = Tag("Getting started", None)
override lazy val serverEndpoints = List(info, hello)
type NonEmptyString = String Refined NonEmpty
Expand Down Expand Up @@ -97,9 +98,9 @@ object Examples {
}
}

abstract class TapirApi[F[_]: Concurrent: ContextShift: Timer] {
abstract class TapirApi[F[_]: Async] {
def tag: Tag
def serverEndpoints: List[ServerEndpoint[_, _, _, Any, F]]
def endpoints: List[Endpoint[_, _, _, _]] = serverEndpoints.map(_.endpoint)
def routes: HttpRoutes[F] = Http4sServerInterpreter.toRoutes(serverEndpoints)
def routes: HttpRoutes[F] = Http4sServerInterpreter().toRoutes(serverEndpoints)
}
23 changes: 15 additions & 8 deletions src/main/scala/app/Config.scala
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
package app

import cats.implicits._
import ciris._
import ciris.{Effect, _}
import ciris.refined._
import com.comcast.ip4s.{Host, Port}
import eu.timepit.refined.api.Refined
import eu.timepit.refined.auto._
import eu.timepit.refined.string.Url
import eu.timepit.refined.types.net.PortNumber
import io.odin.Level
import io.odin.formatter.Formatter
import io.odin.json.{Formatter => JFormatter}

import app.ServerUrl

case class Config(server: ServerConfig, logger: LoggerConfig)
case class ServerConfig(port: PortNumber, apiDocs: ApiDocsConfig)
case class ServerConfig(host: Host, port: Port, apiDocs: ApiDocsConfig)
case class ApiDocsConfig(serverUrl: ServerUrl, description: Option[String])
case class LoggerConfig(level: Level, formatter: Formatter)

package object app {

type ServerUrl = String Refined Url

implicit val portDecoder: ConfigDecoder[String, Port] =
ConfigDecoder[String, String].mapOption("Port")(Port.fromString)

implicit val hostDecoder: ConfigDecoder[String, Host] =
ConfigDecoder[String, String].mapOption("Host")(Host.fromString)

implicit val logLevelDecoder: ConfigDecoder[String, Level] =
ConfigDecoder[String, String].mapOption("Level")(_.toLowerCase match {
case "trace" => Level.Trace.some
Expand All @@ -40,22 +46,23 @@ package object app {
case _ => None
})

private val loggerConfig: ConfigValue[LoggerConfig] = (
private val loggerConfig: ConfigValue[Effect, LoggerConfig] = (
env("LOG_LEVEL").as[Level].default(Level.Info),
env("LOG_FORMATTER").as[Formatter].default(Formatter.colorful)
).parMapN(LoggerConfig)

private val apiDocsConfig: ConfigValue[ApiDocsConfig] = (
private val apiDocsConfig: ConfigValue[Effect, ApiDocsConfig] = (
env("APIDOCS_SERVER_URL").as[ServerUrl].default("http://localhost:8080"),
env("APIDOCS_DESCRIPTION").option
).parMapN(ApiDocsConfig)

private val serverConfig: ConfigValue[ServerConfig] = (
env("PORT").as[PortNumber].default(8080),
private val serverConfig: ConfigValue[Effect, ServerConfig] = (
env("HOST").as[Host].default(Host.fromString("0.0.0.0").get),
env("PORT").as[Port].default(Port.fromInt(8080).get),
apiDocsConfig
).parMapN(ServerConfig)

val config: ConfigValue[Config] = (
val config: ConfigValue[Effect, Config] = (
serverConfig,
loggerConfig
).parMapN(Config)
Expand Down
Loading

0 comments on commit a0e8030

Please sign in to comment.