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;