Skip to content

Commit

Permalink
v1.1.0 리팩토링 이후 배포
Browse files Browse the repository at this point in the history
v1.1.0 리팩토링 이후 배포
  • Loading branch information
Shin-Jae-Yoon authored Sep 21, 2023
2 parents ea62d2a + b7d27ad commit 8539525
Show file tree
Hide file tree
Showing 7 changed files with 257 additions and 59 deletions.
42 changes: 42 additions & 0 deletions .github/workflows/jtoon-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: JToon CI actions

on:
push:
branches: [ "develop" ]
pull_request:
branches: [ "main", "develop" ]

permissions:
contents: read

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: JDK 17 설정
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'corretto'

- name: Gradle 캐싱
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Gradle Grant 권한 부여
run: chmod +x gradlew

- name: Gradle 빌드
uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0
with:
arguments: build
75 changes: 75 additions & 0 deletions .github/workflows/jtoon-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: JToon deployment

on:
push:
branches: [ "main" ]

permissions:
contents: write

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: 배포 버전 추출
run: |
VERSION=$(grep -o -E "v[0-9]+\.[0-9]+\.[0-9]+" <<< "${{ github.event.head_commit.message }}")
echo "VERSION=${VERSION}" >> $GITHUB_ENV
- name: Github release 자동생성
uses: action-pack/github-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag: ${{ env.VERSION }}
title: JTOON - ${{ env.VERSION }}

- name: JDK 17 설정
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'corretto'

- name: Gradle 캐싱
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: 설정파일 application-prod.yml 생성
run: |
cd ./module-application/src/main/resources
touch ./application-prod.yml
echo "${{ secrets.APPLICATION_PROD }}" > ./application-prod.yml
shell: bash

- name: Gradle Grant 권한 부여
run: chmod +x gradlew

- name: Gradle 빌드
uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0
with:
arguments: build

- name: 멀티플랫폼 위한 Docker Buildx 설정
uses: docker/setup-buildx-action@v2

- name: Docker Hub 로그인, 빌드, 푸쉬
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- run: |
cd module-application
docker build -t ${{ secrets.DOCKER_HUB_USERNAME }}/${{ secrets.DOCKER_HUB_REPOSITORY }}:latest -f Dockerfile . --platform linux/x86_64
docker push ${{ secrets.DOCKER_HUB_USERNAME }}/${{ secrets.DOCKER_HUB_REPOSITORY }}:latest
docker tag ${{ secrets.DOCKER_HUB_USERNAME }}/${{ secrets.DOCKER_HUB_REPOSITORY }}:latest ${{ secrets.DOCKER_HUB_USERNAME }}/${{ secrets.DOCKER_HUB_REPOSITORY }}:${{ env.VERSION }}
docker push ${{ secrets.DOCKER_HUB_USERNAME }}/${{ secrets.DOCKER_HUB_REPOSITORY }}:${{ env.VERSION }}
34 changes: 34 additions & 0 deletions docs/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
## 📌 개발 내용

수정 or 추가, 개발된 내용에 대해서 명확하게 작성바랍니다.

## 📑 PR 포인트

좀 더 상세하게 리뷰 받고 싶은 부분을 기재해주세요.

<br/>

### 👥 협업을 위한 코드리뷰

1. 세상에 바보같은 질문은 없다.
2. 실수를 예방하는 팀이 아니라, 실수를 잘 다루는 팀이 되자.
3. 분업이 아닌 협업을 하자. 우린 모두 같은 문제를 이겨내기 위해 모였다.
4. 영원한 것은 없으니 대화를 하자.
5. 서로 존중하자.
6. 많이 부딪치고 깨닫고 배우자.
7. 부드럽게 설득하고 열린 마음으로 설득당해보자.

### ✅ 리마인더

- 본인의 로컬에서 정상 동작하는지 확인해주세요.
- 최신 브랜치를 Pull 받고 PR을 요청했는지 확인해주세요.
- API가 추가되었을 경우 테스트를 하고 PR을 올려주세요.
- Conflict가 났을 때, UI상에서 해결하지 말고, 본인 local에서 해결해주세요.
- Commit 메시지 제대로 작성해주세요.

### ⚙️ 코드리뷰 룰

- R(Request Change): 해당 블럭은 꼭 변경해주셨으면 좋겠습니다.
- C(Comment): 웬만하면 고려해주시면 좋겠습니다.
- Q(Question) : 해당 라인이 궁금합니다.
- A(Approve): 반영해도 좋고 넘어가도 좋습니다. 혹은 사소한 의견입니다.
12 changes: 12 additions & 0 deletions infrastructure/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,21 @@ services:
restart: always
expose:
- ${SERVER_PORT}
depends_on:
- redis
jtoon-green:
image: ${DOCKER_HUB_USERNAME}/${DOCKER_HUB_REPOSITORY}:latest
container_name: jtoon-green
restart: always
expose:
- ${SERVER_PORT}
depends_on:
- redis
redis:
image: redis:latest
container_name: redis
command: redis-server
ports:
- ${redis-inbound}:${redis-outbound}
volumes:
- ./data/:/data
117 changes: 80 additions & 37 deletions infrastructure/scripts/deploy.sh
Original file line number Diff line number Diff line change
@@ -1,48 +1,91 @@
#!/bin/sh

SLACK_WEB_HOOK="${slack_web_hook_url}"
IS_BLUE=$(docker ps | grep jtoon-blue)

NGINX_CONF="${PWD}/nginx/nginx.conf"

docker-compose up -d nginx
docker-compose up -d redis

if [ -n "$IS_BLUE" ]; then
echo "### BLUE => GREEN ###"
echo "1. jtoon-green 이미지 가져오고 실행"
docker-compose pull jtoon-green
docker-compose up -d jtoon-green
while [ 1 = 1 ]; do
echo "2. jtoon-green health check"
sleep 5
REQUEST=$(docker exec nginx curl http://jtoon-green:${SERVER_PORT})
if [ -n "$REQUEST" ]; then
echo "health check 성공"
break;
fi
done;
sed -i 's/jtoon-blue/jtoon-green/g' $NGINX_CONF
echo "3. nginx 설정파일 reload"
docker exec nginx service nginx reload
echo "4. jtoon-blue 컨테이너 종료"
docker-compose stop jtoon-blue
echo "### BLUE => GREEN ###"
echo "1. jtoon-green 이미지 가져오고 실행"
docker-compose pull jtoon-green
docker-compose up -d jtoon-green

attempt=1
while [ $attempt -le 24 ]; do
echo "2. jtoon-green health check (Attempt: $attempt)"
sleep 5
REQUEST=$(docker exec nginx curl http://jtoon-green:${SERVER_PORT})

if [ -n "$REQUEST" ]; then
echo "jtoon-green health check 성공"
sed -i 's/jtoon-blue/jtoon-green/g' $NGINX_CONF
echo "3. nginx 설정파일 reload"
docker exec nginx service nginx reload
echo "4. jtoon-blue 컨테이너 종료"
docker-compose stop jtoon-blue

echo "slack 알람 발송 : $(date +%Y)-$(date +%m)-$(date +%d) $(date +%H):$(date +%M):$(date +%S)"
json="{ \"text\": \"jtoon-green 배포 성공 !! -> 배포 성공 시각: $(date '+%Y-%m-%d %H:%M:%S')\" }"
curl -X POST -H 'Content-type: application/json' --data "$json" "$slack_web_hook"

break;
fi

if [ $attempt -eq 24 ]; then
echo "jtoon-green 배포 중 문제 발생 : $(date +%Y)-$(date +%m)-$(date +%d) $(date +%H):$(date +%M):$(date +%S)"
echo "slack 알람 발송 : $(date +%Y)-$(date +%m)-$(date +%d) $(date +%H):$(date +%M):$(date +%S)"
json="{ \"text\": \"jtoon-green 배포 중 문제가 발생하여 배포가 비정상 중단되었으니 확인 부탁드립니다 -> 문제 발생 시각: $(date '+%Y-%m-%d %H:%M:%S')\" }"
curl -X POST -H 'Content-type: application/json' --data "$json" "$slack_web_hook"

docker-compose stop jtoon-green

exit 1;
fi

attempt=$((attempt+1))
done;
else
echo "### GREEN => BLUE ###"
echo "1. jtoon-blue 이미지 가져오고 실행"
docker-compose pull jtoon-blue
docker-compose up -d jtoon-blue
while [ 1 = 1 ]; do
echo "2. jtoon-blue health check"
sleep 5
REQUEST=$(docker exec nginx curl http://jtoon-blue:${SERVER_PORT})
if [ -n "$REQUEST" ]; then
echo "health check 성공"
break;
fi
done;
sed -i 's/jtoon-green/jtoon-blue/g' $NGINX_CONF
echo $NGINX_CONF
echo "3. nginx 설정파일 reload"
docker exec nginx service nginx reload
echo "4. jtoon-green 컨테이너 종료"
docker-compose stop jtoon-green
echo "### GREEN => BLUE ###"
echo "1. jtoon-blue 이미지 가져오고 실행"
docker-compose pull jtoon-blue
docker-compose up -d jtoon-blue

attempt=1
while [ $attempt -le 24 ]; do
echo "2. jtoon-blue health check (Attempt: $attempt)"
sleep 5
REQUEST=$(docker exec nginx curl http://jtoon-blue:${SERVER_PORT})

if [ -n "$REQUEST" ]; then
echo "jtoon-blue health check 성공"
sed -i 's/jtoon-green/jtoon-blue/g' $NGINX_CONF
echo "3. nginx 설정파일 reload"
docker exec nginx service nginx reload
echo "4. jtoon-green 컨테이너 종료"
docker-compose stop jtoon-green

echo "slack 알람 발송 : $(date +%Y)-$(date +%m)-$(date +%d) $(date +%H):$(date +%M):$(date +%S)"
json="{ \"text\": \"jtoon-blue 배포 성공 !! -> 배포 성공 시각: $(date '+%Y-%m-%d %H:%M:%S')\" }"
curl -X POST -H 'Content-type: application/json' --data "$json" "$slack_web_hook"

break;
fi

if [ $attempt -eq 24 ]; then
echo "jtoon-blue 배포 중 문제 발생 : $(date +%Y)-$(date +%m)-$(date +%d) $(date +%H):$(date +%M):$(date +%S)"
echo "slack 알람 발송 : $(date +%Y)-$(date +%m)-$(date +%d) $(date +%H):$(date +%M):$(date +%S)"
json="{ \"text\": \"jtoon-blue 배포 중 문제가 발생하여 배포가 비정상 중단되었으니 확인 부탁드립니다 -> 문제 발생 시각: $(date '+%Y-%m-%d %H:%M:%S')\" }"
curl -X POST -H 'Content-type: application/json' --data "$json" "$slack_web_hook"

docker-compose stop jtoon-blue

exit 1;
fi

attempt=$((attempt+1))
done;
fi
9 changes: 9 additions & 0 deletions module-application/app-api/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
### Docker 이미지를 생성할 때 기반이 되는 베이스 이미지를 설정한다.
FROM amazoncorretto:17
### 조셉팀 ^-^
MAINTAINER 박세연, 신재윤, 홍혁준, 김영명, 김희빈
### 경로에 해당하는 파일을 Docker 이미지 내부로 복사한다.
COPY ${PWD}/build/libs/app-api-0.0.1-SNAPSHOT.jar jtoon.jar
### Docker 컨테이너가 시작될 때 실행할 명령을 지정한다.

ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=prod", "/jtoon.jar"]
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,21 @@

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.test.context.ActiveProfiles;

import jakarta.mail.MessagingException;
import shop.jtoon.entity.Mail;

@SpringBootTest
@ActiveProfiles("test")
@ExtendWith(MockitoExtension.class)
class SmtpServiceTest {

@Autowired
@Mock
JavaMailSenderImpl javaMailSender;

@Test
@DisplayName("SMTP 연결 성공")
void smtp_connection_success() {
// when, then
assertThatCode(() -> javaMailSender.testConnection()).doesNotThrowAnyException();
}

@Test
@DisplayName("SMTP 연결 실패")
void smtp_connection_fail() throws MessagingException {
// when, then
JavaMailSenderImpl emptyJavaMailSender = new JavaMailSenderImpl();
assertThatThrownBy(emptyJavaMailSender::testConnection).isInstanceOf(MessagingException.class);
}

@Test
@DisplayName("인증 Mail 생성 성공")
void create_authentication_mail_success() {
Expand Down

0 comments on commit 8539525

Please sign in to comment.