refactor(server): source build version from git tag

- Stamp version, channel and vendor into META-INF/build-info.properties
- Read build metadata at runtime from BuildProperties instead of expanded YAML
- Remove app.common placeholders from application.yaml
- Derive the OpenAPI info version from the packaged build version
- Point the OCI image source label at the GitHub repository
- Drop redundant repository blocks from settings.gradle.kts
This commit is contained in:
siujamo committed 2026-09-01 16:08:22 +08:00
1 parent 685646f88e
commit aca203020e
8 files changed
+44 -52

No files matched your search

+1 -1
View File
@@ -12,7 +12,7 @@ LABEL org.opencontainers.image.title="ahsarah-guide-server" \
org.opencontainers.image.description="REST API backend for Ahsarah Guide" \
org.opencontainers.image.version="${IMAGE_VERSION}" \
org.opencontainers.image.vendor="${IMAGE_VENDOR}" \
org.opencontainers.image.source="https://onixbyte.dev/onixbyte/ahsarah-guide" \
org.opencontainers.image.source="https://github.com/onixbyte/ahsarah-guide" \
org.opencontainers.image.licenses="MIT" \
org.opencontainers.image.created="${BUILD_DATE}"
+16 -11
View File
@@ -23,6 +23,22 @@ java {
}
}
// Generate META-INF/build-info.properties at build time. The build version comes
// from the project version (driven by the git tag in CI); channel and vendor are
// stamped alongside it so the runtime no longer needs template placeholders.
springBoot {
buildInfo {
properties {
additional.set(
mapOf(
"channel" to buildChannel,
"vendor" to vendor
)
)
}
}
}
dependencies {
// BOMs are imported as platforms, so they cannot be bundled.
implementation(platform(libs.aws.sdk.bom))
@@ -48,17 +64,6 @@ dependencies {
testRuntimeOnly(libs.bundles.testRuntime)
}
tasks.processResources {
filesMatching("application.yaml") {
println("appVersion = ${artefactVersion}, channel = ${buildChannel}, vendor = ${vendor}")
expand(
"appVersion" to artefactVersion,
"channel" to buildChannel,
"vendor" to vendor
)
}
}
tasks.test {
useJUnitPlatform()
}
-13
View File
@@ -1,14 +1 @@
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
}
}
dependencyResolutionManagement {
repositories {
mavenCentral()
}
}
rootProject.name = "ahsarah-guide-server"
@@ -2,10 +2,8 @@ package com.onixbyte.ahsarahguide.config;
import com.onixbyte.ahsarahguide.interceptor.GitHubWebhookInterceptor;
import com.onixbyte.ahsarahguide.interceptor.TrafficInterceptor;
import com.onixbyte.ahsarahguide.properties.AppProperties;
import com.onixbyte.ahsarahguide.security.resolver.CurrentUserArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@@ -14,7 +12,6 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@Configuration
@EnableConfigurationProperties(AppProperties.class)
public class AppConfig implements WebMvcConfigurer {
private final TrafficInterceptor trafficInterceptor;
@@ -4,13 +4,16 @@ import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Contact;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.info.License;
import io.swagger.v3.oas.models.OpenAPI;
import org.springdoc.core.customizers.OpenApiCustomizer;
import org.springframework.boot.info.BuildProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@OpenAPIDefinition(
info = @Info(
title = "Ahsarah Guide Server",
description = "API for Ahsarah Guide",
version = "1.4.0",
contact = @Contact(
name = "Zihlu Wang",
email = "zihlu.wang@onixbyte.com"
@@ -23,4 +26,20 @@ import org.springframework.context.annotation.Configuration;
)
@Configuration
public class OpenApiConfiguration {
/**
* Overrides the OpenAPI info version with the packaged build version so the
* docs always match the released artefact instead of a hard-coded value.
*
* @param buildProperties the build-info properties generated at build time
* @return customiser that stamps the build version onto the API info
*/
@Bean
public OpenApiCustomizer versionCustomizer(BuildProperties buildProperties) {
return openApi -> {
if (openApi.getInfo() != null) {
openApi.getInfo().setVersion(buildProperties.getVersion());
}
};
}
}
@@ -1,15 +1,15 @@
package com.onixbyte.ahsarahguide.manager;
import com.onixbyte.ahsarahguide.properties.AppProperties;
import org.springframework.boot.info.BuildProperties;
import org.springframework.stereotype.Component;
@Component
public class AppManager {
private final AppProperties appProperties;
private final BuildProperties buildProperties;
public AppManager(AppProperties appProperties) {
this.appProperties = appProperties;
public AppManager(BuildProperties buildProperties) {
this.buildProperties = buildProperties;
}
/**
@@ -19,9 +19,9 @@ public class AppManager {
*/
public String getVersion() {
return "v%s-%s by @%s".formatted(
appProperties.version(),
appProperties.channel(),
appProperties.vendor()
buildProperties.getVersion(),
buildProperties.get("channel"),
buildProperties.get("vendor")
);
}
}
@@ -1,11 +0,0 @@
package com.onixbyte.ahsarahguide.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "app.common")
public record AppProperties(
String version,
String channel,
String vendor
) {
}
@@ -53,8 +53,3 @@ logging:
org.hibernate:
orm.connections.pooling: off
app:
common:
version: ${appVersion}
channel: ${channel}
vendor: ${vendor}