Skip to content

Commit 10e064b

Browse files
lkw9241seungwookc97MEOHINseok6555GerHerMo
authored
[feat] dev에서 main으로 push#98 (#103)
* chore : 코드래빗 자동화 설정1 * feat : 글로벌 클래스 start kit 설정1 * feat : 8080 접속시 스웨거로 리다이렉트 하도록 설정 * chore : ISSUE_TEMPLATE 삭제 * chore : 코드래빗 자동화 설정2 * Create ISSUE_TEMPLATE.md (#3) * [fix] issue 템플릿에 YAML front matter 추가 (#10) * [feat] User 도메인 추가#7 (#11) * feat: User 엔티티추가 * feat: User DTO 추가 * feat: UserRepository 추가 * feat: Wishlist 엔티티 추가 * feat: WishlistStatus 추가 - soft delete 관리를 위함 * feat: WishlistRepository 추가 * chore: .gitignore에 db 파일 추가 * feat: Wishlist 요청/응답 DTO 추가 * chore : 코드래빗 한국어 설정 * refactor: User 엔티티 필드 수정 * feat: User 회원등급 enum 추가 * refactor: User role 필드와 @Builder.Default를 추가 * feat: UserService 추가 * [feat] cocktail엔티티, 리포지토리, DTO 추가 #9 * {feat} : domain * {fix}:Cocktail-Wishlist relation * {fix}: add profileImgUrl * [feat] Security Config설정, CustomAuthenticationFilter 설정#1 (#18) * chore : 코드래빗 한국어 설정 * feat : OAuth&시큐리티 의존성 추가 및 환경변수 등록 * feat : Security Config설정, CustomAuthenticationFilter 설정1 * feat : secure설정 로컬에서 사용x, prod yml생성하여 true적용 되도록 전환. 로깅 dev.yml로 이동 * [feat] 프로필 조회 기능 구현 #16 (#20) * feat: User엔티티에 JPA Auditing 적용 * feat: 프로필 요청 DTO 추가 * feat: ABV 레벨 및 퍼센트 라벨링 기능 추가 * feat: 닉네임 중복 확인 메서드 추가 * feat: 프로필 조회 로직 추가 * fix: 불필요한 필드 삭제 * feat: 로그인한 사용자 프로필 조회 API 추가 * [feat] 프로필 수정 기능 구현 #21 (#22) * feat: User엔티티에 JPA Auditing 적용 * feat: 프로필 요청 DTO 추가 * feat: ABV 레벨 및 퍼센트 라벨링 기능 추가 * feat: 닉네임 중복 확인 메서드 추가 * feat: 프로필 조회 로직 추가 * fix: 불필요한 필드 삭제 * feat: 로그인한 사용자 프로필 조회 API 추가 * feat: 사용자 프로필 수정 DTO 추가 * feat: 사용자 프로필 수정 로직 추가 * feat: 사용자 프로필 수정 API 추가 * fix: springdoc-openapi 버전 호환성 문제 해결 * feat : OAuth 핸들러 구현 및 관련 유저 서비스 추가1 * feat : Security Config 설정 및 OAuth 구현#2 * refactor : 불필요한 코드 삭제 및 구조 개선 * feat : Redis의존성 추가 및 리프레시 토큰 엔티티, 레포지터리 생성 * feat : 리프레시 토큰 핵심 서비스 작성 * refactor : 리프레시 토큰 패키지 변경 및 코드 정리 * [feat] 나만의 Bar(킵) 목록 조회 기능 구현 #23 (#29) * refactor: Wishlist 엔티티를 MyBar 엔티티로 리팩토링 및 개선 - Wishlist 도메인을 MyBar 도메인으로 명칭 변경 - `createdAt` 필드에 `@CreatedDate` 어노테이션 적용하여 생성 시간 자동화 - Soft Delete 구현을 위해 `deletedAt` 필드 추가 - `WishlistStatus` enum을 `KeepStatus` enum으로 변경 * refactor: WishlistStatus enum을 KeepStatus enum으로 변경 - 도메인 명칭 변경에 맞춰 WishlistStatus enum 클래스를 KeepStatus로 변경 - enum 패키지 위치를 'wishlist'에서 'mybar'으로 이동 * refactor: 불필요한 Dto 삭제 * feat: 마이바 목록 조회 DTO 추가 - 마이바 목록 조회 시 사용될 MyBarListResponseDto 클래스 추가 - 페이징 처리를 위한 nextCursor 필드 추가 * refactor: WishlistResponseDto를 MyBarItemResponseDto로 리팩토링 - WishlistResponseDto 클래스를 MyBarItemResponseDto로 명칭 변경 - DTO가 사용자(User) 정보 대신 킵한 칵테일(Cocktail) 정보를 직접 포함하도록 수정 * refactor: WishlistRepository를 MyBarRepository로 리팩토링 및 쿼리 메소드 추가 - WishlistRepository 인터페이스를 MyBarRepository로 명칭 변경 - '나만의 바' 기능의 데이터 접근을 위해 쿼리 메소드 2개 추가 - `findByUserIdAndStatusOrderByIdDesc`: 특정 사용자의 킵 목록을 페이징하여 조회 - `countByUserIdAndStatus`: 특정 사용자의 활성 킵 개수를 카운트 * refactor: API 응답을 커서 기반 페이징 방식에서 오프셋 기반 페이징 방식으로 변경 * feat: 마이바(MyBar) 목록 조회 서비스 로직 구현 * feat: 마이바(MyBar) 목록 조회 API 구현 * fix typo * feat: 리프레시 토큰 기반 인증 시스템 구현 * [feat] 칵테일 조회 및 검색 기능 구현 (#32) * {feat} : domain * {fix}:Cocktail-Wishlist relation * fix : enums * fix : bug * feat : 조회기능, 조init data * fix : naming * feat : cocktailSearch * fix :bug * feat: 리프레시 토큰 기반 인증 시스템 구현 * [feat] 나만의 bar(킵) 추가/재추가 기능 구현 #30 (#33) * feat: 마이바(MyBar) 엔티티에 keptAt 필드 추가 - `keptAt`은 칵테일이 마지막으로 킵된 시점을 저장하며, 목록 정렬 기준으로 활용될 예정 기존의 `createdAt` 필드는 엔티티가 생성된 시점만을 나타내므로, '킵' 해제 후 다시 '킵'하는 경우 목록의 최상단에 재배치되게 하려면 최신 '킵' 시간을 추적할 수 있는 별도의 필드가 필요했습니다. 이를 위해 `keptAt` 필드를 추가하여 최신 킵 시간을 관리하고, 이를 목록 정렬의 기준으로 사용하도록 개선했습니다. * feat: MyBarItemResponseDto에 keptAt 필드 추가 * refactor: MyBarRepository에 킵 관련 쿼리 메소드 추가 및 정렬 기준 변경 - `findByUserIdAndStatusOrderByIdDesc` 쿼리 메소드의 정렬 기준을 `KeptAt`으로 변경 - 최근에 킵한 칵테일이 목록 상단에 오도록 `keptAt`을 기준으로 내림차순 정렬하고, 동일한 시간일 경우 `id`로 보조 정렬 - `countByUserIdAndStatus` 쿼리 메소드의 매개변수명을 `user_Id`로 통일 - 칵테일 킵 상태 확인(`existsByUser_IdAndCocktail_IdAndStatus`)을 위한 쿼리 메소드 추가 - 복원/재킵(`findByUser_IdAndCocktail_Id`)을 위한 쿼리 메소드 추가 * feat: 마이바(MyBar) '킵' 기능 추가 및 목록 조회 로직 개선 - `keep` 메서드를 추가하여 칵테일을 킵하거나 재킵하는 로직 구현 - 기존 목록 조회 메서드(`getMyBar`)의 쿼리 정렬 기준을 `KeptAt`으로 변경 - `UserRepository`와 `CocktailRepository`를 추가하여 엔티티 참조에 활용 * feat: 마이바(MyBar) 칵테일 킵(Keep) API 추가 - `POST /me/bar/{cocktailId}/keep` 엔드포인트 추가 - URL `@PathVariable`로 칵테일 ID를 받고, `@AuthenticationPrincipal`로 사용자 ID를 획득 - `MyBarService`의 `keep` 메서드를 호출하여 킵 기능 처리 - 성공 시 HTTP 201 상태 코드와 "kept" 메시지 반환 * refactor: MyBarRepository 쿼리 메소드의 필드명 수정 -`@ManyToOne` 관계에서 연관 엔티티의 ID 필드를 직접 참조할 때의 **JPA 규칙**을 따르기 위함입니다. 이전 코드에서는 `Cocktail` 엔티티의 PK 필드명(`cocktailId`)을 생략했으나, 명확한 필드 경로(`Cocktail_CocktailId`)를 명시하여 코드의 가독성과 일관성을 높였습니다. * [feat] 나만의 bar soft delete 기능 구현 #31 (#36) * feat: MyBarRepository에 소프트 삭제 기능 추가 - MyBar 엔티티를 삭제 시 실제 DB에서 삭제하는 대신, status를 'DELETED'로 변경하는 소프트 삭제 로직을 추가 * feat: 마이바(MyBar) 킵 해제 기능 추가 (소프트 삭제) * feat: MyBarController에 칵테일 킵(Keep) 해제 API 추가 * feat : 기존 액세스 토큰 대신 리프레시 토큰 같이 발급 * feat: post 도메인 추가 * feat : jwt토큰에 닉네임 파라미터 추가 및 코드 리팩토링 * refactor: AbvLevel Enum의 L1 등급 기준 및 로직 변경 (#38) - `AbvLevel` Enum의 L1 등급에 대한 최소(min) 기준값을 0에서 5로 변경 * feat: 게시글 다건 조회, 작성 구현 * feat: 게시글 단건 조회 구현 * feat : 레디스 로컬 실행을 위한 docker-compose.yml 작성 * [refactor] 나만의 bar 페이지네이션을 커서 기반으로 리팩토링 #49 (#51) * refactor: MyBar 목록 API 페이징 방식을 오프셋에서 커서 기반으로 변경 - 응답 DTO인 `MyBarListResponseDto`에서 `nextPage` 필드를 제거하고, 대신 `nextCursor` 필드를 추가 * feat: MyBarRepository에 커서 기반 페이징 메서드 추가 - `MyBarRepository`에 커서 기반 페이징을 위한 새로운 쿼리 메서드 `findSliceByCursor`를 추가 * refactor: MyBarService에 커서 기반 페이징 로직 구현 및 적용 - MyBar 목록 조회 API의 페이징 방식을 기존의 오프셋(offset) 기반에서 커서(cursor) 기반으로 변경 - `getMyBar` 메서드의 파라미터를 `page`, `pageSize`에서 `cursor`, `limit`로 수정하여 커서 기반 페이징에 적합하게 변경 - `Cursor` 클래스를 새로 추가하여 커서의 인코딩/디코딩 로직을 구현 커서는 `epochMillis`와 `id`를 조합하여 Base64로 인코딩 - 첫 페이지 요청(`cursor`가 null 또는 빈 문자열)과 다음 페이지 요청(`cursor`가 존재)을 분리하여 처리하는 로직을 추가 * refactor: MyBarController의 목록 조회 API 페이징 방식 변경 - 마이바(MyBar) 목록을 조회하는 GET API의 페이징 방식을 오프셋(offset) 기반에서 커서(cursor) 기반으로 리팩토링 - 기존의 `@RequestParam`인 `page`와 `pageSize`를 `cursor`와 `limit`로 변경 - `cursor`는 `String` 타입으로, 다음 페이지를 식별하는 데 사용 * refactor: MyBarListResponseDto의 커서 필드를 분리하여 재구성 - `MyBarListResponseDto`의 `nextCursor` 필드를 제거하고, `nextKeptAt`과 `nextId` 두 개의 필드로 분리 - 기존의 Base64로 인코딩된 문자열 커서 대신, 서버 내부에서 직접 사용할 수 있는 `LocalDateTime`과 `Long` 타입의 필드를 제공 * refactor: MyBarService의 커서 기반 페이징 로직 재구성 (간소화) - `MyBarService`의 `getMyBar` 메서드에서 커서 기반 페이징 로직을 간소화 - 기존의 Base64 인코딩/디코딩 방식을 제거하고, 커서 값을 `lastKeptAt` (LocalDateTime)과 `lastId` (Long) 두 개의 파라미터로 직접 받도록 변경 * refactor: MyBar 목록 조회 API 파라미터를 커서 값으로 직접 변경 - MyBar 목록 조회 API의 `@GetMapping` 메서드 파라미터를 커서 기반 페이징에 맞게 변경 - 기존의 단일 `cursor` 문자열 필드 대신, `lastKeptAt` (LocalDateTime)과 `lastId` (Long)를 직접 받도록 수정 - `lastKeptAt` 파라미터에 `@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)`을 적용하여 ISO 8601 형식의 시간 데이터를 자동으로 변환 * feat: 게시글 수정 구현 * feat: 게시글 삭제 구현 * feat: 무한스크롤 페이징 구현 * [refactor] 프로필 수정 메서드를 Patch로 변경 #53 (#57) * refactor: 프로필 수정 DTO에서 이메일 필드 제거 * refactor: ProfileService에서 이메일 관련 로직 제거 - `ProfileService`의 `updateProfile` 메서드에서 이메일 관련 업데이트 로직을 삭제 - 이는 프로필 수정 DTO(ProfileUpdateRequestDto)에서 이메일 필드를 제거한 변경사항에 맞춘 후속 조치 * refactor: ProfileController API 엔드포인트 및 HTTP 메서드 변경 - `ProfileController`의 기본 API 엔드포인트를 `/me/profile`에서 `/api/me/profile`로 변경 - 프로필 수정에 사용되던 **`PUT` 메서드를 제거하고,** 부분 업데이트에 더 적합한 `PATCH` 메서드를 도입 * [feat] 내활동: 내가 쓴 글 조회 기능 구현 #58 (#68) * feat: 단일 히스토리 게시글 정보 DTO 추가 - HistoryPostItemDto: 게시글 목록 페이지에서 사용될 게시글의 핵심 정보(id, 제목, 이미지 URL, 좋아요/댓글 수)를 담는 DTO - from() 정적 팩토리 메서드: Post 엔티티를 HistoryPostItemDto로 변환하는 로직 구현 * feat: 히스토리 목록 페이지네이션을 위한 DTO 추가 - HistoryPostListDto: 히스토리 목록, 다음 페이지 유무, 다음 페이지 커서(nextCreatedAt, nextId) 정보를 담는 DTO - HistoryPostItemDto: 단일 히스토리 항목 정보를 담는 DTO * feat: 마이페이지 게시글 목록 조회 기능 추가 (커서 기반 페이지네이션) - `HistoryRepository`에 사용자 게시글 목록 조회를 위한 쿼리 메서드 2개 추가 - `findMyPostsFirstPage`: 초기 페이지 게시글을 조회 - `findMyPostsAfter`: 다음 페이지 게시글을 커서를 기반으로 조회하여 성능 개선 * feat: 마이페이지 게시글 목록 조회 서비스 로직 구현 - `HistoryService.getMyPosts()`: 사용자 ID, 커서(마지막 생성 시간, ID), 조회 개수(limit)를 인자로 받아 게시글 목록을 반환하는 메서드 추가 - `HistoryRepository`를 사용하여 커서 기반 페이지네이션을 처리 * feat: 마이페이지 게시글 목록 조회 API 구현 * feat: comment 도메인 생성 * [feat] 칵테일 컨트롤러 단건조회 구현 * {feat} : domain * {fix}:Cocktail-Wishlist relation * fix : enums * fix : bug * feat : 조회기능, 조init data * feat : cocktailSearch * feat : search * feat: get cocktailTest * feat : controller * feat : terraform 설정 * feat: 댓글 작성 기능 구현 * feat: gemini yml add * feat: add chatbot entity * feat: add chat double DTO * feat: add gemini doubel DTO * feat: chatbot Repository * [feat] 알림 목록 조회 기능 구현 #70 (#74) * feat: 알림(Notification) 엔티티 구현 * feat: 단일 알림 항목 DTO 추가 * feat: 알림 목록 페이지네이션 DTO 추가 * feat: 알림 이동(클릭) 응답 DTO 추가 * feat: 알림(Notification) Repository에 조회 기능 추가 - `findMyNotificationsFirstPage`: 사용자 ID를 기반으로 알림 목록의 첫 페이지를 조회하는 쿼리 추가 - `findMyNotificationsAfter`: 커서(lastCreatedAt, lastId)를 사용하여 다음 페이지의 알림 목록을 효율적으로 조회하는 쿼리 추가 - `findByIdAndUserId`: 특정 사용자의 특정 알림을 안전하게 조회하는 메서드 추가 * eat: 알림 종류(NotificationType) Enum 추가 - `NotificationType`: 알림의 종류를 구분하는 열거형 * feat: 알림(Notification) 서비스 로직 구현 - `NotificationService.getNotifications()`: 사용자 ID를 기반으로 알림 목록을 커서 기반 페이지네이션으로 조회 - `NotificationService.markAsReadAndGetPostLink()`: 특정 알림을 읽음 처리하고, 연결된 게시글의 ID 및 API URL을 반환 - 알림이 존재하지 않거나 사용자 ID와 불일치할 경우 예외 처리 추가 * feat: 알림(Notification) 관련 API 엔드포인트 구현 * feat: add Gemini config on Global * feat: add Geminiservice * feat: add chatbot service * feat: add chatbot controller * feat: chatbot endpoint permitAll * feat: ignore add * fix: Delete .claude directory * [feat] 칵테일 검색/필터 컨트롤러 기능 구현#72 * {feat} : domain * {fix}:Cocktail-Wishlist relation * fix : enums * fix : bug * feat : 조회기능, 조init data * feat : cocktailSearch * feat: get cocktailTest * feat : controller * feat : cocktail controller * fix : Dto naming * fix: CocktailDetailResponseDto * feat: 댓글 다건 조회 기능 구현 * [feat] 내 활동: 내가 작성한 댓글 목록 조회 기능 구현 #78 (#85) * refactor: 컨트롤러 API 경로에 /api 접두사 추가 * refactor: History 패키지 및 클래스 명칭 변경 * feat: 마이페이지 댓글 히스토리 DTO 추가 * feat: 마이페이지 댓글 목록 페이지네이션 DTO 추가 * feat: 마이페이지 댓글 이동 응답 DTO 추가 * feat: 마이페이지 댓글 히스토리 Repository 구현 - `MyHistoryCommentRepository`에 사용자 댓글 조회 기능 추가 - `findMyCommentsFirstPage()`: 사용자 ID를 기반으로 댓글 목록의 첫 페이지를 조회 - `findMyCommentsAfter()`: 커서(lastCreatedAt, lastId)를 사용하여 다음 페이지의 댓글 목록을 효율적으로 조회 - `findByIdAndUserId()`: 특정 사용자의 특정 댓글을 조회하는 기능 추가 * refactor: MyHistoryService로 클래스명 및 패키지명 변경 * feat: 마이페이지 댓글 히스토리 기능 추가 - MyHistoryService에 사용자가 작성한 댓글 목록을 조회하는 getMyComments() 메서드를 추가 - 커서 기반 페이지네이션을 적용 - 댓글을 클릭하면 해당 댓글이 속한 게시글로 이동할 수 있도록 getPostLinkFromMyComment() 메서드를 구현 - 삭제된 게시글에 대한 예외 처리를 추가 * refactor: MyHistoryController로 클래스명 및 패키지 변경 * feat: 마이페이지 댓글 히스토리 API 추가 * fix typo * feat: 댓글 단건 조회 기능 구현 * [feat] 내활동: 내가 쓴 글 목록에서 클릭시 해당 게시글로 이동 구현 #86 (#88) * feat: 마이페이지 게시글 이동 응답 DTO 추가 * eat: MyHistoryPostRepository에 게시글 조회 메서드 추가 - findByIdAndUserId(): 게시글 ID와 사용자 ID를 모두 사용하여 특정 게시글을 조회하는 메서드를 추가 * feat: 마이페이지 게시글 이동 서비스 로직 추가 - MyHistoryService에 getPostLinkFromMyPost() 메서드를 추가하여 특정 게시글로 이동하는 기능을 구현 * feat: 마이페이지 게시글 이동 API 추가 * feat: 댓글 수정 기능 구현 * feat : 무중단 배포 위한 yml 및 github flow 작성 * fix typo * fix typo.. * feat: 댓글 삭제 기능 구현 * feat: 댓글 삭제 기능 구현 * [feat] 칵테일 공유 기능 구현 * {feat} : domain * {fix}:Cocktail-Wishlist relation * fix : enums * fix : bug * feat : 조회기능, 조init data * feat : cocktailSearch * feat : controller * feat : cocktail controller * CocktailShareController * fix : bug * [refactor] Refresh Token 아키텍처 개선 * feat : terraform 설정 * feat : 무중단 배포 위한 yml 및 github flow 작성 * refactor: 리프레시 토큰 레디스 -> jpa 사용하도록 변경, redis는 OAuth 세션 저장시에만 사용 * fix : DATABSE_URL 환경변수 수정 * fix: 백엔드 배포환경 url 수정 * feat : mysql 드라이버 및 username, password 명시(yml) * {feat} : domain * {fix}:Cocktail-Wishlist relation * fix : enums * fix : bug * feat : 조회기능, 조init data * feat : cocktailSearch * feat : controller * merge to main --------- Co-authored-by: seungwookc97 <[email protected]> Co-authored-by: MEOHIN <[email protected]> Co-authored-by: meohin <[email protected]> Co-authored-by: SeokGeunHo <[email protected]> Co-authored-by: SeokGeunHo <[email protected]> Co-authored-by: GerHerMo <[email protected]> Co-authored-by: GerHerMo <[email protected]>
1 parent d0088b9 commit 10e064b

File tree

121 files changed

+5901
-1
lines changed

Some content is hidden

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

121 files changed

+5901
-1
lines changed

.github/ISSUE_TEMPLATE/basic.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
name: "📝 기본 이슈"
3+
about: "이슈 생성 시 기본으로 사용하는 템플릿"
4+
title: "[ISSUE] "
5+
labels: []
6+
assignees: ""
7+
---
8+
9+
### 이슈 태그
10+
[] 안에 'X' 문자를 넣어주세요
11+
12+
- [ ] 공백
13+
- [ ] feat
14+
- [ ] fix
15+
- [ ] style
16+
- [ ] refactor
17+
- [ ] test
18+
- [ ] chore
19+
20+
---
21+
22+
### 📖 개요
23+
<!-- 이슈의 목적과 배경을 간단히 적어주세요. -->
24+
25+
---
26+
27+
### ⚒️ 작업 내용
28+
- [X] 체크 박스 내용 (체크됨)
29+
- [ ] 체크 박스 내용 (체크 안됨)
30+
- 그냥 목록 내용
31+
32+
---
33+
34+
### ✅ 수용 조건(완료 기준)
35+
- [ ] 무엇을 보면 완료로 볼 수 있는지 명확히 적기
36+
37+
### 🧩 참고 자료(옵션)
38+
- 링크 / 스크린샷 / 로그 등

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## 📢 기능 설명
2+
3+
필요시 실행결과 스크린샷 첨부
4+
<br>
5+
6+
## 연결된 issue
7+
8+
연결된 issue를 자동으로 닫기 위해 아래 {이슈넘버}를 입력해주세요. <br>
9+
close #{이슈넘버}
10+
<br>
11+
<br>
12+
13+
## 🩷 Approve 하기 전 확인해주세요!
14+
15+
- [ ] 리뷰어가 확인해줬으면 하는 사항 적어주세요.
16+
- [ ]
17+
18+
<br>
19+
20+
## ✅ 체크리스트
21+
22+
- [ ] PR 제목 규칙 잘 지켰는가?
23+
- [ ] 추가/수정사항을 설명하였는가?
24+
- [ ] 이슈넘버를 적었는가?
25+
- [ ] Approve 하기 전 확인 사항 체크했는가?

.github/workflows/autoIssue.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# 워크플로우 이름
2+
name: 이슈 자동화
3+
4+
# 실행 조건: 이슈가 열렸을 때
5+
on:
6+
issues:
7+
types: [ opened ]
8+
9+
# 실행할 작업
10+
jobs:
11+
automate-issue:
12+
runs-on: ubuntu-latest
13+
permissions:
14+
issues: write
15+
contents: read
16+
17+
steps:
18+
# 이슈 제목에 따라 Label 자동 할당 (예시)
19+
- name: design 라벨 할당
20+
if: contains(github.event.issue.title, 'design')
21+
uses: actions-ecosystem/action-add-labels@v1
22+
with:
23+
labels: design
24+
25+
- name: feat 라벨 할당
26+
if: contains(github.event.issue.title, 'feat')
27+
uses: actions-ecosystem/action-add-labels@v1
28+
with:
29+
labels: feat
30+
31+
- name: fix 라벨 할당
32+
if: contains(github.event.issue.title, 'fix')
33+
uses: actions-ecosystem/action-add-labels@v1
34+
with:
35+
labels: fix
36+
37+
- name: refactor 라벨 할당
38+
if: contains(github.event.issue.title, 'refactor')
39+
uses: actions-ecosystem/action-add-labels@v1
40+
with:
41+
labels: refactor
42+
43+
- name: chore 라벨 할당
44+
if: contains(github.event.issue.title, 'chore')
45+
uses: actions-ecosystem/action-add-labels@v1
46+
with:
47+
labels: chore
48+
49+
50+
# GitHub 프로젝트의 'Backlog' 컬럼에 자동 추가
51+
- name : Github 프로젝트에 추가
52+
uses: jinhokim98/project-flow-add-issue-to-project@v1
53+
with:
54+
github_token: ${{ secrets.PROJECT_ACCESS_TOKEN }}
55+
project_owner: prgrms-web-devcourse-final-project
56+
project_number: 145
57+
target_column: 'Backlog'

.github/workflows/autoPR.yml

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# 워크플로우 이름
2+
name: PR 자동화
3+
4+
# 실행 조건: main, dev/** 브랜치로 PR이 열렸을 때
5+
on:
6+
pull_request:
7+
branches: [ main, dev, 'dev/**' ]
8+
types: [ opened ]
9+
10+
# 실행할 작업
11+
jobs:
12+
automate-pr:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
pull-requests: write
16+
issues: write
17+
contents: read
18+
19+
steps:
20+
# PR 작성자를 Assignee로 자동 할당
21+
- name: PR 작성자를 담당자로 할당
22+
uses: actions-ecosystem/action-add-assignees@v1
23+
with:
24+
github_token: ${{ secrets.PROJECT_ACCESS_TOKEN }}
25+
assignees: ${{ github.event.pull_request.user.login }}
26+
27+
28+
# PR 제목에 따라 Label 자동 할당 (예시)
29+
# - name: 제목에 'feat'가 있으면 'feature' 라벨 추가
30+
# if: contains(github.event.pull_request.title, 'feat')
31+
# uses: actions-ecosystem/action-add-labels@v1
32+
# with:
33+
# labels: feature
34+
35+
36+
# PR 제목에 따라 Label 자동 할당
37+
- name: design 라벨 할당
38+
if: contains(github.event.pull_request.title, 'design')
39+
uses: actions-ecosystem/action-add-labels@v1
40+
with:
41+
labels: design
42+
43+
- name: feat 라벨 할당
44+
if: contains(github.event.pull_request.title, 'feat')
45+
uses: actions-ecosystem/action-add-labels@v1
46+
with:
47+
labels: feat
48+
49+
- name: fix 라벨 할당
50+
if: contains(github.event.pull_request.title, 'fix')
51+
uses: actions-ecosystem/action-add-labels@v1
52+
with:
53+
labels: fix
54+
55+
- name: refactor 라벨 할당
56+
if: contains(github.event.pull_request.title, 'refactor')
57+
uses: actions-ecosystem/action-add-labels@v1
58+
with:
59+
labels: refactor
60+
61+
- name: chore 라벨 할당
62+
if: contains(github.event.pull_request.title, 'chore')
63+
uses: actions-ecosystem/action-add-labels@v1
64+
with:
65+
labels: chore
66+
67+
68+
# '연습용 프로젝트'에 등록
69+
- name: GitHub 프로젝트에 추가
70+
uses: actions/[email protected]
71+
with:
72+
project-url: "https://github.com/orgs/prgrms-web-devcourse-final-project/projects/145"
73+
github-token: ${{ secrets.PROJECT_ACCESS_TOKEN }}

.github/workflows/deploy.yml

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
name: deploy
2+
3+
# =========================
4+
# 전역 환경변수
5+
# =========================
6+
env:
7+
IMAGE_REPOSITORY: backend # GHCR 이미지 리포지토리명(소유자 포함 X)
8+
CONTAINER_1_NAME: backend
9+
EC2_INSTANCE_TAG_NAME: team2-ec2-1 # 배포 대상 EC2 Name 태그
10+
DOCKER_NETWORK: common # 도커 네트워크
11+
BACKEND_DIR: . # Dockerfile 위치
12+
13+
14+
on:
15+
push:
16+
paths:
17+
- ".github/workflows/**"
18+
- "src/**"
19+
- "build.gradle.kts"
20+
- "settings.gradle.kts"
21+
- "Dockerfile"
22+
- "terraform/main.tf"
23+
branches:
24+
- main
25+
26+
# 권한 최소화/명시화
27+
permissions:
28+
contents: write # 태그/릴리즈
29+
packages: write # GHCR 푸시
30+
31+
# 기본 셸
32+
defaults:
33+
run:
34+
shell: bash
35+
36+
jobs:
37+
# ---------------------------------------------------------
38+
# 1) 태그/릴리즈 생성
39+
# ---------------------------------------------------------
40+
makeTagAndRelease:
41+
runs-on: ubuntu-latest
42+
outputs:
43+
tag_name: ${{ steps.create_tag.outputs.new_tag }} # 이후 잡에서 사용할 태그명
44+
steps:
45+
- uses: actions/checkout@v4
46+
47+
# 버전 태그 자동 생성 (vX.Y.Z)
48+
- name: Create Tag
49+
id: create_tag
50+
uses: mathieudutour/[email protected]
51+
with:
52+
github_token: ${{ secrets.GIT_TOKEN }}
53+
54+
# 릴리즈 생성
55+
- name: Create Release
56+
id: create_release
57+
uses: actions/create-release@v1
58+
env:
59+
GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }}
60+
with:
61+
tag_name: ${{ steps.create_tag.outputs.new_tag }}
62+
release_name: Release ${{ steps.create_tag.outputs.new_tag }}
63+
body: ${{ steps.create_tag.outputs.changelog }}
64+
draft: false
65+
prerelease: false
66+
67+
# ---------------------------------------------------------
68+
# 2) 도커 이미지 빌드/푸시 (캐시 최대 활용)
69+
# ---------------------------------------------------------
70+
buildImageAndPush:
71+
name: 도커 이미지 빌드와 푸시
72+
needs: makeTagAndRelease
73+
runs-on: ubuntu-latest
74+
steps:
75+
- uses: actions/checkout@v4
76+
77+
# 빌드 컨텍스트에 .env 생성 (비어있어도 실패하지 않게)
78+
- name: .env 파일 생성
79+
env:
80+
DOT_ENV: ${{ secrets.DOT_ENV }}
81+
run: |
82+
# .env가 없으면 빌드 캐시가 매번 깨질 수 있으므로 항상 생성
83+
mkdir -p "${{ env.BACKEND_DIR }}"
84+
printf "%s" "${DOT_ENV}" > "${{ env.BACKEND_DIR }}/.env"
85+
86+
- name: Docker Buildx 설치
87+
uses: docker/setup-buildx-action@v3
88+
89+
# GHCR 로그인
90+
- name: 레지스트리 로그인
91+
uses: docker/login-action@v3
92+
with:
93+
registry: ghcr.io
94+
username: ${{ github.actor }}
95+
password: ${{ secrets.GIT_TOKEN }}
96+
97+
# 저장소 소유자명을 소문자로 (GHCR 경로 표준화)
98+
- name: set lower case owner name
99+
run: |
100+
echo "OWNER_LC=${OWNER,,}" >> "${GITHUB_ENV}"
101+
env:
102+
OWNER: "${{ github.repository_owner }}"
103+
104+
# 캐시를 최대한 활용하여 빌드 → 버전태그 및 latest 동시 푸시
105+
- name: 빌드 앤 푸시
106+
uses: docker/build-push-action@v6
107+
with:
108+
context: ${{ env.BACKEND_DIR }}
109+
push: true
110+
cache-from: type=gha
111+
cache-to: type=gha,mode=max
112+
tags: |
113+
ghcr.io/${{ env.OWNER_LC }}/${{ env.IMAGE_REPOSITORY }}:${{ needs.makeTagAndRelease.outputs.tag_name }}
114+
ghcr.io/${{ env.OWNER_LC }}/${{ env.IMAGE_REPOSITORY }}:latest
115+
116+
# ---------------------------------------------------------
117+
# 3) 배포
118+
# ---------------------------------------------------------
119+
deploy:
120+
name: 배포
121+
runs-on: ubuntu-latest
122+
needs: [makeTagAndRelease, buildImageAndPush]
123+
steps:
124+
# AWS 자격 구성
125+
- uses: aws-actions/configure-aws-credentials@v4
126+
with:
127+
aws-region: ${{ secrets.AWS_REGION }}
128+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
129+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
130+
131+
# Name 태그로 EC2 인스턴스 조회 (없으면 실패)
132+
- name: 인스턴스 ID 가져오기
133+
id: get_instance_id
134+
run: |
135+
INSTANCE_ID=$(aws ec2 describe-instances \
136+
--filters "Name=tag:Name,Values=${{ env.EC2_INSTANCE_TAG_NAME }}" "Name=instance-state-name,Values=running" \
137+
--query "Reservations[].Instances[].InstanceId" --output text)
138+
[[ -n "${INSTANCE_ID}" && "${INSTANCE_ID}" != "None" ]] || { echo "No running instance found"; exit 1; }
139+
echo "INSTANCE_ID=${INSTANCE_ID}" >> "${GITHUB_ENV}"
140+
141+
# 원격(SSM)으로 배포 수행
142+
- name: AWS SSM Send-Command
143+
uses: peterkimzz/aws-ssm-send-command@master
144+
with:
145+
aws-region: ${{ secrets.AWS_REGION }}
146+
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
147+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
148+
instance-ids: ${{ env.INSTANCE_ID }}
149+
working-directory: /
150+
comment: Deploy
151+
command: |
152+
set -Eeuo pipefail
153+
154+
LOG="/tmp/ssm-$(date +%Y%m%d_%H%M%S).log"
155+
exec > >(awk '{ fflush(); print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }' | tee -a "$LOG")
156+
exec 2> >(awk '{ fflush(); print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }' | tee -a "$LOG" >&2)
157+
158+
source /etc/environment || true
159+
160+
OWNER_LC="${{ github.repository_owner }}"
161+
OWNER_LC="${OWNER_LC,,}"
162+
IMAGE_TAG='${{ needs.makeTagAndRelease.outputs.tag_name }}'
163+
IMAGE_REPOSITORY='${{ env.IMAGE_REPOSITORY }}'
164+
IMAGE="ghcr.io/${OWNER_LC}/${IMAGE_REPOSITORY}:${IMAGE_TAG}"
165+
CONTAINER_1_NAME="${{ env.CONTAINER_1_NAME }}"
166+
NET="${{ env.DOCKER_NETWORK }}"
167+
168+
docker pull $IMAGE
169+
docker stop $CONTAINER_1_NAME || true
170+
docker rm $CONTAINER_1_NAME || true
171+
docker run -d --restart unless-stopped --name $CONTAINER_1_NAME --network $NET $IMAGE
172+
{
173+
docker images --format '{{.Repository}}:{{.Tag}}' \
174+
| grep -F "ghcr.io/${OWNER_LC}/${IMAGE_REPOSITORY}:" \
175+
| grep -v -F ":${IMAGE_TAG}" \
176+
| grep -v -F ":latest" \
177+
| xargs -r docker rmi
178+
} || true

.gitignore

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,20 @@ out/
3838

3939
### Custom ###
4040
db_dev.mv.db
41-
db_dev.trace.db
41+
db_dev.trace.db
42+
43+
### Environment Variables ###
44+
.env
45+
46+
### Terraform ###
47+
.terraform
48+
.terraform.lock.hcl
49+
terraform.tfstate
50+
terraform.tfstate.backup
51+
.terraform.tfstate.lock.info
52+
terraform/secrets.tf
53+
54+
55+
### Claude AI ###
56+
CLAUDE.md
57+
.claude/

0 commit comments

Comments
 (0)