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
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
96 changes: 0 additions & 96 deletions .github/workflows/CICD.yml

This file was deleted.

110 changes: 46 additions & 64 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ pipeline {

environment {
DISCORD_WEBHOOK = credentials('discord-webhook')
DB_DRIVER = 'mysql'
DB_HOST = 'mysql-ci'
DB_PORT = '3306'
DB_NAME = 'homeaid_db'
DB_USERNAME = 'homeaid_user'
DB_PASSWORD = 'root'
}

tools {
Expand All @@ -16,34 +22,13 @@ pipeline {
}
}

stage('Build MySQL Service') {
stage('Set Variables') {
steps {
script {
// Docker로 MySQL 컨테이너 띄우기 (jenkins 서버에 Docker가 설치되어 있어야 함)
sh '''
docker run -d \
--name mysql-ci \
-e MYSQL_DATABASE=${DB_NAME} \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_USER=homeaid_user \
-e MYSQL_PASSWORD=${DB_PASSWORD} \
-p 3306:3306 \
--health-cmd="mysqladmin ping -h localhost --silent" \
--health-interval=10s \
--health-timeout=5s \
--health-retries=3 \
mysql:latest

# DB 준비 대기 (최대 60초)
for i in {1..12}; do
if docker exec mysql-ci mysqladmin ping -h localhost --silent; then
echo "MySQL is ready!"
break
fi
echo "Waiting for MySQL..."
sleep 5
done
'''
wrap([$class: 'BuildUser']) {
script {
env.BUILD_USER = "${env.BUILD_USER}"
echo "Triggered by: ${env.BUILD_USER}"
}
}
}
}
Expand All @@ -67,47 +52,44 @@ pipeline {

post {
success {
script {
def message = """{
"embeds": [{
"title": "✅ CI 성공",
"description": "**📦 Repository:** `${env.JOB_NAME}`\\n**🌿 Branch:** `${env.BRANCH_NAME}`\\n**👤 Triggered by:** `${env.BUILD_USER}`\\n[🔗 Jenkins 로그 확인하기](${env.BUILD_URL})",
"color": 5763719
}],
"content": "✅ CI 통과: `${env.BRANCH_NAME}` 브랜치입니다!"
}"""
sh """
curl -H "Content-Type: application/json" \
-X POST \
-d '${message}' \
${DISCORD_WEBHOOK}
"""
wrap([$class: 'BuildUser']) {
script {
def message = """{
"embeds": [{
"title": "✅ CI 성공",
"description": "**📦 Repository:** `${env.JOB_NAME}`\\n**🌿 Branch:** `${env.BRANCH_NAME}`\\n**👤 Triggered by:** `${env.BUILD_USER}`\\n[🔗 Jenkins 로그 확인하기](${env.BUILD_URL})",
"color": 5763719
}],
"content": "✅ CI 통과: `${env.BRANCH_NAME}` 브랜치입니다!"
}"""
sh """
curl -H "Content-Type: application/json" \
-X POST \
-d '${message}' \
${DISCORD_WEBHOOK}
"""
}
}
}
failure {
script {
def message = """{
"embeds": [{
"title": "❌ CI 실패",
"description": "**📦 Repository:** `${env.JOB_NAME}`\\n**🌿 Branch:** `${env.BRANCH_NAME}`\\n**👤 Triggered by:** `${env.BUILD_USER}`\\n[🔗 Jenkins 로그 확인하기](${env.BUILD_URL})",
"color": 16711680
}],
"content": "❗ CI 실패 발생: `${env.BRANCH_NAME}` 브랜치 확인해주세요!"
}"""
sh """
curl -H "Content-Type: application/json" \
-X POST \
-d '${message}' \
${DISCORD_WEBHOOK}
"""
wrap([$class: 'BuildUser']) {
script {
def message = """{
"embeds": [{
"title": "❌ CI 실패",
"description": "**📦 Repository:** `${env.JOB_NAME}`\\n**🌿 Branch:** `${env.BRANCH_NAME}`\\n**👤 Triggered by:** `${env.BUILD_USER}`\\n[🔗 Jenkins 로그 확인하기](${env.BUILD_URL})",
"color": 16711680
}],
"content": "❗ CI 실패 발생: `${env.BRANCH_NAME}` 브랜치 확인해주세요!"
}"""
sh """
curl -H "Content-Type: application/json" \
-X POST \
-d '${message}' \
${DISCORD_WEBHOOK}
"""
}
}
}
always {
// Clean up MySQL container
sh '''
docker stop mysql-ci || true
docker rm mysql-ci || true
'''
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/board")
@RequestMapping("/api/v1/boards")
@Tag(name = "1:1 문의글", description = "사용자와 관리자 간 1:1 문의글 API")
@SecurityRequirement(name = "Bearer Authentication")
public class UserBoardController {
Expand Down Expand Up @@ -155,7 +155,7 @@ public ResponseEntity<CommonApiResponse<UserBoardResponseDto>> getBoard(
content = @Content(schema = @Schema(implementation = CommonApiResponse.class)))
})
public ResponseEntity<CommonApiResponse<PagedResponseDto<UserBoardListResponseDto>>> searchBoard(
@Parameter(description = "검색 키워드", example = "문의")
@Parameter(description = "검색 키워드")
@RequestParam(name = "keyword", required = false) String keyword,
@Parameter(description = "페이지 번호 (0부터 시작)", example = "0")
@RequestParam(name = "page", defaultValue = "0") int page,
Expand Down
38 changes: 38 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
version: '3.8'

services:
jenkins:
image: jenkins/jenkins:lts
container_name: jenkins
ports:
- "8080:8080"
- "50000:50000"
volumes:
- jenkins_home:/var/jenkins_home
networks:
- ci-network

mysql-ci:
image: mysql:latest
container_name: mysql-ci
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: homeaid_db
MYSQL_USER: homeaid_user
MYSQL_PASSWORD: root
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 30s
timeout: 10s
retries: 5
networks:
- ci-network

volumes:
jenkins_home:

networks:
ci-network:
driver: bridge
27 changes: 16 additions & 11 deletions global/src/main/java/com/homeaid/config/SwaggerConfig.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.homeaid.config;

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
Expand All @@ -12,17 +14,16 @@ public class SwaggerConfig {

@Bean
public OpenAPI springOpenAPI() {

return new OpenAPI()
.info(new Info()
.title("HomeAid API 명세서")
.version("v1")
.description("HomeAid는 매칭시스템을 활용하여 고객에게 맞춤형 매니저를 매칭시켜주고 가사 및 청소 서비스를 제공합니다."));
/*// 전역 보안 요구사항 추가
.description("HomeAid는 매칭시스템을 활용하여 고객에게 맞춤형 매니저를 매칭시켜주고 가사 및 청소 서비스를 제공합니다."))
// 전역 보안 요구사항 추가
.addSecurityItem(new SecurityRequirement().addList("Bearer Authentication"))
// 보안 스키마 정의
.components(new Components()
.addSecuritySchemes("Bearer Authentication", createBearerTokenScheme()));*/
.addSecuritySchemes("Bearer Authentication", createBearerTokenScheme()));
}

/**
Expand All @@ -42,14 +43,16 @@ private SecurityScheme createBearerTokenScheme() {
public GroupedOpenApi reservationAPI() {
return GroupedOpenApi.builder()
.group("reservations")
.displayName("예약")
.pathsToMatch("/api/v1/customer/reservations/**")
.build();
}

@Bean
public GroupedOpenApi serviceOptionAPI() {
return GroupedOpenApi.builder()
.group("serviceOption")
.group("serviceOptions")
.displayName("서비스 옵션")
.pathsToMatch("/api/v1/admin/service-option/**")
.build();
}
Expand All @@ -59,6 +62,7 @@ public GroupedOpenApi serviceOptionAPI() {
public GroupedOpenApi matchingAPI() {
return GroupedOpenApi.builder()
.group("matchings")
.displayName("매칭")
.pathsToMatch("/api/v1/admin/matchings/**")
.build();
}
Expand All @@ -69,26 +73,27 @@ public GroupedOpenApi userAPI() {

return GroupedOpenApi.builder()
.group("Users")
.pathsToMatch("/api/v1/user/**")
.displayName("로그인/회원가입")
.pathsToMatch("/api/v1/swagger/auth/**")
.build();
}

@Bean

public GroupedOpenApi worklogAPI() {
return GroupedOpenApi.builder()
.group("worklog")
.group("workLogs")
.displayName("작업기록")
.pathsToMatch("/api/v1/manager/work-logs/**")
.build();
}

@Bean

public GroupedOpenApi boardAPI() {
return GroupedOpenApi.builder()
.group("Boards")
.displayName("💬 1:1 문의글")
.pathsToMatch("/api/v1/board/**")
.displayName("문의글")
.pathsToMatch("/api/v1/boards/**")
.build();

}
Expand All @@ -98,7 +103,7 @@ public GroupedOpenApi reviewAPI() {
return GroupedOpenApi.builder()
.group("reviews")
.displayName("리뷰")
.pathsToMatch("/api/v1/review/**")
.pathsToMatch("/api/v1/reviews/**")
.build();
}
}
Loading