Skip to content

Commit 7b4e8ea

Browse files
authored
Merge pull request #18 from Sysone-Mini-2nd/dev
cicd:백엔드 cicd
2 parents 4ce4dc9 + 704ec01 commit 7b4e8ea

189 files changed

Lines changed: 8620 additions & 16 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/deploy.yml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
name: BE CI/CD
2+
3+
# 이 워크플로우가 언제 실행될지 정의합니다.
4+
on:
5+
push:
6+
branches: [ "main" ] # main 브랜치에 코드가 푸시(push)될 때 실행됩니다.
7+
8+
# 실행될 작업(job)들을 정의합니다.
9+
jobs:
10+
build-and-deploy:
11+
# 작업이 실행될 가상 환경을 지정합니다. (Ubuntu 최신 버전)
12+
runs-on: ubuntu-latest
13+
14+
# 작업의 단계(step)들을 정의합니다.
15+
steps:
16+
# 1. 소스 코드 체크아웃
17+
# GitHub 저장소의 코드를 가상 환경으로 가져옵니다.
18+
- name: Checkout
19+
uses: actions/checkout@v4
20+
21+
# 2. JDK 17 설치
22+
# 빌드에 필요한 Java 환경을 설정합니다.
23+
- name: Set up JDK 17
24+
uses: actions/setup-java@v4
25+
with:
26+
java-version: '17'
27+
distribution: 'temurin'
28+
29+
# 3. Gradle 실행 권한 부여
30+
# gradlew 스크립트에 실행 권한을 줍니다.
31+
- name: Grant execute permission for gradlew
32+
run: chmod +x gradlew
33+
34+
# 4. Gradle로 빌드
35+
# 코드를 컴파일하고 테스트를 실행한 뒤, 실행 가능한 JAR 파일을 생성합니다.
36+
- name: Build with Gradle
37+
run: ./gradlew build
38+
39+
# 5. GCP 인증
40+
# GitHub Secrets에 저장된 서비스 계정 키를 사용하여 GCP에 인증합니다.
41+
- name: Authenticate to Google Cloud
42+
uses: 'google-github-actions/auth@v2'
43+
with:
44+
credentials_json: '${{ secrets.GCP_SA_KEY }}'
45+
46+
# 6. 빌드된 JAR 파일을 GCP VM으로 전송
47+
# gcloud scp 명령어를 사용해 JAR 파일을 VM의 홈 디렉토리로 복사합니다.
48+
- name: Transfer JAR to GCP VM
49+
run: |
50+
# build/libs/ 폴더에서 생성된 JAR 파일 이름을 자동으로 찾습니다.
51+
JAR_FILE=$(find build/libs/ -name "*.jar" | head -n 1)
52+
gcloud compute scp \
53+
$JAR_FILE \
54+
${{ secrets.GCP_INSTANCE_NAME }}:~/ \
55+
--project=${{ secrets.GCP_PROJECT_ID }} \
56+
--zone=${{ secrets.GCP_ZONE }}
57+
58+
# 7. VM에 접속하여 애플리케이션 실행 (환경 변수 주입)
59+
# gcloud ssh 명령어로 VM에 접속하여 기존 앱을 종료하고,
60+
# GitHub Secrets의 값들을 환경 변수로 주입하여 새 앱을 실행합니다.
61+
- name: Deploy to GCP VM
62+
env:
63+
# Spring Boot 애플리케이션에 필요한 모든 Secret들을 env 컨텍스트에 등록합니다.
64+
DB_URL: ${{ secrets.DB_URL }}
65+
DB_USERNAME: ${{ secrets.DB_USERNAME }}
66+
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
67+
JWT_SECRET: ${{ secrets.JWT_SECRET }} # JWT Secret 추가
68+
GOOGLE_EMAIL: ${{ secrets.GOOGLE_EMAIL }}
69+
GOOGLE_EMAIL_KEY: ${{ secrets.GOOGLE_EMAIL_KEY }}
70+
NAVER_CLIENT: ${{ secrets.NAVER_CLIENT }}
71+
NAVER_SECRET: ${{ secrets.NAVER_SECRET }}
72+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
73+
run: |
74+
# build/libs/ 폴더에서 생성된 JAR 파일의 순수 이름만 추출합니다.
75+
JAR_FILE_NAME=$(basename $(find build/libs/ -name "*.jar" | head -n 1))
76+
77+
# gcloud ssh 명령어로 VM에 접속하여 배포 스크립트를 실행합니다.
78+
gcloud compute ssh ${{ secrets.GCP_INSTANCE_NAME }} \
79+
--project=${{ secrets.GCP_PROJECT_ID }} \
80+
--zone=${{ secrets.GCP_ZONE }} \
81+
--command="
82+
# 기존에 실행 중인 동일한 이름의 Java 프로세스를 찾아 종료합니다.
83+
PID=\$(pgrep -f '$JAR_FILE_NAME')
84+
if [ -n \"\$PID\" ]; then
85+
echo 'Stopping existing process with PID: \$PID'
86+
kill -9 \$PID
87+
sleep 5
88+
fi
89+
90+
# env 컨텍스트에 등록된 변수들을 nohup 명령어 앞에 붙여서 실행합니다.
91+
echo 'Starting new application process...'
92+
nohup env \
93+
DB_URL='${DB_URL}' \
94+
DB_USERNAME='${DB_USERNAME}' \
95+
DB_PASSWORD='${DB_PASSWORD}' \
96+
JWT_SECRET='${JWT_SECRET}' \
97+
GOOGLE_EMAIL='${GOOGLE_EMAIL}' \
98+
GOOGLE_EMAIL_KEY='${GOOGLE_EMAIL_KEY}' \
99+
NAVER_CLIENT='${NAVER_CLIENT}' \
100+
NAVER_SECRET='${NAVER_SECRET}' \
101+
OPENAI_API_KEY='${OPENAI_API_KEY}' \
102+
java -jar ~/$JAR_FILE_NAME > ~/app.log 2>&1 &
103+
"

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,8 @@ $RECYCLE.BIN/
187187
# Windows shortcuts
188188
*.lnk
189189

190-
# End of https://www.toptal.com/developers/gitignore/api/macos,windows,intellij+all
190+
.env
191+
192+
# End of https://www.toptal.com/developers/gitignore/api/macos,windows,intellij+all.env
193+
/src/main/resources/db/schema.sql
194+
/src/main/resources/db/schemaDelete.sql

build.gradle

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,54 @@ dependencies {
3232
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
3333
implementation 'org.springframework.boot:spring-boot-starter-web'
3434
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.5'
35-
// implementation 'org.springframework.ai:spring-ai-starter-model-openai'
35+
implementation 'org.springframework.ai:spring-ai-starter-model-openai'
36+
implementation 'org.springframework.boot:spring-boot-starter-websocket'
37+
implementation 'org.springframework:spring-websocket'
38+
implementation 'org.springframework:spring-messaging'
39+
// WebSocket 보안을 위한 의존성 추가
40+
implementation 'org.springframework.security:spring-security-messaging'
41+
42+
implementation 'org.springframework.boot:spring-boot-starter-security'
43+
44+
implementation 'org.springframework.boot:spring-boot-starter-validation'
45+
implementation 'org.springframework.boot:spring-boot-starter-security'
46+
implementation 'org.springframework.boot:spring-boot-starter-validation'
47+
implementation 'org.springframework.security:spring-security-test'
48+
49+
// SockJS 클라이언트 WebJar 추가 (백엔드에서 SockJS 핸드셰이크 지원용)
50+
implementation 'org.webjars:sockjs-client:1.5.1'
51+
52+
// JWT 관련 의존성 추가
53+
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
54+
implementation 'io.jsonwebtoken:jjwt-impl:0.12.3'
55+
implementation 'io.jsonwebtoken:jjwt-jackson:0.12.3'
56+
3657
compileOnly 'org.projectlombok:lombok'
3758
developmentOnly 'org.springframework.boot:spring-boot-devtools'
3859
runtimeOnly 'com.oracle.database.jdbc:ojdbc11'
3960
annotationProcessor 'org.projectlombok:lombok'
4061
testImplementation 'org.springframework.boot:spring-boot-starter-test'
4162
testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.5'
4263
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
64+
65+
66+
67+
// Apache POI - 모든 모듈을 동일한 버전으로 통일
68+
implementation 'org.apache.poi:poi:5.2.3'
69+
implementation 'org.apache.poi:poi-ooxml:5.2.3'
70+
implementation 'org.apache.poi:poi-scratchpad:5.2.3'
71+
72+
// build.gradle에 추가
73+
implementation 'pro.verron:docx-stamper:1.6.4'
74+
75+
// 이메일 전송
76+
implementation 'org.springframework.boot:spring-boot-starter-mail'
77+
78+
// JSON 처리
79+
implementation 'com.fasterxml.jackson.core:jackson-databind'
80+
81+
// test용 H2 DB
82+
testImplementation 'com.h2database:h2'
4383
}
4484

4585
dependencyManagement {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.sys.stm.domains.assignedPerson.dao;
2+
3+
import com.sys.stm.domains.assignedPerson.domain.AssignedPerson;
4+
import com.sys.stm.domains.assignedPerson.dto.response.AssignedPersonDashBoardResponseDTO;
5+
import com.sys.stm.domains.assignedPerson.dto.response.PmInfoResponseDTO;
6+
import com.sys.stm.domains.assignedPerson.dto.response.AssignedPersonDetailResponseDTO;
7+
import java.util.List;
8+
import org.apache.ibatis.annotations.Mapper;
9+
import org.apache.ibatis.annotations.Param;
10+
11+
@Mapper
12+
public interface AssignedPersonRepository {
13+
int countByProjectId(Long projectId);
14+
int createAssignedPerson(AssignedPerson assignedPerson);
15+
void deleteByProjectIdAndMemberIds(@Param("projectId") Long projectId, @Param("memberIds") List<Long> memberIds);
16+
List<AssignedPersonDetailResponseDTO> findMembersByProjectId(Long projectId);
17+
List<Long> findMemberIdsByProjectId(Long projectId);
18+
List<PmInfoResponseDTO> findPmsByProjectIds(List<Long> projectIds);
19+
List<AssignedPersonDashBoardResponseDTO> findMembersNameByProjectId(Long projectId);
20+
String findRoleByProjectIdAndMemberId(Long projectId, Long memberId);
21+
// List<Member> findAllMemberByProjectId(Long projectId);
22+
// Member findPmByProjectId;
23+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.sys.stm.domains.assignedPerson.domain;
2+
3+
import com.sys.stm.global.common.entity.BaseEntity;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.EqualsAndHashCode;
7+
8+
@EqualsAndHashCode(callSuper = true)
9+
@Builder
10+
@Data
11+
public class AssignedPerson extends BaseEntity {
12+
private Long id;
13+
private Long projectId;
14+
private Long memberId;
15+
private AssignedPersonRole role;
16+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.sys.stm.domains.assignedPerson.domain;
2+
3+
import lombok.Getter;
4+
import lombok.RequiredArgsConstructor;
5+
6+
@Getter
7+
@RequiredArgsConstructor
8+
public enum AssignedPersonRole {
9+
USER("팀원"),
10+
PM("프로젝트 매니저");
11+
12+
private final String displayName;
13+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.sys.stm.domains.assignedPerson.dto.response;
2+
3+
import lombok.Builder;
4+
import lombok.Data;
5+
6+
@Data
7+
@Builder
8+
public class AssignedPersonDashBoardResponseDTO {
9+
private Long id;
10+
private String name;
11+
private String position;
12+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.sys.stm.domains.assignedPerson.dto.response;
2+
3+
import com.sys.stm.domains.assignedPerson.domain.AssignedPersonRole;
4+
import java.sql.Timestamp;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Builder;
7+
import lombok.Data;
8+
import lombok.NoArgsConstructor;
9+
10+
@Builder
11+
@Data
12+
@NoArgsConstructor
13+
@AllArgsConstructor
14+
public class AssignedPersonDetailResponseDTO {
15+
private Long id;
16+
private String name;
17+
private AssignedPersonRole role;
18+
private Timestamp lastLoginAt;
19+
private Timestamp createdAt;
20+
private Timestamp updatedAt;
21+
private String picUrl;
22+
private String position;
23+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.sys.stm.domains.assignedPerson.dto.response;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
8+
@Builder
9+
@Data
10+
@NoArgsConstructor
11+
@AllArgsConstructor
12+
public class PmInfoResponseDTO {
13+
private Long projectId;
14+
private Long pmId;
15+
private String pmName;
16+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.sys.stm.domains.assignedPerson.service;
2+
3+
import com.sys.stm.domains.assignedPerson.dto.response.AssignedPersonDashBoardResponseDTO;
4+
5+
import java.util.List;
6+
7+
public interface AssignedPersonService {
8+
List<AssignedPersonDashBoardResponseDTO> findMembersNameByProjectId(Long projectId);
9+
String findRoleByProjectIdAndMemberId(Long projectId, Long memberId);
10+
}

0 commit comments

Comments
 (0)