Compare commits

...

9 Commits

Author SHA1 Message Date
siujamo 0671937ecd feat: add versioning entrypoint 2026-05-26 10:18:27 +08:00
siujamo e2a40795c5 chore: opt-in to Node.js 24 for GitHub Actions to clear deprecation warning
Set the environment variable FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 to true
to force the workflow and runner to execute all JavaScript actions using
Node.js 24. This resolves the future deprecation warning for Node.js 20.
2026-05-25 16:01:19 +08:00
siujamo a8ff1cabad chore: rewrite GitHub Actions to build, publish release JAR, and push image to GHCR
Update build-and-deploy.yml workflow to:
1. Run single job 'build-and-release' to bypass artifact transfers.
2. Build JAR with -PartefactVersion parameter.
3. Upload the compiled JAR asset directly into GitHub Releases.
4. Build and push the Docker image directly to GitHub Container Registry (ghcr.io).
2026-05-25 15:52:54 +08:00
siujamo e4dca61f98 chore: merge CI stages into a single release job to optimize speed
Merge build, package, and deploy stages into a single 'release' job. By building
the jar and running docker commands in the same container using local docker socket,
we completely bypass the need for GitLab artifact uploading/downloading. This significantly
reduces network overhead and speeds up release deployment.
2026-05-25 15:43:23 +08:00
siujamo e7da3a76b7 ci: recover artefact uploading 2026-05-25 14:45:26 +08:00
siujamo 5cea825bc0 chore: remove gitlab artifacts to avoid slow uploads
Remove artifacts uploading from the build stage. Since we use a shared
docker socket on the same runner host, the package stage can access the
locally built jar file directly without needing gitlab coordinator upload/download.
2026-05-25 14:39:33 +08:00
siujamo bd2748e25c fix: disable provenance in docker build to fix GitLab Registry 0B display
Add `--provenance=false` flag to `docker build` command. This stops Docker BuildKit
from generating OCI Referrers/attestations, which are not correctly parsed by GitLab
Container Registry and cause the UI to display 0B size and "missing manifest digest" errors.
2026-05-25 13:58:14 +08:00
siujamo 0f1093774f fix: use GitLab predefined environment variables for container registry
Replace custom registry variables with GitLab's predefined CI_REGISTRY,
CI_REGISTRY_IMAGE, and CI_REGISTRY_USER to ensure the built-in CI_JOB_TOKEN
has correct push permissions.
2026-05-25 11:47:22 +08:00
siujamo d19b7f5563 fix: allow jar files to be copied in Docker build context
Add '!build/libs/*.jar' to .dockerignore so that Docker build can access the build
artifacts in the package stage.
2026-05-25 11:05:25 +08:00
8 changed files with 131 additions and 110 deletions
+2
View File
@@ -1,4 +1,6 @@
delta-force-guide-server.iml delta-force-guide-server.iml
build/ build/
!.gitlab-ci.yml
!build/libs/*.jar
.idea/ .idea/
.gradle .gradle
+34 -75
View File
@@ -6,15 +6,17 @@ on:
env: env:
APP_NAME: delta-force-guide-server APP_NAME: delta-force-guide-server
IMAGE_REGISTRY: ${{ vars.GITLAB_REGISTRY }} FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
IMAGE_NAME: ${{ vars.GITLAB_IMAGE_NAME }}
jobs: jobs:
# ================================================================ # ================================================================
# Job 1 — Package: build the JAR with Gradle # Single Job: Build, Upload JAR to Release, and Push to GHCR
# ================================================================ # ================================================================
package: build-and-release:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -28,54 +30,47 @@ jobs:
- name: Set up Gradle - name: Set up Gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@v4
# 使用 Release Tag 做为 Gradle 属性传入
- name: Build with Gradle - name: Build with Gradle
run: ./gradlew build run: ./gradlew bootJar -x test -PartefactVersion="${{ github.event.release.tag_name }}"
- name: Upload JAR artifact
uses: actions/upload-artifact@v4
with:
name: app-jar
path: build/libs/delta-force-guide-server-*.jar
retention-days: 1
# ================================================================
# Job 2 — Build & push Docker image to GitHub Container Registry
# ================================================================
build-and-push:
needs: package
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Download JAR artifact
uses: actions/download-artifact@v4
with:
name: app-jar
path: build/libs
- name: Resolve JAR file path - name: Resolve JAR file path
id: jar id: jar
run: echo "file=$(ls build/libs/delta-force-guide-server-*.jar | head -1)" >> "$GITHUB_OUTPUT" run: |
JAR_PATH=$(find build/libs -name '*.jar' | head -1)
echo "file=$JAR_PATH" >> "$GITHUB_OUTPUT"
# 上传 JAR 包到 GitHub Release 中
- name: Upload JAR to GitHub Release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ${{ steps.jar.outputs.file }}
asset_name: ${{ github.event.repository.name }}-${{ github.event.release.tag_name }}.jar
tag: ${{ github.event.release.tag_name }}
overwrite: true
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Log in to GitLab Container Registry # 登录到 GitHub Container Registry (GHCR)
- name: Log in to GHCR
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ${{ env.IMAGE_REGISTRY }} registry: ghcr.io
username: ${{ vars.GITLAB_REGISTRY_USER }} username: ${{ github.actor }}
password: ${{ secrets.GITLAB_REGISTRY_PASSWORD }} password: ${{ secrets.GITHUB_TOKEN }}
# 镜像打标签准备
- name: Generate image tags - name: Generate image tags
id: meta id: meta
run: | run: |
echo "version=${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT" OWNER_LC=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
echo "latest=${{ env.IMAGE_NAME }}:latest" >> "$GITHUB_OUTPUT" REPO_LC=$(echo "${{ github.event.repository.name }}" | tr '[:upper:]' '[:lower:]')
echo "tag_version=ghcr.io/$OWNER_LC/$REPO_LC:${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT"
echo "tag_latest=ghcr.io/$OWNER_LC/$REPO_LC:latest" >> "$GITHUB_OUTPUT"
# 构建并上传镜像到 GHCR
- name: Build and push Docker image - name: Build and push Docker image
uses: docker/build-push-action@v6 uses: docker/build-push-action@v6
with: with:
@@ -84,44 +79,8 @@ jobs:
build-args: JAR_FILE=${{ steps.jar.outputs.file }} build-args: JAR_FILE=${{ steps.jar.outputs.file }}
push: true push: true
tags: | tags: |
${{ steps.meta.outputs.version }} ${{ steps.meta.outputs.tag_version }}
${{ steps.meta.outputs.latest }} ${{ steps.meta.outputs.tag_latest }}
cache-from: type=gha cache-from: type=gha
cache-to: type=gha,mode=max cache-to: type=gha,mode=max
# ================================================================
# Job 3 — Deploy on the target server via SSH
# ================================================================
deploy:
needs: build-and-push
runs-on: ubuntu-latest
steps:
- name: Deploy via SSH
uses: appleboy/ssh-action@v1.2.0
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
script: |
set -e
echo '=== Pulling image ==='
echo '${{ secrets.GITLAB_REGISTRY_PASSWORD }}' | docker login ${{ env.IMAGE_REGISTRY }} \
-u ${{ vars.GITLAB_REGISTRY_USER }} --password-stdin
docker pull ${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}
echo '=== Stopping old container ==='
docker stop ${{ env.APP_NAME }} || true
docker rm ${{ env.APP_NAME }} || true
echo '=== Starting new container ==='
docker run -d \
--name ${{ env.APP_NAME }} \
--restart unless-stopped \
-p ${DEPLOY_PORT:-8080}:8080 \
${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}
echo '=== Cleaning up old images ==='
docker image prune -f
echo '=== Deployment complete ==='
+11 -35
View File
@@ -1,16 +1,12 @@
variables: variables:
REGISTRY: registry.onixbyte.cn
IMAGE_NAME: delta-force-guide
GRADLE_OPTS: -Dorg.gradle.daemon=false GRADLE_OPTS: -Dorg.gradle.daemon=false
DOCKER_HOST: unix:///var/run/docker.sock DOCKER_HOST: unix:///var/run/docker.sock
stages: stages:
- build - release
- package
- deploy
build: release:
stage: build stage: release
image: amazoncorretto:21-alpine image: amazoncorretto:21-alpine
cache: cache:
key: gradle key: gradle
@@ -19,41 +15,21 @@ build:
- .gradle/caches - .gradle/caches
before_script: before_script:
- chmod +x gradlew - chmod +x gradlew
- apk add --no-cache docker-cli
script: script:
- ./gradlew bootJar -x test -PartefactVersion="$CI_COMMIT_TAG" - ./gradlew bootJar -x test -PartefactVersion="$CI_COMMIT_TAG"
artifacts:
paths:
- build/libs/*.jar
expire_in: 30 min
rules:
- if: $CI_COMMIT_TAG
package:
stage: package
image: docker:27
needs:
- build
script:
- JAR_FILE=$(find build/libs -name '*.jar' | head -1) - JAR_FILE=$(find build/libs -name '*.jar' | head -1)
- echo "Building Docker image for tag $CI_COMMIT_TAG with JAR $JAR_FILE" - echo "Building Docker image for tag $CI_COMMIT_TAG with JAR $JAR_FILE"
- docker build - docker build
--provenance=false
-f Dockerfile.ci -f Dockerfile.ci
--build-arg JAR_FILE="$JAR_FILE" --build-arg JAR_FILE="$JAR_FILE"
-t "$REGISTRY/$IMAGE_NAME:$CI_COMMIT_TAG" -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG"
. .
- docker tag "$REGISTRY/$IMAGE_NAME:$CI_COMMIT_TAG" "$REGISTRY/$IMAGE_NAME:latest" - docker tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG" "$CI_REGISTRY_IMAGE:latest"
rules: - echo "Pushing image $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG"
- if: $CI_COMMIT_TAG - docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG"
deploy: - docker push "$CI_REGISTRY_IMAGE:latest"
stage: deploy
image: docker:27
needs:
- package
script:
- echo "Pushing image $REGISTRY/$IMAGE_NAME:$CI_COMMIT_TAG"
- docker login "$REGISTRY" -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"
- docker push "$REGISTRY/$IMAGE_NAME:$CI_COMMIT_TAG"
- docker push "$REGISTRY/$IMAGE_NAME:latest"
rules: rules:
- if: $CI_COMMIT_TAG - if: $CI_COMMIT_TAG
@@ -0,0 +1,10 @@
package com.onixbyte.deltaforceguide.config;
import com.onixbyte.deltaforceguide.properties.AppProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(AppProperties.class)
public class AppConfig {
}
@@ -0,0 +1,24 @@
package com.onixbyte.deltaforceguide.controller;
import com.onixbyte.deltaforceguide.service.AppService;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/versions")
public class VersionController {
private final AppService appService;
public VersionController(AppService appService) {
this.appService = appService;
}
@Operation(description = "获取当前应用版本号")
@GetMapping
public String getVersion() {
return appService.getVersion();
}
}
@@ -0,0 +1,23 @@
package com.onixbyte.deltaforceguide.manager;
import com.onixbyte.deltaforceguide.properties.AppProperties;
import org.springframework.stereotype.Component;
@Component
public class AppManager {
private final AppProperties appProperties;
public AppManager(AppProperties appProperties) {
this.appProperties = appProperties;
}
/**
* Retrieves the application version.
*
* @return the version string of this application
*/
public String getVersion() {
return appProperties.version();
}
}
@@ -0,0 +1,9 @@
package com.onixbyte.deltaforceguide.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "app.common")
public record AppProperties(
String version
) {
}
@@ -0,0 +1,18 @@
package com.onixbyte.deltaforceguide.service;
import com.onixbyte.deltaforceguide.manager.AppManager;
import org.springframework.stereotype.Service;
@Service
public class AppService {
private final AppManager appManager;
public AppService(AppManager appManager) {
this.appManager = appManager;
}
public String getVersion() {
return appManager.getVersion();
}
}