diff --git a/.deploy/Dockerfile b/.deploy/Dockerfile new file mode 100644 index 00000000..25848cbe --- /dev/null +++ b/.deploy/Dockerfile @@ -0,0 +1,16 @@ +FROM openjdk:11-jdk + +# 타임존 설정 +ENV TZ=Asia/Seoul +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +ARG CACHEBREAKER=1 +ARG JAR_FILE=./build/libs/backend-0.0.1-SNAPSHOT.jar +COPY ${JAR_FILE} app.jar + +# 문서를 이미지의 /static/docs 디렉토리에 복사 +COPY ./build/docs/asciidoc/*.html /static/docs/ + +# 애플리케이션 실행 시 -cp 옵션을 사용하여 /static/docs 디렉토리를 클래스패스에 추가 +ENTRYPOINT ["java","-cp",".:/static/docs","-jar","/app.jar"] + diff --git a/.deploy/deploy_dev.sh b/.deploy/deploy_dev.sh new file mode 100644 index 00000000..0c2181d8 --- /dev/null +++ b/.deploy/deploy_dev.sh @@ -0,0 +1,67 @@ +DOCKER_APP_NAME=meetup +DOCKER_USERNAME=modagbul + +# 최신 이미지 가져오기 +docker pull ${DOCKER_USERNAME}/moing_dev:blue +docker pull ${DOCKER_USERNAME}/moing_dev:green + +# 현재 실행 중인 컨테이너를 확인 (blue 또는 green) +EXIST_BLUE=$(docker ps --filter name=${DOCKER_APP_NAME}-blue --filter status=running -q) +EXIST_GREEN=$(docker ps --filter name=${DOCKER_APP_NAME}-green --filter status=running -q) + +# 둘 다 실행 중이지 않을 경우 blue 실행 +if [ -z "$EXIST_BLUE" ] && [ -z "$EXIST_GREEN" ]; then + echo "No containers running. Starting blue up" + + # 만약 컨테이너가 중지된 상태로 존재하면 삭제한다. + if [ "$(docker ps -a --filter name=${DOCKER_APP_NAME}-blue -q)" ]; then + docker rm ${DOCKER_APP_NAME}-blue + fi + + docker run -d --name ${DOCKER_APP_NAME}-blue -p 8081:8080 -e TZ=Asia/Seoul ${DOCKER_USERNAME}/moing_dev:blue + BEFORE_COMPOSE_COLOR="green" + AFTER_COMPOSE_COLOR="blue" +elif [ -z "$EXIST_BLUE" ]; then + echo "blue up" + + # 만약 컨테이너가 중지된 상태로 존재하면 삭제한다. + if [ "$(docker ps -a --filter name=${DOCKER_APP_NAME}-blue -q)" ]; then + docker rm ${DOCKER_APP_NAME}-blue + fi + + docker run -d --name ${DOCKER_APP_NAME}-blue -p 8081:8080 -e TZ=Asia/Seoul ${DOCKER_USERNAME}/moing_dev:blue + BEFORE_COMPOSE_COLOR="green" + AFTER_COMPOSE_COLOR="blue" +else + echo "green up" + + # 만약 컨테이너가 중지된 상태로 존재하면 삭제한다. + if [ "$(docker ps -a --filter name=${DOCKER_APP_NAME}-green -q)" ]; then + docker rm ${DOCKER_APP_NAME}-green + fi + + docker run -d --name ${DOCKER_APP_NAME}-green -p 8082:8080 -e TZ=Asia/Seoul ${DOCKER_USERNAME}/moing_dev:green + BEFORE_COMPOSE_COLOR="blue" + AFTER_COMPOSE_COLOR="green" +fi + + +sleep 40 + +# 새로운 컨테이너가 제대로 실행되었는지 확인 +EXIST_AFTER=$(docker ps --filter name=${DOCKER_APP_NAME}-${AFTER_COMPOSE_COLOR} --filter status=running -q) +if [ -n "$EXIST_AFTER" ]; then + # nginx.config를 컨테이너에 맞게 변경해주고 reload 한다 + cp ./nginx.${AFTER_COMPOSE_COLOR}.conf /etc/nginx/nginx.conf + sudo nginx -s reload + + # 이전 컨테이너 종료 + docker stop ${DOCKER_APP_NAME}-${BEFORE_COMPOSE_COLOR} + docker rm ${DOCKER_APP_NAME}-${BEFORE_COMPOSE_COLOR} + echo "$BEFORE_COMPOSE_COLOR down" +else + # Docker logs + LOGS=$(docker logs ${DOCKER_APP_NAME}-${AFTER_COMPOSE_COLOR} 2>&1) + echo "Error: ${DOCKER_APP_NAME}-${AFTER_COMPOSE_COLOR} failed to start." + echo "$LOGS" +fi \ No newline at end of file diff --git a/.deploy/deploy_prod.sh b/.deploy/deploy_prod.sh new file mode 100644 index 00000000..91c86b59 --- /dev/null +++ b/.deploy/deploy_prod.sh @@ -0,0 +1,67 @@ +DOCKER_APP_NAME=meetup +DOCKER_USERNAME=modagbul + +# 최신 이미지 가져오기 +docker pull ${DOCKER_USERNAME}/moing_prod:blue +docker pull ${DOCKER_USERNAME}/moing_prod:green + +# 현재 실행 중인 컨테이너를 확인 (blue 또는 green) +EXIST_BLUE=$(docker ps --filter name=${DOCKER_APP_NAME}-blue --filter status=running -q) +EXIST_GREEN=$(docker ps --filter name=${DOCKER_APP_NAME}-green --filter status=running -q) + +# 둘 다 실행 중이지 않을 경우 blue 실행 +if [ -z "$EXIST_BLUE" ] && [ -z "$EXIST_GREEN" ]; then + echo "No containers running. Starting blue up" + + # 만약 컨테이너가 중지된 상태로 존재하면 삭제한다. + if [ "$(docker ps -a --filter name=${DOCKER_APP_NAME}-blue -q)" ]; then + docker rm ${DOCKER_APP_NAME}-blue + fi + + docker run -d --name ${DOCKER_APP_NAME}-blue -p 8081:8080 -e TZ=Asia/Seoul ${DOCKER_USERNAME}/moing_prod:blue + BEFORE_COMPOSE_COLOR="green" + AFTER_COMPOSE_COLOR="blue" +elif [ -z "$EXIST_BLUE" ]; then + echo "blue up" + + # 만약 컨테이너가 중지된 상태로 존재하면 삭제한다. + if [ "$(docker ps -a --filter name=${DOCKER_APP_NAME}-blue -q)" ]; then + docker rm ${DOCKER_APP_NAME}-blue + fi + + docker run -d --name ${DOCKER_APP_NAME}-blue -p 8081:8080 -e TZ=Asia/Seoul ${DOCKER_USERNAME}/moing_prod:blue + BEFORE_COMPOSE_COLOR="green" + AFTER_COMPOSE_COLOR="blue" +else + echo "green up" + + # 만약 컨테이너가 중지된 상태로 존재하면 삭제한다. + if [ "$(docker ps -a --filter name=${DOCKER_APP_NAME}-green -q)" ]; then + docker rm ${DOCKER_APP_NAME}-green + fi + + docker run -d --name ${DOCKER_APP_NAME}-green -p 8082:8080 -e TZ=Asia/Seoul ${DOCKER_USERNAME}/moing_prod:green + BEFORE_COMPOSE_COLOR="blue" + AFTER_COMPOSE_COLOR="green" +fi + + +sleep 40 + +# 새로운 컨테이너가 제대로 실행되었는지 확인 +EXIST_AFTER=$(docker ps --filter name=${DOCKER_APP_NAME}-${AFTER_COMPOSE_COLOR} --filter status=running -q) +if [ -n "$EXIST_AFTER" ]; then + # nginx.config를 컨테이너에 맞게 변경해주고 reload 한다 + cp ./nginx.${AFTER_COMPOSE_COLOR}.conf /etc/nginx/nginx.conf + sudo nginx -s reload + + # 이전 컨테이너 종료 + docker stop ${DOCKER_APP_NAME}-${BEFORE_COMPOSE_COLOR} + docker rm ${DOCKER_APP_NAME}-${BEFORE_COMPOSE_COLOR} + echo "$BEFORE_COMPOSE_COLOR down" +else + # Docker logs + LOGS=$(docker logs ${DOCKER_APP_NAME}-${AFTER_COMPOSE_COLOR} 2>&1) + echo "Error: ${DOCKER_APP_NAME}-${AFTER_COMPOSE_COLOR} failed to start." + echo "$LOGS" +fi \ No newline at end of file diff --git a/.github/workflows/CD-dev.yml b/.github/workflows/CD-dev.yml new file mode 100644 index 00000000..40cd9a33 --- /dev/null +++ b/.github/workflows/CD-dev.yml @@ -0,0 +1,123 @@ +name: CD-dev + +on: + push: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + env: + working-directory: ./ + APPLICATION: ${{ secrets.APPLICATION_DEV }} + GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS_DEV }} + APPLE_KEY: ${{ secrets.APPLE_KEY_DEV }} + + steps: + # 소스 코드 체크아웃 + - uses: actions/checkout@v2 + + # JDK 11 설정 + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + + # Gradle 패키지 캐시 + - name: Cache Gradle packages + uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + # 설정 파일 생성 + - run: | + mkdir ./src/main/resources + cd ./src/main/resources + touch ./application.yml + echo "${{env.APPLICATION}}" > ./application.yml + touch ./firebase-key.json + echo "${{env.GOOGLE_APPLICATION_CREDENTIALS}}" | base64 --decode > ./firebase-key.json + touch ./apple-key.p8 + echo "${{env.APPLE_KEY}}" > ./apple-key.p8 + + # 설정 파일을 작업공간에 저장 + - uses: actions/upload-artifact@v2 + with: + name: application.yml + path: ./src/main/resources/application.yml + + - uses: actions/upload-artifact@v2 + with: + name: firebase-key.json + path: ./src/main/resources/firebase-key.json + + - uses: actions/upload-artifact@v2 + with: + name: apple-key.p8 + path: ./src/main/resources/apple-key.p8 + + # gradlew 권한 설정 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + working-directory: ${{ env.working-directory }} + + # Gradle로 빌드 + - name: Build with Gradle + run: ./gradlew build + working-directory: ${{ env.working-directory }} + + # Gradle 캐시 정리 + - name: Cleanup Gradle Cache + if: ${{ always() }} + run: | + rm -f ~/.gradle/caches/modules-2/modules-2.lock + rm -f ~/.gradle/caches/modules-2/gc.properties + + # Docker 이미지 빌드 및 푸시 + - name: Docker build + run: | + docker build --no-cache -f ./.deploy/Dockerfile -t ${{ secrets.DOCKER_USERNAME_DEV }}/moing_dev:green . + docker build --no-cache -f ./.deploy/Dockerfile -t ${{ secrets.DOCKER_USERNAME_DEV }}/moing_dev:blue . + + + - name: Docker Hub Login + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKER_USERNAME_DEV }} + password: ${{ secrets.DOCKER_PASSWORD_DEV }} + + - name: Docker push + run: | + docker push ${{ secrets.DOCKER_USERNAME_DEV }}/moing_dev:green + docker push ${{ secrets.DOCKER_USERNAME_DEV }}/moing_dev:blue + + # EC2로 deploy.sh 전송 + - name: Deploy deploy.sh to EC2 + uses: appleboy/scp-action@master + with: + host: ${{ secrets.EC2_SERVER_HOST_DEV }} + username: ec2-user + key: ${{ secrets.PRIVATE_KEY_DEV }} + source: "./.deploy/deploy_dev.sh" + target: "/home/ec2-user/" + + # 배포 스크립트 실행 + - name: Deploy on EC2 + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.EC2_SERVER_HOST_DEV }} + username: ec2-user + key: ${{ secrets.PRIVATE_KEY_DEV }} + envs: GITHUB_SHA + script: | + chmod +x /home/ec2-user/deploy_dev.sh + /home/ec2-user/deploy_dev.sh \ No newline at end of file diff --git a/.github/workflows/CD-prod.yml b/.github/workflows/CD-prod.yml new file mode 100644 index 00000000..2c132f0c --- /dev/null +++ b/.github/workflows/CD-prod.yml @@ -0,0 +1,123 @@ +name: CD-prod + +on: + push: + branches: [ "release" ] + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + env: + working-directory: ./ + APPLICATION: ${{ secrets.APPLICATION_PROD }} + GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS_PROD }} + APPLE_KEY: ${{ secrets.APPLE_KEY_PROD }} + + steps: + # 소스 코드 체크아웃 + - uses: actions/checkout@v2 + + # JDK 11 설정 + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + + # Gradle 패키지 캐시 + - name: Cache Gradle packages + uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + # 설정 파일 생성 + - run: | + mkdir ./src/main/resources + cd ./src/main/resources + touch ./application.yml + echo "${{env.APPLICATION}}" > ./application.yml + touch ./firebase-key.json + echo "${{env.GOOGLE_APPLICATION_CREDENTIALS}}" | base64 --decode > ./firebase-key.json + touch ./apple-key.p8 + echo "${{env.APPLE_KEY}}" > ./apple-key.p8 + + # 설정 파일을 작업공간에 저장 + - uses: actions/upload-artifact@v2 + with: + name: application.yml + path: ./src/main/resources/application.yml + + - uses: actions/upload-artifact@v2 + with: + name: firebase-key.json + path: ./src/main/resources/firebase-key.json + + - uses: actions/upload-artifact@v2 + with: + name: apple-key.p8 + path: ./src/main/resources/apple-key.p8 + + # gradlew 권한 설정 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + working-directory: ${{ env.working-directory }} + + # Gradle로 빌드 + - name: Build with Gradle + run: ./gradlew build + working-directory: ${{ env.working-directory }} + + # Gradle 캐시 정리 + - name: Cleanup Gradle Cache + if: ${{ always() }} + run: | + rm -f ~/.gradle/caches/modules-2/modules-2.lock + rm -f ~/.gradle/caches/modules-2/gc.properties + + # Docker 이미지 빌드 및 푸시 + - name: Docker build + run: | + docker build --no-cache -f ./.deploy/Dockerfile -t ${{ secrets.DOCKER_USERNAME_PROD }}/moing_prod:green . + docker build --no-cache -f ./.deploy/Dockerfile -t ${{ secrets.DOCKER_USERNAME_PROD }}/moing_prod:blue . + + + - name: Docker Hub Login + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKER_USERNAME_PROD }} + password: ${{ secrets.DOCKER_PASSWORD_PROD }} + + - name: Docker push + run: | + docker push ${{ secrets.DOCKER_USERNAME_PROD }}/moing_prod:green + docker push ${{ secrets.DOCKER_USERNAME_PROD }}/moing_prod:blue + + # EC2로 deploy.sh 전송 + - name: Deploy deploy.sh to EC2 + uses: appleboy/scp-action@master + with: + host: ${{ secrets.EC2_SERVER_HOST_PROD }} + username: ec2-user + key: ${{ secrets.PRIVATE_KEY_PROD }} + source: "./.deploy/deploy_prod.sh" + target: "/home/ec2-user/" + + # 배포 스크립트 실행 + - name: Deploy on EC2 + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.EC2_SERVER_HOST_PROD }} + username: ec2-user + key: ${{ secrets.PRIVATE_KEY_PROD }} + envs: GITHUB_SHA + script: | + chmod +x /home/ec2-user/deploy_prod.sh + /home/ec2-user/deploy_prod.sh \ No newline at end of file diff --git a/.github/workflows/CI-dev.yml b/.github/workflows/CI-dev.yml new file mode 100644 index 00000000..1ef81d51 --- /dev/null +++ b/.github/workflows/CI-dev.yml @@ -0,0 +1,85 @@ +name: CI-dev + +on: + pull_request: + branches: + - main + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + env: + working-directory: ./ + APPLICATION: ${{ secrets.APPLICATION_DEV }} + GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS_DEV }} + APPLE_KEY: ${{ secrets.APPLE_KEY_DEV }} + + steps: + # 소스 코드 체크아웃 + - uses: actions/checkout@v2 + + # JDK 11 설정 + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + + # Gradle 패키지 캐시 + - name: Cache Gradle packages + uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + # 설정 파일 생성 + - run: | + mkdir ./src/main/resources + cd ./src/main/resources + touch ./application.yml + echo "${{env.APPLICATION}}" > ./application.yml + touch ./firebase-key.json + echo "${{env.GOOGLE_APPLICATION_CREDENTIALS}}" | base64 --decode > ./firebase-key.json + touch ./apple-key.p8 + echo "${{env.APPLE_KEY}}" > ./apple-key.p8 + + # 설정 파일을 작업공간에 저장 + - uses: actions/upload-artifact@v2 + with: + name: application.yml + path: ./src/main/resources/application.yml + + - uses: actions/upload-artifact@v2 + with: + name: firebase-key.json + path: ./src/main/resources/firebase-key.json + + - uses: actions/upload-artifact@v2 + with: + name: apple-key.p8 + path: ./src/main/resources/apple-key.p8 + + # gradlew 권한 설정 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + working-directory: ${{ env.working-directory }} + + # Gradle로 빌드 + - name: Build with Gradle + run: ./gradlew build + working-directory: ${{ env.working-directory }} + + # Gradle 캐시 정리 + - name: Cleanup Gradle Cache + if: ${{ always() }} + run: | + rm -f ~/.gradle/caches/modules-2/modules-2.lock + rm -f ~/.gradle/caches/modules-2/gc.properties + diff --git a/.github/workflows/CI-prod.yml b/.github/workflows/CI-prod.yml new file mode 100644 index 00000000..f7ed564f --- /dev/null +++ b/.github/workflows/CI-prod.yml @@ -0,0 +1,84 @@ +name: CI-prod + +on: + pull_request: + branches: + - release + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + env: + working-directory: ./ + APPLICATION: ${{ secrets.APPLICATION_PROD }} + GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS_PROD }} + APPLE_KEY: ${{ secrets.APPLE_KEY_PROD }} + + steps: + # 소스 코드 체크아웃 + - uses: actions/checkout@v2 + + # JDK 11 설정 + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'adopt' + + # Gradle 패키지 캐시 + - name: Cache Gradle packages + uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + # 설정 파일 생성 + - run: | + mkdir ./src/main/resources + cd ./src/main/resources + touch ./application.yml + echo "${{env.APPLICATION}}" > ./application.yml + touch ./firebase-key.json + echo "${{env.GOOGLE_APPLICATION_CREDENTIALS}}" | base64 --decode > ./firebase-key.json + touch ./apple-key.p8 + echo "${{env.APPLE_KEY}}" > ./apple-key.p8 + + # 설정 파일을 작업공간에 저장 + - uses: actions/upload-artifact@v2 + with: + name: application.yml + path: ./src/main/resources/application.yml + + - uses: actions/upload-artifact@v2 + with: + name: firebase-key.json + path: ./src/main/resources/firebase-key.json + + - uses: actions/upload-artifact@v2 + with: + name: apple-key.p8 + path: ./src/main/resources/apple-key.p8 + + # gradlew 권한 설정 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + working-directory: ${{ env.working-directory }} + + # Gradle로 빌드 + - name: Build with Gradle + run: ./gradlew build + working-directory: ${{ env.working-directory }} + + # Gradle 캐시 정리 + - name: Cleanup Gradle Cache + if: ${{ always() }} + run: | + rm -f ~/.gradle/caches/modules-2/modules-2.lock + rm -f ~/.gradle/caches/modules-2/gc.properties diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 2c3bec49..38c626f3 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -1,114 +1,114 @@ -name: CI/CD - -on: - push: - branches: [ "main" ] - -permissions: - contents: read - -jobs: - build: - runs-on: ubuntu-latest - env: - working-directory: ./ - APPLICATION: ${{ secrets.APPLICATION }} - GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }} - APPLE_KEY: ${{ secrets.APPLE_KEY }} - - steps: - # 소스 코드 체크아웃 - - uses: actions/checkout@v2 - - # JDK 11 설정 - - name: Set up JDK 11 - uses: actions/setup-java@v2 - with: - java-version: '11' - distribution: 'adopt' - - # Gradle 패키지 캐시 - - name: Cache Gradle packages - uses: actions/cache@v2 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - ${{ runner.os }}-gradle- - - # 설정 파일 생성 - - run: | - mkdir ./src/main/resources - cd ./src/main/resources - touch ./application.yml - echo "${{env.APPLICATION}}" > ./application.yml - touch ./firebase-key.json - echo "${{env.GOOGLE_APPLICATION_CREDENTIALS}}" | base64 --decode > ./firebase-key.json - touch ./apple-key.p8 - echo "${{env.APPLE_KEY}}" > ./apple-key.p8 - - # 설정 파일을 작업공간에 저장 - - uses: actions/upload-artifact@v2 - with: - name: application.yml - path: ./src/main/resources/application.yml - - - uses: actions/upload-artifact@v2 - with: - name: firebase-key.json - path: ./src/main/resources/firebase-key.json - - - uses: actions/upload-artifact@v2 - with: - name: apple-key.p8 - path: ./src/main/resources/apple-key.p8 - - # gradlew 권한 설정 - - name: Grant execute permission for gradlew - run: chmod +x gradlew - working-directory: ${{ env.working-directory }} - - # Gradle로 빌드 - - name: Build with Gradle - run: ./gradlew build - working-directory: ${{ env.working-directory }} - - # Gradle 캐시 정리 - - name: Cleanup Gradle Cache - if: ${{ always() }} - run: | - rm -f ~/.gradle/caches/modules-2/modules-2.lock - rm -f ~/.gradle/caches/modules-2/gc.properties - - # Docker 이미지 빌드 및 푸시 - - name: Docker build - run: | - docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }} - docker build --no-cache -t ${{ secrets.DOCKER_USERNAME }}/moing:green . - docker build --no-cache -t ${{ secrets.DOCKER_USERNAME }}/moing:blue . - docker push ${{ secrets.DOCKER_USERNAME }}/moing:green - docker push ${{ secrets.DOCKER_USERNAME }}/moing:blue - - # EC2로 deploy.sh 전송 - - name: Deploy deploy.sh to EC2 - uses: appleboy/scp-action@master - with: - host: ${{ secrets.EC2_SERVER_HOST }} - username: ec2-user - key: ${{ secrets.PRIVATE_KEY }} - source: "./deploy.sh" - target: "/home/ec2-user/" - - # 배포 스크립트 실행 - - name: Deploy on EC2 - uses: appleboy/ssh-action@master - with: - host: ${{ secrets.EC2_SERVER_HOST }} - username: ec2-user - key: ${{ secrets.PRIVATE_KEY }} - envs: GITHUB_SHA - script: | - chmod +x /home/ec2-user/deploy.sh - /home/ec2-user/deploy.sh +#name: CI/CD +# +#on: +# push: +# branches: [ "main" ] +# +#permissions: +# contents: read +# +#jobs: +# build: +# runs-on: ubuntu-latest +# env: +# working-directory: ./ +# APPLICATION: ${{ secrets.APPLICATION }} +# GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }} +# APPLE_KEY: ${{ secrets.APPLE_KEY }} +# +# steps: +# # 소스 코드 체크아웃 +# - uses: actions/checkout@v2 +# +# # JDK 11 설정 +# - name: Set up JDK 11 +# uses: actions/setup-java@v2 +# with: +# java-version: '11' +# distribution: 'adopt' +# +# # Gradle 패키지 캐시 +# - name: Cache Gradle packages +# uses: actions/cache@v2 +# with: +# path: | +# ~/.gradle/caches +# ~/.gradle/wrapper +# key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} +# restore-keys: | +# ${{ runner.os }}-gradle- +# +# # 설정 파일 생성 +# - run: | +# mkdir ./src/main/resources +# cd ./src/main/resources +# touch ./application.yml +# echo "${{env.APPLICATION}}" > ./application.yml +# touch ./firebase-key.json +# echo "${{env.GOOGLE_APPLICATION_CREDENTIALS}}" | base64 --decode > ./firebase-key.json +# touch ./apple-key.p8 +# echo "${{env.APPLE_KEY}}" > ./apple-key.p8 +# +# # 설정 파일을 작업공간에 저장 +# - uses: actions/upload-artifact@v2 +# with: +# name: application.yml +# path: ./src/main/resources/application.yml +# +# - uses: actions/upload-artifact@v2 +# with: +# name: firebase-key.json +# path: ./src/main/resources/firebase-key.json +# +# - uses: actions/upload-artifact@v2 +# with: +# name: apple-key.p8 +# path: ./src/main/resources/apple-key.p8 +# +# # gradlew 권한 설정 +# - name: Grant execute permission for gradlew +# run: chmod +x gradlew +# working-directory: ${{ env.working-directory }} +# +# # Gradle로 빌드 +# - name: Build with Gradle +# run: ./gradlew build +# working-directory: ${{ env.working-directory }} +# +# # Gradle 캐시 정리 +# - name: Cleanup Gradle Cache +# if: ${{ always() }} +# run: | +# rm -f ~/.gradle/caches/modules-2/modules-2.lock +# rm -f ~/.gradle/caches/modules-2/gc.properties +# +# # Docker 이미지 빌드 및 푸시 +# - name: Docker build +# run: | +# docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }} +# docker build --no-cache -t ${{ secrets.DOCKER_USERNAME }}/moing:green . +# docker build --no-cache -t ${{ secrets.DOCKER_USERNAME }}/moing:blue . +# docker push ${{ secrets.DOCKER_USERNAME }}/moing:green +# docker push ${{ secrets.DOCKER_USERNAME }}/moing:blue +# +# # EC2로 deploy.sh 전송 +# - name: Deploy deploy.sh to EC2 +# uses: appleboy/scp-action@master +# with: +# host: ${{ secrets.EC2_SERVER_HOST }} +# username: ec2-user +# key: ${{ secrets.PRIVATE_KEY }} +# source: "./deploy.sh" +# target: "/home/ec2-user/" +# +# # 배포 스크립트 실행 +# - name: Deploy on EC2 +# uses: appleboy/ssh-action@master +# with: +# host: ${{ secrets.EC2_SERVER_HOST }} +# username: ec2-user +# key: ${{ secrets.PRIVATE_KEY }} +# envs: GITHUB_SHA +# script: | +# chmod +x /home/ec2-user/deploy.sh +# /home/ec2-user/deploy.sh diff --git a/src/docs/asciidoc/Overview.adoc b/src/docs/asciidoc/Overview.adoc index fc4553d3..f9d7db68 100644 --- a/src/docs/asciidoc/Overview.adoc +++ b/src/docs/asciidoc/Overview.adoc @@ -103,6 +103,10 @@ | 소모임을 가입할 때 | 소모임을 이미 가입함 +| `T0005` +| 소모임을 가입할 때 +| 소모임이 삭제됨 + |=== === MyPage ErrorCode diff --git a/src/main/java/com/moing/backend/domain/team/application/service/SignInTeamUseCase.java b/src/main/java/com/moing/backend/domain/team/application/service/SignInTeamUseCase.java index 093a098a..0603d156 100644 --- a/src/main/java/com/moing/backend/domain/team/application/service/SignInTeamUseCase.java +++ b/src/main/java/com/moing/backend/domain/team/application/service/SignInTeamUseCase.java @@ -5,6 +5,7 @@ import com.moing.backend.domain.team.application.dto.response.CreateTeamResponse; import com.moing.backend.domain.team.domain.entity.Team; import com.moing.backend.domain.team.domain.service.TeamGetService; +import com.moing.backend.domain.team.exception.DeletedTeamException; import com.moing.backend.domain.teamMember.domain.service.TeamMemberSaveService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -25,4 +26,5 @@ public CreateTeamResponse signInTeam(String socialId, Long teamId){ teamMemberSaveService.addTeamMember(team, member); return new CreateTeamResponse(team.getTeamId()); } + } diff --git a/src/main/java/com/moing/backend/domain/team/exception/DeletedTeamException.java b/src/main/java/com/moing/backend/domain/team/exception/DeletedTeamException.java new file mode 100644 index 00000000..53bfdd47 --- /dev/null +++ b/src/main/java/com/moing/backend/domain/team/exception/DeletedTeamException.java @@ -0,0 +1,11 @@ +package com.moing.backend.domain.team.exception; + +import com.moing.backend.global.response.ErrorCode; +import org.springframework.http.HttpStatus; + +public class DeletedTeamException extends TeamException{ + public DeletedTeamException(){ + super(ErrorCode.DELETED_TEAM_ERROR, + HttpStatus.NOT_FOUND); + } +} diff --git a/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java b/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java index d60d33a2..94830dd3 100644 --- a/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java +++ b/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java @@ -4,6 +4,7 @@ import com.moing.backend.domain.team.domain.entity.Team; import com.moing.backend.domain.team.exception.AlreadyJoinTeamException; import com.moing.backend.domain.team.exception.AlreadyWithdrawTeamException; +import com.moing.backend.domain.team.exception.DeletedTeamException; import com.moing.backend.domain.teamMember.domain.entity.TeamMember; import com.moing.backend.domain.teamMember.domain.repository.TeamMemberRepository; import com.moing.backend.global.annotation.DomainService; @@ -20,6 +21,8 @@ public class TeamMemberSaveService { public void addTeamMember(Team team, Member member) { Optional teamMember = teamMemberRepository.findTeamMemberByTeamAndMember(team, member); + checkDeletion(team); + if (teamMember.isPresent()) { handleExistingMember(teamMember.get()); } else { @@ -43,4 +46,9 @@ private void addNewTeamMember(Team team, Member member) { this.teamMemberRepository.save(newMember); } + private void checkDeletion(Team team){ + if(team.isDeleted()) + throw new DeletedTeamException(); + } + } diff --git a/src/main/java/com/moing/backend/global/response/ErrorCode.java b/src/main/java/com/moing/backend/global/response/ErrorCode.java index 9a82564b..d5aa9c43 100644 --- a/src/main/java/com/moing/backend/global/response/ErrorCode.java +++ b/src/main/java/com/moing/backend/global/response/ErrorCode.java @@ -46,6 +46,7 @@ public enum ErrorCode { NOT_AUTH_BY_TEAM_ERROR("T0002","권한이 없습니다."), ALREADY_WITHDRAW_ERROR("T0003","이미 탈퇴한 회원입니다."), ALREADY_JOIN_ERROR("T0004","이미 가입한 회원입니다."), + DELETED_TEAM_ERROR("T0005", "삭제된 소모임입니다."), //마이페이지 관련 에러 코드 INVALID_ALARM_ERROR("MP0001","유효하지 않는 알람 입력값입니다"),