Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e827481
Update create-jira-issue.yml
doyeonk429 Oct 1, 2025
8338fbe
Update close-jira-issue.yml
doyeonk429 Oct 1, 2025
040137b
Update close-jira-issue.yml
doyeonk429 Oct 1, 2025
6007d66
[BOOK-324] fix: 내서재와 독서기록 기본정렬을 수정합니다. (#117) (#118)
minwoo1999 Oct 5, 2025
68085fa
Revise README with project overview and features
minwoo1999 Oct 20, 2025
dd42e15
feat: 멀티 애플리케이션 배포 기능 구현 (#124)
move-hoon Oct 20, 2025
bf2399d
hotfix: Discord 알림 step들에서 shell: bash 제거
move-hoon Oct 20, 2025
7dad91f
chore: ci/cd trigger를 위한 주석 추가
move-hoon Oct 20, 2025
8b202f4
feat: 알림기능을 개발합니다. (#123)
minwoo1999 Oct 21, 2025
00db8c8
hotfix: prod CI/CD 워크플로우 수정
move-hoon Oct 22, 2025
72af904
hotfix: FcmConfig를 test 환경에서 임시 제외 및 ComponentScan 범위 수정
move-hoon Oct 22, 2025
ec11ea2
hotfix: module-name batch로 수정 및 사용하지 않는 Swagger 설정 제거
move-hoon Oct 22, 2025
5fa446c
refactor: 기본정렬과 동적정렬 UPDATE시간으로도 가능하도록 수정 , 감상평 Optional (#126)
minwoo1999 Oct 25, 2025
76ea1c7
hotfix: 독서기록 review optional하게 처리
minwoo1999 Oct 26, 2025
84ffad8
hotfix: dev flyway false 적용
minwoo1999 Oct 26, 2025
9a5515e
feat: 사용자별 다중 디바이스 알림 전송 기능 추가 및 리팩토링 (#128)
minwoo1999 Nov 6, 2025
0cfb1c3
hotfix: eclipse-temurin:21-jdk로 변경
move-hoon Nov 6, 2025
b55b7fc
hotfix: .github 파일 변동 시에도 ci-cd 작동하도록 수정
move-hoon Nov 6, 2025
a9260f5
[BOOK-433] refactor: 멀티디바이스에서 유효하지 않은 FID/FCM 토큰 정리 로직 추가 (#129) (#130)
minwoo1999 Nov 9, 2025
f55eaa3
hotfix: apis,domain,infra - test api
minwoo1999 Nov 13, 2025
6b4c9e8
feat: device, notification, users에 대한 sql문 추가 (#132)
move-hoon Nov 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 177 additions & 0 deletions .github/actions/deploy-module/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
name: 'Deploy Module'
description: 'Build, push and deploy a module to server (dev/prod)'

inputs:
environment:
description: 'Environment (dev or prod)'
required: true
module:
description: 'Module name (apis, admin, batch)'
required: true
port:
description: 'Server port (for logging only - actual port defined in docker-compose.yml)'
required: false
default: 'N/A'
dockerhub-username:
description: 'Docker Hub username'
required: true
dockerhub-token:
description: 'Docker Hub token'
required: true
secret-properties:
description: 'Secret properties (dev or prod)'
required: true
apple-auth-key:
description: 'Apple Auth Key'
required: true
host:
description: 'Server host'
required: true
username:
description: 'Server username'
required: true
ssh-key:
description: 'Server SSH key'
required: true
ssh-port:
description: 'Server SSH port'
required: true
discord-webhook-url:
description: 'Discord webhook URL'
required: true
image-prefix:
description: 'Docker image prefix'
required: true
image-tag-type:
description: 'Image tag type (development-latest or semver)'
required: true
deploy-script:
description: 'Deploy script name (deploy-dev.sh or deploy-prod.sh)'
required: true
default: 'deploy-dev.sh'
release-version:
description: 'Release version tag (e.g., v1.2.3). Only used in production for metadata tracking.'
required: false
default: 'unknown'

runs:
using: 'composite'
steps:
- name: Inject application-secret.properties from Secrets
shell: bash
run: |
mkdir -p ./secret
echo "$SECRET_CONTENT" > ./secret/application-${{ inputs.environment }}-secret.properties
echo "$APPLE_KEY_CONTENT" > ./secret/AuthKey.p8
chmod 600 ./secret/*
env:
SECRET_CONTENT: ${{ inputs.secret-properties }}
APPLE_KEY_CONTENT: ${{ inputs.apple-auth-key }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ inputs.dockerhub-username }}
password: ${{ inputs.dockerhub-token }}

- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: docker.io/${{ inputs.image-prefix }}-${{ inputs.module }}
tags: ${{ inputs.image-tag-type }}

- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha,scope=${{ inputs.module }}
cache-to: type=gha,mode=max,scope=${{ inputs.module }}
build-args: |
MODULE=${{ inputs.module }}

- name: Deploy to Server
uses: appleboy/ssh-action@v1.2.2
with:
host: ${{ inputs.host }}
username: ${{ inputs.username }}
key: ${{ inputs.ssh-key }}
port: ${{ inputs.ssh-port }}
script: |
export DOCKERHUB_USERNAME="${{ inputs.dockerhub-username }}"
export DOCKERHUB_TOKEN="${{ inputs.dockerhub-token }}"
export MODULE="${{ inputs.module }}"
export SPRING_PROFILE="${{ inputs.environment }}"
export IMAGE_TAG="$(echo "${{ steps.meta.outputs.tags }}" | head -n1)"
export RELEASE_VERSION="${{ inputs.release-version }}"
cd ~/deploy
chmod +x ./${{ inputs.deploy-script }}
./${{ inputs.deploy-script }}

- name: Send Discord notification on success (Development)
uses: tsickert/discord-webhook@b217a69502f52803de774ded2b1ab7c282e99645
if: success() && inputs.environment == 'dev'
continue-on-error: true
with:
webhook-url: ${{ inputs.discord-webhook-url }}
embed-title: "✅ [${{ github.repository }}] Development Deploy Succeeded - ${{ inputs.module }}"
embed-description: |
**Module**: `${{ inputs.module }}`
**Commit**: `${{ github.sha }}`
**Author**: `${{ github.actor }}`
**Message**: `${{ github.event.head_commit.message }}`
[View Committed Changes](https://github.com/${{ github.repository }}/commit/${{ github.sha }})
embed-color: 65280

- name: Send Discord notification on success (Production)
uses: tsickert/discord-webhook@b217a69502f52803de774ded2b1ab7c282e99645
if: success() && inputs.environment == 'prod'
continue-on-error: true
with:
webhook-url: ${{ inputs.discord-webhook-url }}
content: "🚀 **Production Deploy Succeeded!**"
embed-title: "✅ [${{ github.repository }}] Production Deploy Succeeded - ${{ inputs.module }}"
embed-description: |
**Module**: `${{ inputs.module }}`
**Deployed by**: `${{ github.actor }}`
The new version has been successfully deployed to production.
[View Workflow](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
embed-color: 65280

- name: Send Discord notification on failure (Development)
uses: tsickert/discord-webhook@b217a69502f52803de774ded2b1ab7c282e99645
if: failure() && inputs.environment == 'dev'
continue-on-error: true
with:
webhook-url: ${{ inputs.discord-webhook-url }}
embed-title: "❌ [${{ github.repository }}] Development Deploy Failed - ${{ inputs.module }}"
embed-description: |
**Module**: `${{ inputs.module }}`
**Commit**: `${{ github.sha }}`
**Author**: `${{ github.actor }}`
An error occurred during the workflow execution.
[View Failed Workflow](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
embed-color: 16711680

- name: Send Discord notification on failure (Production)
uses: tsickert/discord-webhook@b217a69502f52803de774ded2b1ab7c282e99645
if: failure() && inputs.environment == 'prod'
continue-on-error: true
with:
webhook-url: ${{ inputs.discord-webhook-url }}
content: "🚨 **Production Deploy Failed!**"
embed-title: "❌ [${{ github.repository }}] Production Deploy Failed - ${{ inputs.module }}"
embed-description: |
**Module**: `${{ inputs.module }}`
**Deployed by**: `${{ github.actor }}`
An error occurred during the production deployment workflow.
[View Failed Workflow](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
embed-color: 16711680
6 changes: 5 additions & 1 deletion .github/workflows/ci-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,8 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: ./gradlew fullCheck --parallel --build-cache --info --stacktrace
run: |
# fullCheck: 모든 모듈 (apis, admin, batch, gateway 등)의 빌드, 테스트, 정적분석 수행
# --parallel: 모듈별 병렬 빌드로 시간 단축
# --build-cache: Gradle 빌드 캐시 사용
./gradlew fullCheck --parallel --build-cache --info --stacktrace
2 changes: 1 addition & 1 deletion .github/workflows/close-jira-issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ jobs:
uses: atlassian/gajira-transition@v3
with:
issue: ${{ env.JIRA_KEY }}
transition: "31"
transition: 개발 완료
2 changes: 1 addition & 1 deletion .github/workflows/create-jira-issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ jobs:
uses: atlassian/gajira-create@v3
with:
project: BOOK
issuetype: Task
issuetype: 하위 작업
summary: '${{ github.event.issue.title }}'
description: '${{ steps.md2jira.outputs.output-text }}'
fields: |
Expand Down
155 changes: 76 additions & 79 deletions .github/workflows/dev-ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,96 +11,93 @@ concurrency:

env:
REGISTRY: docker.io
IMAGE_NAME: ninecraft0523/ninecraft-server
MODULE: apis
IMAGE_PREFIX: ninecraft0523/ninecraft

jobs:
build-push-and-deploy:
detect-changes:
runs-on: ubuntu-24.04
timeout-minutes: 20
environment: development

outputs:
apis: ${{ steps.filter.outputs.apis }}
# admin: ${{ steps.filter.outputs.admin }} # TODO: Uncomment when admin module is ready
batch: ${{ steps.filter.outputs.batch }}
any: ${{ steps.filter.outputs.any }}
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Inject application-secret.properties from Secrets
run: |
mkdir ./secret
echo "${{ secrets.DEV_SECRET_PROPERTIES }}" > ./secret/application-dev-secret.properties
echo "${{ secrets.APPLE_AUTH_KEY }}" > ./secret/AuthKey.p8
chmod 600 ./secret/*

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
uses: docker/login-action@v3
- name: Check changed files
uses: dorny/paths-filter@v3
id: filter
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
filters: |
apis:
- 'apis/**'
- 'domain/**'
- 'infra/**'
- 'global-utils/**'
- 'observability/**'
- '.github/**'
# admin: # TODO: Uncomment when admin module is ready
# - 'admin/**'
# - 'domain/**'
# - 'infra/**'
# - 'global-utils/**'
# - 'observability/**'
# - '.github/**'
batch:
- 'batch/**'
- 'domain/**'
- 'infra/**'
- 'global-utils/**'
- 'observability/**'
- '.github/**'
any:
- 'apis/**'
# - 'admin/**' # TODO: Uncomment when admin module is ready
- 'batch/**'
- 'domain/**'
- 'infra/**'
- 'global-utils/**'
- 'observability/**'
- '.github/**'

- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=development-latest
build-push-and-deploy:
needs: detect-changes
if: needs.detect-changes.outputs.any == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 20
environment: development
strategy:
fail-fast: false
matrix:
include:
- module: apis
changed: ${{ needs.detect-changes.outputs.apis }}
# - module: admin # TODO: Uncomment when admin module is ready
# changed: ${{ needs.detect-changes.outputs.admin }}
- module: batch
changed: ${{ needs.detect-changes.outputs.batch }}

- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
MODULE=${{ env.MODULE }}
steps:
- name: Checkout code
if: matrix.changed == 'true'
uses: actions/checkout@v4

- name: Deploy to Development Server
uses: appleboy/ssh-action@v1.2.2
- name: Deploy module
if: matrix.changed == 'true'
uses: ./.github/actions/deploy-module
with:
environment: dev
module: ${{ matrix.module }}
dockerhub-username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }}
secret-properties: ${{ secrets.DEV_SECRET_PROPERTIES }}
apple-auth-key: ${{ secrets.APPLE_AUTH_KEY }}
host: ${{ secrets.DEV_HOST }}
username: ${{ secrets.DEV_USERNAME }}
key: ${{ secrets.DEV_SSH_KEY }}
port: ${{ secrets.DEV_PORT }}
script: |
export DOCKERHUB_USERNAME="${{ secrets.DOCKERHUB_USERNAME }}"
export DOCKERHUB_TOKEN="${{ secrets.DOCKERHUB_TOKEN }}"
export IMAGE_TAG="$(echo "${{ steps.meta.outputs.tags }}" | head -n1)"
cd ~/deploy
chmod +x ./deploy.sh
./deploy.sh

- name: Send Discord notification on success
uses: tsickert/discord-webhook@b217a69502f52803de774ded2b1ab7c282e99645
if: success()
continue-on-error: true
with:
webhook-url: ${{ secrets.DEV_DEPLOY_DISCORD_WEBHOOK_URL }}
embed-title: "✅ [${{ github.repository }}] Development Deploy Succeeded"
embed-description: |
**Commit**: `${{ github.sha }}`
**Author**: `${{ github.actor }}`
**Message**: `${{ github.event.head_commit.message }}`
[View Committed Changes](https://github.com/${{ github.repository }}/commit/${{ github.sha }})
embed-color: 65280

- name: Send Discord notification on failure
uses: tsickert/discord-webhook@b217a69502f52803de774ded2b1ab7c282e99645
if: failure()
continue-on-error: true
with:
webhook-url: ${{ secrets.DEV_DEPLOY_DISCORD_WEBHOOK_URL }}
embed-title: "❌ [${{ github.repository }}] Development Deploy Failed"
embed-description: |
**Commit**: `${{ github.sha }}`
**Author**: `${{ github.actor }}`
An error occurred during the workflow execution.
[View Failed Workflow](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
embed-color: 16711680
ssh-key: ${{ secrets.DEV_SSH_KEY }}
ssh-port: ${{ secrets.DEV_PORT }}
discord-webhook-url: ${{ secrets.DEV_DEPLOY_DISCORD_WEBHOOK_URL }}
image-prefix: ${{ env.IMAGE_PREFIX }}
image-tag-type: type=raw,value=development-latest
deploy-script: deploy-dev.sh
Loading