mirror of
https://github.com/booklore-app/booklore.git
synced 2026-02-18 00:17:53 +01:00
Implement version info endpoint and update version display in UI
This commit is contained in:
committed by
Aditya Chandel
parent
6d1384aac4
commit
70a4360207
2
.github/workflows/docker-build-publish.yml
vendored
2
.github/workflows/docker-build-publish.yml
vendored
@@ -100,7 +100,7 @@ jobs:
|
||||
docker buildx create --use
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--build-arg UI_VERSION=${{ env.image_tag }} \
|
||||
--build-arg APP_VERSION=${{ env.image_tag }} \
|
||||
--tag ghcr.io/${{ github.actor }}/booklore-app:${{ env.image_tag }} \
|
||||
--push .
|
||||
|
||||
|
||||
11
Dockerfile
11
Dockerfile
@@ -7,9 +7,6 @@ COPY ./booklore-ui/package.json ./booklore-ui/package-lock.json ./
|
||||
RUN npm install --force
|
||||
COPY ./booklore-ui /angular-app/
|
||||
|
||||
ARG UI_VERSION=development
|
||||
RUN echo "export const version = '${UI_VERSION}';" > /angular-app/src/environments/version.ts
|
||||
|
||||
RUN npm run build --configuration=production
|
||||
|
||||
# Stage 2: Build the Spring Boot app with Gradle
|
||||
@@ -21,10 +18,16 @@ COPY ./booklore-api/gradlew ./booklore-api/gradle/ /springboot-app/
|
||||
COPY ./booklore-api/build.gradle ./booklore-api/settings.gradle /springboot-app/
|
||||
COPY ./booklore-api/gradle /springboot-app/gradle
|
||||
COPY ./booklore-api/src /springboot-app/src
|
||||
COPY ./booklore-api/src/main/resources/application.yaml /springboot-app/src/main/resources/application.yaml
|
||||
|
||||
# Inject version into application.yaml using yq
|
||||
ARG APP_VERSION
|
||||
RUN apk add --no-cache yq && \
|
||||
yq eval '.app.version = strenv(APP_VERSION)' -i /springboot-app/src/main/resources/application.yaml
|
||||
|
||||
RUN ./gradlew clean build
|
||||
|
||||
# Stage 3: Final image combining everything
|
||||
# Stage 3: Final image
|
||||
FROM eclipse-temurin:21.0.5_11-jre-alpine
|
||||
|
||||
RUN apk update && apk add nginx
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.adityachandel.booklore.controller;
|
||||
|
||||
import com.adityachandel.booklore.model.dto.VersionInfo;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/version")
|
||||
public class VersionController {
|
||||
|
||||
@Value("${app.version:unknown}")
|
||||
private String appVersion;
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<VersionInfo> getVersions() {
|
||||
String latestVersion = fetchLatestGitHubReleaseVersion();
|
||||
return ResponseEntity.ok(new VersionInfo(appVersion, latestVersion));
|
||||
}
|
||||
|
||||
private String fetchLatestGitHubReleaseVersion() {
|
||||
try {
|
||||
RestClient restClient = RestClient.builder()
|
||||
.defaultHeader("Accept", "application/vnd.github+json")
|
||||
.defaultHeader("User-Agent", "BookLore-Version-Checker")
|
||||
.build();
|
||||
|
||||
String response = restClient.get()
|
||||
.uri("https://api.github.com/repos/adityachandelgit/BookLore/releases/latest")
|
||||
.retrieve()
|
||||
.body(String.class);
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode root = objectMapper.readTree(response);
|
||||
return root.has("tag_name") ? root.get("tag_name").asText() : "unknown";
|
||||
|
||||
} catch (Exception e) {
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.adityachandel.booklore.model.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class VersionInfo {
|
||||
private String current;
|
||||
private String latest;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
app:
|
||||
path-book: '/app/books'
|
||||
path-config: '/app/data'
|
||||
version: 'development'
|
||||
|
||||
spring:
|
||||
servlet:
|
||||
|
||||
22
booklore-ui/src/app/core/service/version.service.ts
Normal file
22
booklore-ui/src/app/core/service/version.service.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import {API_CONFIG} from '../../config/api-config';
|
||||
|
||||
export interface AppVersion {
|
||||
current: string;
|
||||
latest: string;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class VersionService {
|
||||
private versionUrl = `${API_CONFIG.BASE_URL}/api/v1/version`;
|
||||
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
getVersion(): Observable<AppVersion> {
|
||||
return this.http.get<AppVersion>(this.versionUrl);
|
||||
}
|
||||
}
|
||||
@@ -28,17 +28,28 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<p style="margin-top: auto;" class="p-4 text-center w-full">
|
||||
<a
|
||||
[href]="getVersionUrl(version)"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-gray-300 hover:underline hover:text-gray-500">
|
||||
{{ version }}
|
||||
</a>
|
||||
</p>
|
||||
<ng-container *ngIf="versionInfo">
|
||||
<div style="margin-top: auto;" class="p-4 text-center w-full text-sm">
|
||||
<div class="text-gray-200">
|
||||
<a
|
||||
[href]="getVersionUrl(versionInfo.current)"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="hover:underline hover:text-gray-100 text-sm"
|
||||
>
|
||||
{{ versionInfo.current }}
|
||||
</a>
|
||||
</div>
|
||||
<div *ngIf="versionInfo.latest && versionInfo.latest !== versionInfo.current">
|
||||
<a
|
||||
[href]="getVersionUrl(versionInfo.latest)"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="text-orange-400 hover:underline hover:text-orange-300 text-xs"
|
||||
>
|
||||
(Update)
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import {map} from 'rxjs/operators';
|
||||
import {ShelfService} from '../../../book/service/shelf.service';
|
||||
import {BookService} from '../../../book/service/book.service';
|
||||
import {LibraryShelfMenuService} from '../../../book/service/library-shelf-menu.service';
|
||||
import {version} from '../../../../environments/version';
|
||||
import {AppVersion, VersionService} from '../../../core/service/version.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-menu',
|
||||
@@ -20,15 +20,20 @@ export class AppMenuComponent implements OnInit {
|
||||
shelfMenu$: Observable<any> | undefined;
|
||||
homeMenu$: Observable<any> | undefined;
|
||||
|
||||
versionInfo: AppVersion | null = null;
|
||||
|
||||
private libraryService = inject(LibraryService);
|
||||
private shelfService = inject(ShelfService);
|
||||
private bookService = inject(BookService);
|
||||
private versionService = inject(VersionService);
|
||||
private libraryShelfMenuService = inject(LibraryShelfMenuService);
|
||||
|
||||
protected readonly version = version;
|
||||
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
this.versionService.getVersion().subscribe((data) => {
|
||||
this.versionInfo = data;
|
||||
});
|
||||
|
||||
this.libraryMenu$ = this.libraryService.libraryState$.pipe(
|
||||
map((state) => [
|
||||
{
|
||||
@@ -89,12 +94,12 @@ export class AppMenuComponent implements OnInit {
|
||||
);
|
||||
}
|
||||
|
||||
getVersionUrl(version: string): string {
|
||||
getVersionUrl(version: string | undefined): string {
|
||||
if (!version) return '#';
|
||||
if (version.startsWith('v')) {
|
||||
return `https://github.com/adityachandelgit/BookLore/releases/tag/${version}`;
|
||||
} else {
|
||||
return `https://github.com/adityachandelgit/BookLore/commit/${version}`;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export const version = 'v0.0.0';
|
||||
Reference in New Issue
Block a user