Skip to content

Spring Quartz에 Cluster를 이용한 schedule, workflow 실시간 반영 #431

Spring Quartz에 Cluster를 이용한 schedule, workflow 실시간 반영

Spring Quartz에 Cluster를 이용한 schedule, workflow 실시간 반영 #431

Workflow file for this run

name: CI (Java)
on:
push:
tags:
- 'user-service-v*'
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches:
- main
- develop
- release/**
paths:
- "apps/user-service/**"
- ".github/workflows/ci-java.yml"
permissions:
contents: write # Dependency graph 생성용
packages: write
security-events: write
checks: write
pull-requests: write
pages: write # GitHub Pages 배포
id-token: write # GitHub Pages 배포
actions: write
jobs:
dependency-submission:
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@v4
with:
build-root-directory: apps/user-service
spotless-check:
if: github.event.pull_request.draft == false
name: Lint Check
runs-on: ubuntu-latest
steps:
- name: Debug cache settings
run: |
echo "Event name: ${{ github.event_name }}"
echo "Event type: ${{ github.event.action }}"
echo "Cache read-only condition: ${{ github.event_name == 'pull_request' }}"
echo "GitHub ref: ${{ github.ref }}"
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
with:
cache-read-only: ${{ github.event_name == 'pull_request' }}
gradle-home-cache-cleanup: false
gradle-home-cache-includes: |
caches
notifications
wrapper
cache-write-only: false
- name: Grant execute permission for Gradle wrapper
run: chmod +x ./gradlew
working-directory: apps/user-service
- name: Run Spotless Check
run: ./gradlew spotlessCheck
working-directory: apps/user-service
build:
name: Build
runs-on: ubuntu-latest
needs: spotless-check
strategy:
matrix:
java-version: ["21"]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.java-version }}
uses: actions/setup-java@v4
with:
java-version: '${{ matrix.java-version }}'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
with:
cache-read-only: ${{ github.event_name == 'pull_request' }}
cache-write-only: false
- name: Grant execute permission for Gradle wrapper
run: chmod +x ./gradlew
working-directory: apps/user-service
- name: Run Gradle Build
run: ./gradlew build -x test
working-directory: apps/user-service
- name: Run Tests
run: |
./gradlew unitTest
./gradlew integrationTest
if [ "${{ github.base_ref }}" = "main" ] || [[ "${{ github.ref }}" == refs/tags/* ]]; then
./gradlew e2eTest
fi
working-directory: apps/user-service
- name: Generate document artifacts
run: |
./gradlew javadoc
if [ "${{ github.base_ref }}" = "main" ] || [[ "${{ github.ref }}" == refs/tags/* ]]; then
./gradlew openapi3
fi
working-directory: apps/user-service
- name: Upload build artifacts
if: matrix.java-version == '21' && startsWith(github.ref, 'refs/tags/')
uses: actions/upload-artifact@v4
with:
name: build-artifacts-${{ github.run_id }}-${{ github.run_attempt }}
path: apps/user-service/build/libs/
- name: Upload OpenAPI spec artifacts
if: matrix.java-version == '21' && startsWith(github.ref, 'refs/tags/')
uses: actions/upload-artifact@v4
with:
name: openapi-spec-${{ github.run_id }}-${{ github.run_attempt }}
path: apps/user-service/build/api-spec/
set-image-tag:
name: Set IMAGE_TAG
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/user-service-v')
outputs:
image-tag: ${{ steps.extract-tag.outputs.IMAGE_TAG }}
steps:
- name: Extract version from tag
id: extract-tag
run: |
IMAGE_TAG="${GITHUB_REF#refs/tags/user-service-}"
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_OUTPUT
echo "Extracted IMAGE_TAG: $IMAGE_TAG"
docker:
name: Build Spring Boot Docker Image and push
runs-on: ubuntu-latest
needs:
- build
- set-image-tag
if: startsWith(github.ref, 'refs/tags/user-service-v')
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download build artifacts (JAR)
uses: actions/download-artifact@v4
with:
name: build-artifacts-${{ github.run_id }}-${{ github.run_attempt }}
path: apps/user-service/build/libs/
- name: Login to Docker Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set repo lowercase
run: echo "REPO_LC=${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./apps/user-service
push: true
tags: |
ghcr.io/${{ env.REPO_LC }}/user-service:${{ needs.set-image-tag.outputs.image-tag }}
ghcr.io/${{ env.REPO_LC }}/user-service:latest
- name: Analyze image layers
run: |
echo "=== Image Layer Analysis ==="
docker history ghcr.io/${{ env.REPO_LC }}/user-service:${{ needs.set-image-tag.outputs.image-tag }} --human --no-trunc
swagger-docs:
name: Deploy Swagger Documentation
runs-on: ubuntu-latest
needs:
- build
- set-image-tag
if: startsWith(github.ref, 'refs/tags/user-service-v')
permissions:
contents: read # 리포지토리 읽기
pages: write # GitHub Pages 쓰기
id-token: write # OIDC 토큰
actions: read # Actions 읽기
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download OpenAPI spec artifacts
uses: actions/download-artifact@v4
with:
name: openapi-spec-${{ github.run_id }}-${{ github.run_attempt }}
path: ./openapi-spec
- name: Check OpenAPI spec file exists
id: check-openapi
run: |
if [ -f "./openapi-spec/openapi3.yaml" ]; then
echo "openapi_exists=true" >> $GITHUB_OUTPUT
echo "✅ OpenAPI spec file found"
ls -la ./openapi-spec/
else
echo "openapi_exists=false" >> $GITHUB_OUTPUT
echo "❌ OpenAPI spec file not found"
echo "Available files:"
ls -la ./openapi-spec/ || echo "No openapi-spec directory found"
find . -name "*.yaml" -o -name "*.yml" -o -name "*.json" | grep -i openapi || echo "No OpenAPI files found"
fi
- name: Generate Swagger UI
if: steps.check-openapi.outputs.openapi_exists == 'true'
uses: Legion2/swagger-ui-action@v1
with:
output: user-service-swagger-ui-${{ needs.set-image-tag.outputs.image-tag }}
spec-file: openapi-spec/openapi3.yaml
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy to GitHub Pages
if: steps.check-openapi.outputs.openapi_exists == 'true'
uses: peaceiris/actions-gh-pages@v3
with:
personal_token: ${{ secrets.PERSONAL_TOKEN }}
publish_dir: ./user-service-swagger-ui-${{ needs.set-image-tag.outputs.image-tag }}
destination_dir: user-service/${{ needs.set-image-tag.outputs.image-tag }}
- name: Skip deployment notice
if: steps.check-openapi.outputs.openapi_exists == 'false'
run: |
echo "⏭️ Skipping Swagger documentation deployment"
echo "Reason: OpenAPI spec file not found at ./openapi-spec/openapi3.yaml"
echo "Please check your build configuration to ensure OpenAPI spec is generated"