diff --git a/.checkstyle/checkstyle.xml b/.checkstyle/checkstyle.xml index 454e709..2705869 100644 --- a/.checkstyle/checkstyle.xml +++ b/.checkstyle/checkstyle.xml @@ -81,9 +81,6 @@ - - - @@ -93,9 +90,6 @@ - - - @@ -136,11 +130,6 @@ - - - - - diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..f66fbf7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +* text=auto + +*.bat text eol=crlf +*.sh text eol=lf + +gradlew text eol=lf diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 65bafb3..0000000 --- a/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -ARG JAVA_VERSION=17 -ARG JVM_FLAVOR=hotspot - -FROM openjdk:${JAVA_VERSION}-jdk-slim AS builder -WORKDIR /build - -COPY ./ ./ -RUN ./gradlew clean buildForDocker --no-daemon - - -ARG JAVA_VERSION -ARG JVM_FLAVOR - -FROM openjdk:${JAVA_VERSION}-slim -WORKDIR /app - -RUN groupadd --system bibliothek \ - && useradd --system bibliothek --gid bibliothek \ - && chown -R bibliothek:bibliothek /app -USER bibliothek:bibliothek - -VOLUME /data/storage -EXPOSE 8080 - -# We override default config location search path, -# so that a custom file with defaults can be used -# Normally would use environment variables, -# but they take precedence over config file -# https://docs.spring.io/spring-boot/docs/1.5.6.RELEASE/reference/html/boot-features-external-config.html -ENV SPRING_CONFIG_LOCATION="optional:classpath:/,optional:classpath:/config/,file:./default.application.yaml,optional:file:./,optional:file:./config/" -COPY ./docker/default.application.yaml ./default.application.yaml - -COPY --from=builder /build/build/libs/docker/bibliothek.jar ./ -CMD ["java", "-jar", "/app/bibliothek.jar"] diff --git a/build.gradle.kts b/build.gradle.kts index 25dcb10..6b9fd3d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,16 +1,24 @@ +import java.nio.file.StandardOpenOption +import kotlin.io.path.Path +import kotlin.io.path.bufferedWriter + +buildscript { + dependencies { + classpath("com.google.cloud.tools:jib-spring-boot-extension-gradle:0.1.0") + } +} + plugins { id("java") alias(libs.plugins.indra) alias(libs.plugins.indra.checkstyle) + alias(libs.plugins.jib) alias(libs.plugins.spotless) alias(libs.plugins.spring.dependency.management) alias(libs.plugins.spring.boot) } -group = "io.papermc" -version = "1.0.0-SNAPSHOT" - repositories { mavenCentral() } @@ -34,6 +42,52 @@ spotless { } } +jib { + to { + image = "ghcr.io/papermc/bibliothek" + tags = setOf("latest", project.version.toString()) + } + + from { + image = "azul/zulu-openjdk-alpine:${indra.javaVersions().target().get()}-jre" + platforms { + // We can only build multi-arch images when pushing to a registry, not when building locally + val requestedTasks = gradle.startParameter.taskNames + if ("jibBuildTar" in requestedTasks || "jibDockerBuild" in requestedTasks) { + platform { + // todo: better logic + architecture = when (System.getProperty("os.arch")) { + "aarch64" -> "arm64" + else -> "amd64" + } + os = "linux" + } + } else { + platform { + architecture = "amd64" + os = "linux" + } + platform { + architecture = "arm64" + os = "linux" + } + } + } + } + + pluginExtensions { + pluginExtension { + implementation = "com.google.cloud.tools.jib.gradle.extension.springboot.JibSpringBootExtension" + } + } + + container { + args = listOf("--spring.config.additional-location=optional:file:/config/") + ports = listOf("8080") + labels.put("org.opencontainers.image.source", indra.scm().map { it.url() }) + } +} + dependencies { annotationProcessor("org.springframework.boot", "spring-boot-configuration-processor") checkstyle(libs.stylecheck) @@ -48,20 +102,30 @@ dependencies { } tasks { - bootJar { - launchScript() + val outputImageId = register("printJibMeta") { + description = "Expose image information as an output for GitHub Actions" + + val jibImageJson = project.jib.outputPaths.imageJson + val githubOutput = providers.environmentVariable("GITHUB_OUTPUT") + inputs.property("jibImageJson", jibImageJson) + inputs.property("githubOutput", githubOutput).optional(true) + + doLast { + if (!githubOutput.isPresent) { + didWork = false + return@doLast + } + + Path(githubOutput.get()).bufferedWriter(Charsets.UTF_8, options = arrayOf(StandardOpenOption.CREATE, StandardOpenOption.APPEND)).use { + it.write("imageJson=") + file(jibImageJson).bufferedReader(Charsets.UTF_8).use { meta -> meta.transferTo(it) } + } + } } - // From StackOverflow: https://stackoverflow.com/a/53087407 - // Licensed under: CC BY-SA 4.0 - // Adapted to Kotlin - register("buildForDocker") { - from(bootJar) - into("build/libs/docker") - rename { fileName -> - // a simple way is to remove the "-$version" from the jar filename - // but you can customize the filename replacement rule as you wish. - fileName.replace("-$version", "") + sequenceOf(jib, jibDockerBuild, jibBuildTar).forEach { + it.configure { + finalizedBy(outputImageId.name) } } } diff --git a/docker/default.application.yaml b/docker/default.application.yaml deleted file mode 100644 index cf06453..0000000 --- a/docker/default.application.yaml +++ /dev/null @@ -1,8 +0,0 @@ ---- -app: - # path to volume in Dockerfile - make sure to keep in sync - storagePath: "/data/storage" - apiBaseUrl: "http://localhost/api" -server: - forward-headers-strategy: "framework" - port: 8080 diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..b4bb299 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +group = io.papermc +version = 1.0.0-SNAPSHOT diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index adba471..74d20ca 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,11 +4,12 @@ indra = "3.1.3" [plugins] indra = { id = "net.kyori.indra", version.ref = "indra" } indra-checkstyle = { id = "net.kyori.indra.checkstyle", version.ref = "indra" } +jib = { id = "com.google.cloud.tools.jib", version = "3.4.2" } spotless = { id = "com.diffplug.spotless", version = "6.25.0" } spring-boot = { id = "org.springframework.boot", version = "3.2.2" } spring-dependency-management = { id = "io.spring.dependency-management", version = "1.1.4" } [libraries] jetbrains-annotations = { group = "org.jetbrains", name = "annotations", version = "24.1.0" } -springdoc-openapi-starter-webmvc-ui = { group = "org.springdoc", name = "springdoc-openapi-starter-webmvc-ui", version = "2.3.0" } +springdoc-openapi-starter-webmvc-ui = { group = "org.springdoc", name = "springdoc-openapi-starter-webmvc-ui", version = "2.5.0" } stylecheck = { group = "ca.stellardrift", name = "stylecheck", version = "0.2.1" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7f93135..d64cd49 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e09..b82aa23 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 0adc8e1..1aa94a4 100755 --- a/gradlew +++ b/gradlew @@ -145,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -153,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -202,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/src/main/java/io/papermc/bibliothek/BibliothekApplication.java b/src/main/java/io/papermc/bibliothek/BibliothekApplication.java index 90f679d..09d1d08 100644 --- a/src/main/java/io/papermc/bibliothek/BibliothekApplication.java +++ b/src/main/java/io/papermc/bibliothek/BibliothekApplication.java @@ -34,7 +34,6 @@ }) @SpringBootApplication @ServletComponentScan -@SuppressWarnings("checkstyle:HideUtilityClassConstructor") public class BibliothekApplication { public static void main(final String[] args) { SpringApplication.run(BibliothekApplication.class, args); diff --git a/src/main/java/io/papermc/bibliothek/configuration/AppConfiguration.java b/src/main/java/io/papermc/bibliothek/configuration/AppConfiguration.java index 2546b7f..29011e0 100644 --- a/src/main/java/io/papermc/bibliothek/configuration/AppConfiguration.java +++ b/src/main/java/io/papermc/bibliothek/configuration/AppConfiguration.java @@ -37,42 +37,34 @@ public class AppConfiguration { private String apiVersion; private @NotNull Path storagePath; - @SuppressWarnings("checkstyle:MethodName") public URL getApiBaseUrl() { return this.apiBaseUrl; } - @SuppressWarnings("checkstyle:MethodName") public void setApiBaseUrl(final URL apiBaseUrl) { this.apiBaseUrl = apiBaseUrl; } - @SuppressWarnings("checkstyle:MethodName") public String getApiTitle() { return this.apiTitle; } - @SuppressWarnings("checkstyle:MethodName") public void setApiTitle(final String apiTitle) { this.apiTitle = apiTitle; } - @SuppressWarnings("checkstyle:MethodName") public String getApiVersion() { return this.apiVersion; } - @SuppressWarnings("checkstyle:MethodName") public void setApiVersion(final String apiVersion) { this.apiVersion = apiVersion; } - @SuppressWarnings("checkstyle:MethodName") public Path getStoragePath() { return this.storagePath; } - @SuppressWarnings("checkstyle:MethodName") public void setStoragePath(final Path storagePath) { this.storagePath = storagePath; } diff --git a/src/main/java/io/papermc/bibliothek/controller/v2/DownloadController.java b/src/main/java/io/papermc/bibliothek/controller/v2/DownloadController.java index ea016f2..41e9a11 100644 --- a/src/main/java/io/papermc/bibliothek/controller/v2/DownloadController.java +++ b/src/main/java/io/papermc/bibliothek/controller/v2/DownloadController.java @@ -63,7 +63,6 @@ @RestController @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE) -@SuppressWarnings("checkstyle:FinalClass") public class DownloadController { private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofDays(7)); private final AppConfiguration configuration; diff --git a/src/main/java/io/papermc/bibliothek/controller/v2/ProjectController.java b/src/main/java/io/papermc/bibliothek/controller/v2/ProjectController.java index 6109315..7accce1 100644 --- a/src/main/java/io/papermc/bibliothek/controller/v2/ProjectController.java +++ b/src/main/java/io/papermc/bibliothek/controller/v2/ProjectController.java @@ -50,7 +50,6 @@ @RestController @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE) -@SuppressWarnings("checkstyle:FinalClass") public class ProjectController { private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofMinutes(30)); private final ProjectCollection projects; diff --git a/src/main/java/io/papermc/bibliothek/controller/v2/ProjectsController.java b/src/main/java/io/papermc/bibliothek/controller/v2/ProjectsController.java index 16e176e..505e642 100644 --- a/src/main/java/io/papermc/bibliothek/controller/v2/ProjectsController.java +++ b/src/main/java/io/papermc/bibliothek/controller/v2/ProjectsController.java @@ -42,7 +42,6 @@ @RestController @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE) -@SuppressWarnings("checkstyle:FinalClass") public class ProjectsController { private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofDays(7)); private final ProjectCollection projects; diff --git a/src/main/java/io/papermc/bibliothek/controller/v2/VersionBuildController.java b/src/main/java/io/papermc/bibliothek/controller/v2/VersionBuildController.java index 1152e66..c63be29 100644 --- a/src/main/java/io/papermc/bibliothek/controller/v2/VersionBuildController.java +++ b/src/main/java/io/papermc/bibliothek/controller/v2/VersionBuildController.java @@ -55,7 +55,6 @@ @RestController @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE) -@SuppressWarnings("checkstyle:FinalClass") public class VersionBuildController { private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofDays(7)); private final ProjectCollection projects; diff --git a/src/main/java/io/papermc/bibliothek/controller/v2/VersionBuildsController.java b/src/main/java/io/papermc/bibliothek/controller/v2/VersionBuildsController.java index 7dd879f..dfdb715 100644 --- a/src/main/java/io/papermc/bibliothek/controller/v2/VersionBuildsController.java +++ b/src/main/java/io/papermc/bibliothek/controller/v2/VersionBuildsController.java @@ -53,7 +53,6 @@ @RestController @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE) -@SuppressWarnings("checkstyle:FinalClass") public class VersionBuildsController { private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofMinutes(5)); private final ProjectCollection projects; diff --git a/src/main/java/io/papermc/bibliothek/controller/v2/VersionController.java b/src/main/java/io/papermc/bibliothek/controller/v2/VersionController.java index 93bf72d..6058148 100644 --- a/src/main/java/io/papermc/bibliothek/controller/v2/VersionController.java +++ b/src/main/java/io/papermc/bibliothek/controller/v2/VersionController.java @@ -51,7 +51,6 @@ @RestController @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE) -@SuppressWarnings("checkstyle:FinalClass") public class VersionController { private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofMinutes(5)); private final ProjectCollection projects; diff --git a/src/main/java/io/papermc/bibliothek/controller/v2/VersionFamilyBuildsController.java b/src/main/java/io/papermc/bibliothek/controller/v2/VersionFamilyBuildsController.java index 63b1e16..d014599 100644 --- a/src/main/java/io/papermc/bibliothek/controller/v2/VersionFamilyBuildsController.java +++ b/src/main/java/io/papermc/bibliothek/controller/v2/VersionFamilyBuildsController.java @@ -58,7 +58,6 @@ @RestController @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE) -@SuppressWarnings("checkstyle:FinalClass") public class VersionFamilyBuildsController { private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofMinutes(5)); private final ProjectCollection projects; diff --git a/src/main/java/io/papermc/bibliothek/controller/v2/VersionFamilyController.java b/src/main/java/io/papermc/bibliothek/controller/v2/VersionFamilyController.java index 662d341..97b1996 100644 --- a/src/main/java/io/papermc/bibliothek/controller/v2/VersionFamilyController.java +++ b/src/main/java/io/papermc/bibliothek/controller/v2/VersionFamilyController.java @@ -51,7 +51,6 @@ @RestController @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE) -@SuppressWarnings("checkstyle:FinalClass") public class VersionFamilyController { private static final CacheControl CACHE = HTTP.sMaxAgePublicCache(Duration.ofMinutes(5)); private final ProjectCollection projects; diff --git a/src/main/java/io/papermc/bibliothek/exception/Advice.java b/src/main/java/io/papermc/bibliothek/exception/Advice.java index 45bb1ab..b44e970 100644 --- a/src/main/java/io/papermc/bibliothek/exception/Advice.java +++ b/src/main/java/io/papermc/bibliothek/exception/Advice.java @@ -33,7 +33,6 @@ import org.springframework.web.servlet.NoHandlerFoundException; @ControllerAdvice -@SuppressWarnings("checkstyle:FinalClass") class Advice { private final ObjectMapper json;