Skip to content

fix/BU-231: 근태 조회 API attendances 테이블 조회 및 v1 엔드포인트 통일 #145

fix/BU-231: 근태 조회 API attendances 테이블 조회 및 v1 엔드포인트 통일

fix/BU-231: 근태 조회 API attendances 테이블 조회 및 v1 엔드포인트 통일 #145

Workflow file for this run

name: Build-Up CI Pipeline
on:
pull_request:
branches: [ 'main', 'develop' ]
push:
branches: [ 'main', 'develop' ]
# 동일한 브랜치에 대해 중복 실행 방지
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
# ---------------------------------
# 1. Repo Checkout
# ---------------------------------
- name: 📥 Checkout repository
uses: actions/checkout@v4
# ---------------------------------
# 2. Set up Java 21
# ---------------------------------
- name: ☕ Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
cache: 'gradle'
# ---------------------------------
# 3. Gradle Wrapper 실행 권한 부여
# ---------------------------------
- name: 🔧 Grant execute permission for Gradle Wrapper
run: chmod +x ./gradlew
# ---------------------------------
# 4. 테스트 실행
# ---------------------------------
- name: 🧪 Run Tests
run: ./gradlew test --no-daemon --stacktrace
env:
SPRING_PROFILES_ACTIVE: test
# 테스트용 더미 값 (application-test.yml의 기본값 사용)
JWT_SECRET: test-secret-key-min-256-bits-long-for-hs256-algorithm-test
ENCRYPTION_KEY: 0123456789abcdef0123456789abcdef
# 테스트는 H2 DB를 사용하므로 MySQL 설정 불필요
# ---------------------------------
# 5. 테스트 결과 업로드
# ---------------------------------
- name: 📊 Upload Test Report
if: always()
uses: actions/upload-artifact@v4
with:
name: test-report
path: build/reports/tests/test/
retention-days: 7
# ---------------------------------
# 6. 테스트 커버리지 리포트 (선택사항)
# ---------------------------------
- name: 📈 Upload Coverage Report
if: always()
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: build/reports/jacoco/test/html/
retention-days: 7
# ---------------------------------
# 7. 애플리케이션 빌드
# ---------------------------------
- name: 🏗️ Build Application
run: ./gradlew clean build -x test --no-daemon
env:
# 빌드용 더미 값 (실제 런타임에서는 사용되지 않음)
JWT_SECRET: ${{ secrets.JWT_SECRET || 'test-secret-key-min-256-bits-long-for-hs256-algorithm-test' }}
ENCRYPTION_KEY: ${{ secrets.ENCRYPTION_KEY || '0123456789abcdef0123456789abcdef' }}
# ---------------------------------
# 8. JAR 파일 업로드
# ---------------------------------
- name: 📦 Upload JAR Artifact
uses: actions/upload-artifact@v4
with:
name: buildup-jar
path: build/libs/*.jar
retention-days: 7
docker-build:
needs: build-and-test
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
# ---------------------------------
# 1. Repo Checkout
# ---------------------------------
- name: 📥 Checkout repository
uses: actions/checkout@v4
# ---------------------------------
# 2. Docker Buildx 설정
# ---------------------------------
- name: 🐳 Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# ---------------------------------
# 3. Docker Image Build (Push 없이)
# ---------------------------------
- name: 🏗️ Build Docker image
uses: docker/build-push-action@v5
with:
context: .
push: false
tags: buildup:pr-${{ github.event.pull_request.number }}
load: true
cache-from: type=gha
cache-to: type=gha,mode=max
# ---------------------------------
# 4. Docker 컨테이너 실행 테스트
# ---------------------------------
- name: 🧪 Test Docker container
run: |
# Docker 네트워크 생성
docker network create buildup-test-network
# MySQL 컨테이너 시작 (테스트용)
docker run -d --name mysql-test \
--network buildup-test-network \
-e MYSQL_ROOT_PASSWORD=test_root_pass \
-e MYSQL_DATABASE=buildup_test \
-e MYSQL_USER=buildup_user \
-e MYSQL_PASSWORD=test_pass \
mysql:8.0
echo "⏳ MySQL 시작 대기 중..."
sleep 20
# 애플리케이션 컨테이너 시작
docker run -d --name buildup-test \
--network buildup-test-network \
-e SPRING_PROFILES_ACTIVE=dev \
-e JWT_SECRET=test-secret-key-min-256-bits-long-for-hs256-algorithm-test \
-e ENCRYPTION_KEY=0123456789abcdef0123456789abcdef \
-e SPRING_DATASOURCE_URL="jdbc:mysql://mysql-test:3306/buildup_test?useSSL=false&allowPublicKeyRetrieval=true" \
-e SPRING_DATASOURCE_USERNAME=buildup_user \
-e SPRING_DATASOURCE_PASSWORD=test_pass \
-e ADMIN_USERNAME=admin \
-e ADMIN_PASSWORD=test_admin_pass \
-e AWS_S3_ENABLED=false \
-e AWS_S3_BUCKET=test-bucket \
-e AWS_REGION=ap-northeast-2 \
-e AWS_ACCESS_KEY_ID=test-key \
-e AWS_SECRET_ACCESS_KEY=test-secret \
buildup:pr-${{ github.event.pull_request.number }}
echo "⏳ 애플리케이션 시작 대기 중..."
sleep 40
# 헬스체크
if docker ps | grep buildup-test; then
echo "✅ Docker 컨테이너 정상 실행 중"
# 로그 확인
echo "📋 컨테이너 로그 (마지막 50줄):"
docker logs buildup-test --tail 50
# 헬스체크 엔드포인트 확인
CONTAINER_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' buildup-test)
echo "🔍 헬스체크 테스트: http://${CONTAINER_IP}:8080/api/actuator/health"
# 정리
docker stop buildup-test
docker rm buildup-test
docker stop mysql-test
docker rm mysql-test
docker network rm buildup-test-network
echo "✅ Docker 컨테이너 테스트 완료"
else
echo "❌ Docker 컨테이너 실행 실패"
docker logs buildup-test 2>/dev/null || echo "컨테이너 로그를 가져올 수 없습니다"
docker rm buildup-test 2>/dev/null || true
docker stop mysql-test
docker rm mysql-test
docker network rm buildup-test-network
exit 1
fi
# ---------------------------------
# 알림 작업 (선택사항 - DISCORD_WEBHOOK 설정 시 작동)
# ---------------------------------
notify:
needs: [build-and-test, docker-build]
runs-on: ubuntu-latest
if: always()
steps:
- name: 📢 Notify Discord
continue-on-error: true
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
run: |
# Discord Webhook이 설정되지 않은 경우 스킵
if [ -z "$DISCORD_WEBHOOK" ]; then
echo "⚠️ Discord Webhook이 설정되지 않아 알림을 건너뜁니다."
exit 0
fi
BUILD_STATUS="${{ needs.build-and-test.result }}"
DOCKER_STATUS="${{ needs.docker-build.result }}"
BRANCH="${{ github.ref_name }}"
AUTHOR="${{ github.actor }}"
RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
if [ "${{ github.event_name }}" = "pull_request" ]; then
PR_INFO="PR #${{ github.event.pull_request.number }}"
PR_TITLE="${{ github.event.pull_request.title }}"
else
PR_INFO="Push to ${BRANCH}"
PR_TITLE="Direct Push"
fi
# 전체 상태 판단
if [ "${BUILD_STATUS}" = "success" ] && ([ "${DOCKER_STATUS}" = "success" ] || [ "${DOCKER_STATUS}" = "skipped" ]); then
ICON="✅"
COLOR=3066993
MESSAGE="Build-Up CI 성공"
else
ICON="❌"
COLOR=15158332
MESSAGE="Build-Up CI 실패"
fi
PAYLOAD=$(cat <<EOF
{
"embeds": [{
"title": "${ICON} ${MESSAGE}",
"description": "${PR_TITLE}",
"color": ${COLOR},
"fields": [
{
"name": "이벤트",
"value": "${PR_INFO}",
"inline": true
},
{
"name": "브랜치",
"value": "\`${BRANCH}\`",
"inline": true
},
{
"name": "작성자",
"value": "${AUTHOR}",
"inline": true
},
{
"name": "빌드 상태",
"value": "${BUILD_STATUS}",
"inline": true
},
{
"name": "Docker 빌드",
"value": "${DOCKER_STATUS}",
"inline": true
},
{
"name": "로그",
"value": "[보기](${RUN_URL})",
"inline": true
}
],
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)"
}]
}
EOF
)
curl -X POST \
-H 'Content-Type: application/json' \
--data "${PAYLOAD}" \
"$DISCORD_WEBHOOK"