Skip to content

Commit 91d9b41

Browse files
authored
Merge branch 'dev' into lkh
2 parents 0eb701a + b870c5f commit 91d9b41

File tree

7 files changed

+167
-127
lines changed

7 files changed

+167
-127
lines changed

.github/workflows/deploy.yml

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ jobs:
8181
runs-on: ubuntu-latest
8282

8383
steps:
84-
8584
- name: Deploy to GCP Instance
8685
uses: appleboy/ssh-action@v1.1.0
8786
with:
@@ -92,29 +91,91 @@ jobs:
9291
script: |
9392
cd $HOME/project
9493
94+
echo "Updating .env file with latest Secret Manager values..."
95+
96+
# .env 파일 백업
97+
cp .env .env.backup.$(date +%Y%m%d_%H%M%S)
98+
99+
# Secret Manager 관련 라인들 제거
100+
sed -i '/^DB_URL=/d' .env
101+
sed -i '/^JWT_SECRET=/d' .env
102+
sed -i '/^GOOGLE_CLIENT_ID=/d' .env
103+
sed -i '/^GOOGLE_CLIENT_SECRET=/d' .env
104+
sed -i '/^GOOGLE_API_KEY=/d' .env
105+
sed -i '/^GOOGLE_CALENDAR_REDIRECT_URI=/d' .env
106+
sed -i '/^OAUTH_REDIRECT_URI=/d' .env
107+
sed -i '/^KAKAO_CLIENT_ID=/d' .env
108+
sed -i '/^KAKAO_CLIENT_SECRET=/d' .env
109+
sed -i '/^KAKAO_API_KEY=/d' .env
110+
sed -i '/^ZOOM_ACCOUNT_ID=/d' .env
111+
sed -i '/^ZOOM_CLIENT_ID=/d' .env
112+
sed -i '/^ZOOM_CLIENT_SECRET=/d' .env
113+
sed -i '/^GCP_IP=/d' .env
114+
sed -i '/^FRONT_DOMAIN_A=/d' .env
115+
sed -i '/^FRONT_DOMAIN_B=/d' .env
116+
sed -i '/^FRONT_CALLBACK=/d' .env
117+
sed -i '/^REDIS_HOST=/d' .env
118+
sed -i '/^REDIS_PORT=/d' .env
119+
120+
# Secret Manager에서 최신 값들을 가져와서 .env에 추가
121+
echo "" >> .env
122+
echo "DB_URL=$(gcloud secrets versions access latest --secret='db-url')" >> .env
123+
echo "JWT_SECRET=$(gcloud secrets versions access latest --secret='jwt-secret')" >> .env
124+
echo "GOOGLE_CLIENT_ID=$(gcloud secrets versions access latest --secret='google-client-id')" >> .env
125+
echo "GOOGLE_CLIENT_SECRET=$(gcloud secrets versions access latest --secret='google-client-secret')" >> .env
126+
echo "GOOGLE_API_KEY=$(gcloud secrets versions access latest --secret='google-api-key')" >> .env
127+
echo "GOOGLE_CALENDAR_REDIRECT_URI=$(gcloud secrets versions access latest --secret='google-calendar-redirect-uri')" >> .env
128+
echo "OAUTH_REDIRECT_URI=$(gcloud secrets versions access latest --secret='oauth-redirect-uri')" >> .env
129+
echo "KAKAO_CLIENT_ID=$(gcloud secrets versions access latest --secret='kakao-client-id')" >> .env
130+
echo "KAKAO_CLIENT_SECRET=$(gcloud secrets versions access latest --secret='kakao-client-secret')" >> .env
131+
echo "KAKAO_API_KEY=$(gcloud secrets versions access latest --secret='kakao-api-key')" >> .env
132+
echo "ZOOM_ACCOUNT_ID=$(gcloud secrets versions access latest --secret='zoom-account-id')" >> .env
133+
echo "ZOOM_CLIENT_ID=$(gcloud secrets versions access latest --secret='zoom-client-id')" >> .env
134+
echo "ZOOM_CLIENT_SECRET=$(gcloud secrets versions access latest --secret='zoom-client-secret')" >> .env
135+
echo "GCP_IP=$(gcloud secrets versions access latest --secret='gcp-ip')" >> .env
136+
echo "FRONT_DOMAIN_A=$(gcloud secrets versions access latest --secret='front-domain-A')" >> .env
137+
echo "FRONT_DOMAIN_B=$(gcloud secrets versions access latest --secret='front-domain-B')" >> .env
138+
echo "FRONT_CALLBACK=$(gcloud secrets versions access latest --secret='front-callback')" >> .env
139+
echo "REDIS_HOST=$(gcloud secrets versions access latest --secret='redis-host')" >> .env
140+
echo "REDIS_PORT=$(gcloud secrets versions access latest --secret='redis-port')" >> .env
141+
142+
echo "Updated Secret Manager Values"
143+
144+
echo "Stopping existing containers..."
95145
sudo docker-compose down || true
96146
147+
echo "Cleaning up old images..."
97148
sudo docker image prune -f
98-
sudo docker rmi ${{ secrets.DOCKER_USERNAME }}/ittaeok-gcp:latest || true
149+
sudo docker rmi ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_NAME }}:latest || true
99150
sudo docker system prune -f || true
100151
101-
sudo docker pull ${{ secrets.DOCKER_USERNAME }}/ittaeok-gcp:latest --disable-content-trust
152+
echo "Pulling latest image..."
153+
sudo docker pull ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_NAME }}:latest --disable-content-trust
102154
155+
echo "Starting containers with updated configuration..."
103156
sudo docker-compose up -d
104157
158+
echo "Container status:"
105159
sudo docker-compose ps
106160
107-
sleep 10
108-
sudo docker-compose logs --tail=20
161+
echo "Waiting for application to start..."
162+
sleep 15
163+
164+
echo "Recent logs:"
165+
sudo docker-compose logs --tail=30
109166
110167
echo "=== Deployed Image Info ==="
111-
sudo docker images | grep ittaeok-gcp
168+
sudo docker images | grep ${{ secrets.DOCKER_IMAGE_NAME }}
112169
113170
echo "=== Container Info ==="
114171
sudo docker ps | grep ittaeok
172+
173+
echo "=== Environment Variables Verification ==="
174+
sudo docker exec ittaeok env | grep -E "(DB_URL|JWT_SECRET|REDIS_HOST)" | head -3
115175
116176
- name: Deployment completed
117177
run: |
118178
echo "Deployment completed successfully"
119179
echo "Deployed commit: ${{ github.sha }}"
120-
echo "Repository: ${{ github.repository }}"
180+
echo "Repository: ${{ github.repository }}"
181+
echo "Secret Manager values automatically updated"

docker-compose.yml

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ services:
4040
start_period: 30s
4141

4242
ittaeok-container:
43-
image: ${DOCKER_IMAGES_NAME} # ex: leeseojun/ittaeok:latest
43+
image: ${DOCKER_IMAGES_NAME}
4444
container_name: ittaeok
4545
restart: always
4646
depends_on:
@@ -52,20 +52,41 @@ services:
5252
- "80:80"
5353
- "443:443"
5454
environment:
55-
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql-container:3306/ittaeok?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul
56-
- SPRING_DATASOURCE_USERNAME=ittaeok_user
57-
- SPRING_DATASOURCE_PASSWORD=1234
58-
59-
- SPRING_DATA_REDIS_HOST=redis-container
60-
- SPRING_DATA_REDIS_PORT=6379
61-
- SPRING_DATA_REDIS_PASSWORD=${REDIS_PASSWORD}
62-
- SPRING_DATA_REDIS_SSL_ENABLED=false
63-
64-
- GOOGLE_APPLICATION_CREDENTIALS=${GOOGLE_APPLICATION_CREDENTIALS}
65-
- GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT}
66-
67-
- SPRING_CLOUD_GCP_SECRETMANAGER_ENABLED="true"
68-
- SPRING_CLOUD_GCP_PROJECT_ID=${GOOGLE_CLOUD_PROJECT}
55+
# Database
56+
- DB_URL=${DB_URL}
57+
- MYSQL_USER=${MYSQL_USER}
58+
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
59+
60+
# Redis
61+
- REDIS_HOST=${REDIS_HOST}
62+
- REDIS_PORT=${REDIS_PORT}
63+
- REDIS_PASSWORD=${REDIS_PASSWORD}
64+
65+
# JWT
66+
- JWT_SECRET=${JWT_SECRET}
67+
68+
# Google
69+
- GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
70+
- GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
71+
- GOOGLE_API_KEY=${GOOGLE_API_KEY}
72+
- OAUTH_REDIRECT_URI=${OAUTH_REDIRECT_URI}
73+
- GOOGLE_CALENDAR_REDIRECT_URI=${GOOGLE_CALENDAR_REDIRECT_URI}
74+
75+
# Kakao
76+
- KAKAO_CLIENT_ID=${KAKAO_CLIENT_ID}
77+
- KAKAO_CLIENT_SECRET=${KAKAO_CLIENT_SECRET}
78+
- KAKAO_API_KEY=${KAKAO_API_KEY}
79+
80+
# Zoom
81+
- ZOOM_ACCOUNT_ID=${ZOOM_ACCOUNT_ID}
82+
- ZOOM_CLIENT_ID=${ZOOM_CLIENT_ID}
83+
- ZOOM_CLIENT_SECRET=${ZOOM_CLIENT_SECRET}
84+
85+
# URL
86+
- GCP_IP=${GCP_IP}
87+
- FRONT_DOMAIN_A=${FRONT_DOMAIN_A}
88+
- FRONT_DOMAIN_B=${FRONT_DOMAIN_B}
89+
- FRONT_CALLBACK=${FRONT_CALLBACK}
6990
volumes:
7091
- ./gcp-key.json:/app/gcp-key.json:ro
7192
networks:

src/main/java/com/grepp/spring/app/controller/api/mypage/payload/response/GoogleTokenResponse.java

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/main/java/com/grepp/spring/app/model/schedule/service/ScheduleCommandService.java

Lines changed: 23 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,7 @@
33
import com.fasterxml.jackson.core.JsonProcessingException;
44
import com.fasterxml.jackson.databind.JsonNode;
55
import com.fasterxml.jackson.databind.ObjectMapper;
6-
import com.grepp.spring.app.controller.api.mypage.payload.response.GoogleTokenResponse;
7-
import com.grepp.spring.app.controller.api.schedule.payload.request.AddWorkspaceRequest;
8-
import com.grepp.spring.app.controller.api.schedule.payload.request.CreateDepartLocationRequest;
9-
import com.grepp.spring.app.controller.api.schedule.payload.request.CreateSchedulesRequest;
10-
import com.grepp.spring.app.controller.api.schedule.payload.request.ModifySchedulesRequest;
11-
import com.grepp.spring.app.controller.api.schedule.payload.request.WriteSuggestedLocationRequest;
6+
import com.grepp.spring.app.controller.api.schedule.payload.request.*;
127
import com.grepp.spring.app.controller.api.schedule.payload.response.CreateOnlineMeetingRoomResponse;
138
import com.grepp.spring.app.controller.api.schedule.payload.response.CreateSchedulesResponse;
149
import com.grepp.spring.app.model.event.entity.Event;
@@ -17,68 +12,34 @@
1712
import com.grepp.spring.app.model.schedule.code.MeetingPlatform;
1813
import com.grepp.spring.app.model.schedule.code.ScheduleRole;
1914
import com.grepp.spring.app.model.schedule.code.VoteStatus;
20-
import com.grepp.spring.app.model.schedule.dto.AddWorkspaceDto;
21-
import com.grepp.spring.app.model.schedule.dto.CreateDepartLocationDto;
22-
import com.grepp.spring.app.model.schedule.dto.CreateOnlineMeetingRoomDto;
23-
import com.grepp.spring.app.model.schedule.dto.CreateScheduleDto;
24-
import com.grepp.spring.app.model.schedule.dto.DepartLocationMetroTransferDto;
25-
import com.grepp.spring.app.model.schedule.dto.ModifyScheduleDto;
26-
import com.grepp.spring.app.model.schedule.dto.ModifyWorkspaceDto;
27-
import com.grepp.spring.app.model.schedule.dto.CreateScheduleMembersDto;
28-
import com.grepp.spring.app.model.schedule.dto.SubwayStationDto;
29-
import com.grepp.spring.app.model.schedule.dto.VoteMiddleLocationDto;
30-
import com.grepp.spring.app.model.schedule.dto.WriteSuggestedLocationDto;
31-
import com.grepp.spring.app.model.schedule.dto.WriteSuggestedMetroTransferDto;
32-
import com.grepp.spring.app.model.schedule.dto.ZoomMeetingDto;
33-
import com.grepp.spring.app.model.schedule.entity.Line;
34-
import com.grepp.spring.app.model.schedule.entity.Location;
35-
import com.grepp.spring.app.model.schedule.entity.Metro;
36-
import com.grepp.spring.app.model.schedule.entity.MetroTransfer;
37-
import com.grepp.spring.app.model.schedule.entity.Schedule;
38-
import com.grepp.spring.app.model.schedule.entity.ScheduleMember;
39-
import com.grepp.spring.app.model.schedule.entity.Vote;
40-
import com.grepp.spring.app.model.schedule.entity.Workspace;
41-
import com.grepp.spring.app.model.schedule.repository.LineQueryRepository;
42-
import com.grepp.spring.app.model.schedule.repository.LocationCommandRepository;
43-
import com.grepp.spring.app.model.schedule.repository.LocationQueryRepository;
44-
import com.grepp.spring.app.model.schedule.repository.MetroQueryRepository;
45-
import com.grepp.spring.app.model.schedule.repository.MetroTransferCommandRepository;
46-
import com.grepp.spring.app.model.schedule.repository.ScheduleCommandRepository;
47-
import com.grepp.spring.app.model.schedule.repository.ScheduleMemberQueryRepository;
48-
import com.grepp.spring.app.model.schedule.repository.ScheduleMemberRepository;
49-
import com.grepp.spring.app.model.schedule.repository.ScheduleQueryRepository;
50-
import com.grepp.spring.app.model.schedule.repository.VoteCommandRepository;
51-
import com.grepp.spring.app.model.schedule.repository.VoteQueryRepository;
52-
import com.grepp.spring.app.model.schedule.repository.WorkspaceCommandRepository;
53-
import com.grepp.spring.app.model.schedule.repository.WorkspaceQueryRepository;
54-
import com.grepp.spring.infra.error.exceptions.schedule.EventNotActivatedException;
55-
import com.grepp.spring.infra.error.exceptions.schedule.VoteAlreadyProgressException;
56-
import com.grepp.spring.infra.utils.RandomPicker;
15+
import com.grepp.spring.app.model.schedule.dto.*;
16+
import com.grepp.spring.app.model.schedule.entity.*;
17+
import com.grepp.spring.app.model.schedule.repository.*;
5718
import com.grepp.spring.infra.error.exceptions.NotFoundException;
5819
import com.grepp.spring.infra.error.exceptions.group.UserNotFoundException;
20+
import com.grepp.spring.infra.error.exceptions.schedule.EventNotActivatedException;
5921
import com.grepp.spring.infra.error.exceptions.schedule.LocationNotFoundException;
22+
import com.grepp.spring.infra.error.exceptions.schedule.VoteAlreadyProgressException;
6023
import com.grepp.spring.infra.response.GroupErrorCode;
6124
import com.grepp.spring.infra.response.ScheduleErrorCode;
25+
import com.grepp.spring.infra.utils.RandomPicker;
6226
import jakarta.persistence.EntityManager;
6327
import jakarta.persistence.PersistenceContext;
64-
import java.time.format.DateTimeFormatter;
65-
import java.util.ArrayList;
66-
import java.util.List;
67-
import java.util.Optional;
6828
import lombok.RequiredArgsConstructor;
6929
import lombok.extern.slf4j.Slf4j;
7030
import org.springframework.beans.factory.annotation.Autowired;
7131
import org.springframework.beans.factory.annotation.Value;
72-
import org.springframework.http.HttpEntity;
73-
import org.springframework.http.HttpHeaders;
74-
import org.springframework.http.HttpMethod;
75-
import org.springframework.http.MediaType;
76-
import org.springframework.http.ResponseEntity;
32+
import org.springframework.http.*;
7733
import org.springframework.stereotype.Service;
7834
import org.springframework.transaction.annotation.Transactional;
7935
import org.springframework.web.client.RestTemplate;
8036
import org.springframework.web.util.UriComponentsBuilder;
8137

38+
import java.time.format.DateTimeFormatter;
39+
import java.util.ArrayList;
40+
import java.util.List;
41+
import java.util.Optional;
42+
8243
@Service
8344
@Slf4j
8445
@RequiredArgsConstructor
@@ -120,9 +81,6 @@ public class ScheduleCommandService {
12081
@Autowired
12182
private ZoomOAuthService zoomOAuthService;
12283

123-
@Value("${zoom.refresh-token}")
124-
private String zoomRefreshToken;
125-
12684
// 공통 로직
12785
private Optional<Schedule> getSchedule(Long scheduleId) {
12886
Optional<Schedule> schedule = scheduleQueryRepository.findById(scheduleId);
@@ -183,8 +141,7 @@ private void createScheduleMembers(CreateSchedulesRequest request, Schedule sche
183141

184142
if (entry.getMemberId().equals(userId)) {
185143
role = ScheduleRole.ROLE_MASTER;
186-
}
187-
else {
144+
} else {
188145
role = ScheduleRole.ROLE_MEMBER;
189146
}
190147

@@ -311,7 +268,7 @@ public void createDepartLocation(Long scheduleId, CreateDepartLocationRequest re
311268
metroTransferCommandRepository.deleteByScheduleId(scheduleId);
312269
locationCommandRepository.deleteLocation(scheduleId);
313270

314-
ScheduleMember scheduleMember = getScheduleMember(scheduleId,userId);
271+
ScheduleMember scheduleMember = getScheduleMember(scheduleId, userId);
315272
Optional<Metro> metro = getMetro(request.getDepartLocationName());
316273
setDepartLocation(request, metro, scheduleMember);
317274

@@ -378,7 +335,7 @@ private static Double getLatitude(List<ScheduleMember> scheduleLocations) {
378335
}
379336

380337
private static void setDepartLocation(CreateDepartLocationRequest request, Optional<Metro> metro,
381-
ScheduleMember scheduleMember) {
338+
ScheduleMember scheduleMember) {
382339
// DB에 존재하지 않는다면
383340
if (metro.isEmpty()) {
384341
CreateDepartLocationDto dto = CreateDepartLocationDto.toDto(request);
@@ -455,7 +412,7 @@ public void voteMiddleLocation(Schedule schedule, ScheduleMember scheduleMember,
455412
// Location 엔티티에 비관적 락을 걸고 조회하기
456413
// 파라미터를 id로 받으면 더 좋을 것 같음
457414
Location location = locationQueryRepository.findByIdWithPessimisticLock(lid.getId())
458-
.orElseThrow(() -> new IllegalArgumentException("장소를 찾을 수 없습니다."));
415+
.orElseThrow(() -> new IllegalArgumentException("장소를 찾을 수 없습니다."));
459416
// log.info("location = {}", location.toString());
460417

461418

@@ -510,8 +467,7 @@ public CreateOnlineMeetingRoomResponse createOnlineMeeting(Long scheduleId) {
510467
Schedule schedule = scheduleQueryRepository.findById(scheduleId)
511468
.orElseThrow(() -> new NotFoundException("일정을 찾을 수 없습니다. (ID: " + scheduleId + ")"));
512469

513-
GoogleTokenResponse tokenResponse = zoomOAuthService.refreshAccessToken(zoomRefreshToken);
514-
String accessToken = tokenResponse.getAccessToken();
470+
String accessToken = zoomOAuthService.getAccessToken();
515471

516472
if (accessToken == null || accessToken.trim().isEmpty()) {
517473
throw new IllegalStateException("Zoom 인증 토큰을 갱신하는데 실패했습니다. 리프레시 토큰을 확인하세요.");
@@ -551,17 +507,17 @@ public CreateOnlineMeetingRoomResponse createOnlineMeeting(Long scheduleId) {
551507

552508
@Transactional
553509
public void WriteSuggestedLocation(Schedule schedule, WriteSuggestedLocationRequest request,
554-
String userId) {
510+
String userId) {
555511

556512
List<Location> locationList = locationQueryRepository.findByScheduleId(schedule.getId());
557513
boolean bool = true;
558514

559515
for (Location l : locationList) {
560-
if(l.getVoteCount() != 0) bool = false;
516+
if (l.getVoteCount() != 0) bool = false;
561517
}
562518

563519
if (bool) {
564-
ScheduleMember scheduleMember = getScheduleMember(schedule.getId(),userId);
520+
ScheduleMember scheduleMember = getScheduleMember(schedule.getId(), userId);
565521
Member member = memberRepository.findById(userId).orElseThrow();
566522
Optional<Metro> metro = getMetro(request.getLocationName());
567523

@@ -577,15 +533,14 @@ public void WriteSuggestedLocation(Schedule schedule, WriteSuggestedLocationRequ
577533
MetroTransfer metroTransfer = WriteSuggestedMetroTransferDto.fromDto(dto);
578534
metroTransferCommandRepository.save(metroTransfer);
579535
}
580-
}
581-
else {
536+
} else {
582537
throw new VoteAlreadyProgressException(ScheduleErrorCode.VOTE_ALREADY_PROGRESS);
583538
}
584539

585540
}
586541

587542
private Location saveSuggestedLocation(Schedule schedule, WriteSuggestedLocationRequest request,
588-
Optional<Metro> metro, Member member) {
543+
Optional<Metro> metro, Member member) {
589544
Location location;
590545
// DB에 존재하지 않는다면
591546
if (metro.isEmpty()) {

0 commit comments

Comments
 (0)