diff --git a/.github/workflows/Deploy.yml b/.github/workflows/Deploy.yml new file mode 100644 index 00000000..d18d3a32 --- /dev/null +++ b/.github/workflows/Deploy.yml @@ -0,0 +1,81 @@ +name: Deploy to AWS CodeDeploy + +on: + push: + branches: + - deploy + +env: + S3_BUCKET_NAME: sursim-img + APPLICATION_NAME: boomerang + DEPLOYMENT_GROUP_NAME: boomerang-deploy-group + REGION: ap-northeast-2 + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up JDK 21 + uses: actions/setup-java@v3 + with: + java-version: '21' + distribution: 'temurin' + + - name: Create application.properties from Secrets + working-directory: ./boomerang + run: | + echo "Current directory: $(pwd)" + mkdir -p src/main/resources + echo "${{ secrets.APPLICATION }}" > src/main/resources/application.properties + cat src/main/resources/application.properties + + - name: Grant execute permission for gradlew + working-directory: ./boomerang + run: chmod +x ./gradlew + + - name: Build with Gradle + working-directory: ./boomerang + run: ./gradlew build -x test + + - name: Convert Windows line endings to Unix line endings + run: | + # Convert Windows line endings to Unix line endings for all scripts in the 'scripts' directory + find ./scripts -type f -name "*.sh" -exec sed -i 's/\r$//' {} \; + + - name: Make zip file including appspec.yml + run: | + # Ensure appspec.yml is included in the zip + cp appspec.yml ./boomerang/ + cp -r ./boomerang/build/libs ./boomerang/ # Copy libs folder + cp -r ./scripts ./boomerang/ # Copy scripts folder + chmod +x ./boomerang/scripts/*.sh # Grant execute permissions to all .sh files + cd ./boomerang + zip -r ../application.zip . + cd .. + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ env.REGION }} + + - name: Upload to S3 + run: aws s3 cp application.zip s3://$S3_BUCKET_NAME/application.zip + + - name: List objects in S3 bucket + run: aws s3 ls s3://$S3_BUCKET_NAME/ # List objects in the S3 bucket + + - name: Deploy with CodeDeploy + run: | + aws deploy create-deployment \ + --application-name $APPLICATION_NAME \ + --deployment-config-name CodeDeployDefault.AllAtOnce \ + --deployment-group-name $DEPLOYMENT_GROUP_NAME \ + --file-exists-behavior OVERWRITE \ + --s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=application.zip \ + --region $REGION diff --git a/README.md b/README.md index 3be489f9..8b137891 100644 --- a/README.md +++ b/README.md @@ -1,77 +1 @@ -## 5주차 리뷰 받고 싶은 부분 - - -### 5주차에 작업 내용 -- [x] 카카오 로그인 -- [x] 커뮤니티의 보드 CRUD 작업 -*** -### 6주차에 작업할 내용 -- 커뮤니티의 댓글 기능 합치기 -- 커뮤니티의 좋아요 기능 합치기 - - -- 보증금 돌려받기 가이드라인의 유저상황조사 기능 구현 (문성민) -- 보증금 돌려받기 가이드라인의 유저별 진행도 기능 구현 (진서현) -- 에러시 로그를 찍는 기능 (정재빈) - -*** -### 궁금한 점 -#### 질문 1. 도메인객체는 어디 계층에서까지 다룰 수 있을지 궁금합니다. - -상황 1.`요청 객체 - 도메인 - 응답 객체` 만 사용하는 상황입니다. -현재는 컨트롤러에서 도메인을 응답객체로 만들고 있는데,도메인 객체를 컨트롤러에서 다뤄도 될지 궁금합니다. 이런 상황에서는 보통 응답객체를 어디서 만드나요? - - ->[컨트롤러 코드] ->```java -> @GetMapping("/{board_id}") -> public ResponseEntity getBoardById(@PathVariable(name = "board_id") Long boardId) { -> Board board = boardService.getBoardById(boardId); -> -> return ResponseEntity.status(HttpStatus.OK) -> .body(new BoardResponseDto(board)); -> } ->``` -> -> ->[서비스 코드] ->```java -> // ID로 게시물 가져오기 -> public Board getBoardById(Long id) { -> return boardRepository.findById(id) -> .orElseThrow(() -> new BusinessException(ErrorCode.BOARD_NOT_FOUND_ERROR)); -> } ->``` - - -### 질문 2. 연관관계에서 즉시로딩과 지연로딩 선택 기준 -Board 테이블을 조회할때마다, 항상 작성자의 정보가 필요한 상황이라면, -어떻게 연관관계 조회 전략을 선택하는 것이 좋을지 궁금합니다. - -#### 방법 1.`FetchType.LAZY` 선택하고 `get메서드`로 조회 - -#### 방법 2. `FetchType.EAGER`를 설정, 지연로딩을 선택하지 않음 - -#### 방법 3. 작성자의 이메일을 필드로 저장 후 -- 작성자의 이메일만 필요한 상황, 따라서 이메일을 필드로 저장 후, 유저의 이메일이 변경될 떄, 게시글의 작성자 이메일 필드를 바꿔주는 기능을 추가함. -- 이때 작성자의 이메일은 자주 변경되지 않을 것으로 가정했습니다. - - ->[엔티티 코드] -> ```java -> -> @Table(name = "board") -> public class Board { -> -> @Id -> @GeneratedValue(strategy = GenerationType.IDENTITY) -> private Long id; -> -> @ManyToOne(fetch = FetchType.EAGER) -> @JoinColumn(name = "member_id", nullable = false) -> private Member member; -> } ->``` - - diff --git a/appspec.yml b/appspec.yml new file mode 100644 index 00000000..deed8d16 --- /dev/null +++ b/appspec.yml @@ -0,0 +1,20 @@ +version: 0.0 +os: linux +files: + - source: libs/ + destination: /home/ubuntu/my-spring-app/libs/ + - source: scripts/ + destination: /home/ubuntu/my-spring-app/scripts/ + +permissions: + - object: /home/ubuntu/my-spring-app + pattern: "**" + owner: ubuntu + group: ubuntu + mode: 755 # 실행 권한 부여 + +hooks: + ApplicationStart: + - location: scripts/start_server.sh + timeout: 60 + runas: ubuntu diff --git a/boomerang/src/main/java/boomerang/board/dto/BoardBestListRequestDto.java b/boomerang/src/main/java/boomerang/board/dto/BoardBestListRequestDto.java index 67d1dc13..063e81b4 100644 --- a/boomerang/src/main/java/boomerang/board/dto/BoardBestListRequestDto.java +++ b/boomerang/src/main/java/boomerang/board/dto/BoardBestListRequestDto.java @@ -16,4 +16,5 @@ public class BoardBestListRequestDto { private int size = 10; private BoardType board_type; private int content_length; + } diff --git a/boomerang/src/main/java/boomerang/board/service/BoardService.java b/boomerang/src/main/java/boomerang/board/service/BoardService.java index 8ee482a9..5806eebd 100644 --- a/boomerang/src/main/java/boomerang/board/service/BoardService.java +++ b/boomerang/src/main/java/boomerang/board/service/BoardService.java @@ -19,7 +19,6 @@ import java.time.LocalDate; import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; @Service public class BoardService { diff --git a/boomerang/src/main/java/boomerang/global/response/ErrorCode.java b/boomerang/src/main/java/boomerang/global/response/ErrorCode.java index 49fcc0b3..d461d1a5 100644 --- a/boomerang/src/main/java/boomerang/global/response/ErrorCode.java +++ b/boomerang/src/main/java/boomerang/global/response/ErrorCode.java @@ -10,9 +10,9 @@ public enum ErrorCode { ACCESS_TOKEN_NOT_EXISTS_ERROR(HttpStatus.BAD_REQUEST, "EG002", "Access Token Not Exists Error"), JWT_ERROR(HttpStatus.UNAUTHORIZED, "EG003", "JWT token is not valid"), BAD_REQUEST(HttpStatus.BAD_REQUEST, "EG004", "잘못된 요청입니다."), - COOKIES_ERROR(HttpStatus.UNAUTHORIZED, "EG005", "닉네임 쿠키 생성중 오류가 발생했습니다."), - KAKAO_ERROR(HttpStatus.UNAUTHORIZED, "EG006", "카카오 로그인 중 에러가 발생했습니다."), - FILE_ERROR(HttpStatus.UNAUTHORIZED, "EG007", "욕설 파일 읽어오는 과정 중 에러가 발생했습니다."), + COOKIES_ERROR(HttpStatus.BAD_REQUEST, "EG005", "닉네임 쿠키 생성중 오류가 발생했습니다."), + KAKAO_ERROR(HttpStatus.BAD_REQUEST, "EG006", "카카오 로그인 중 에러가 발생했습니다."), + FILE_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "EG007", "욕설 파일 읽어오는 과정 중 에러가 발생했습니다."), // Template TEMPLATE_NOT_FOUND_ERROR(HttpStatus.BAD_REQUEST, "EM001", "Template Not Found Error"), diff --git a/scripts/start_server.sh b/scripts/start_server.sh new file mode 100644 index 00000000..0b80459e --- /dev/null +++ b/scripts/start_server.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# JAR 파일 경로 +JAR_PATH="/home/ubuntu/my-spring-app/libs/boomerang-0.0.1-SNAPSHOT.jar" + +# 애플리케이션 종료 (기존 프로세스 종료) +pkill -f $JAR_PATH + +# 애플리케이션 실행 +nohup java -jar $JAR_PATH > /home/ubuntu/my-spring-app/log.txt 2>&1 &