Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/#66 스케줄러 모듈 분리 #68

Merged
merged 19 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 57 additions & 6 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Checkout Repository
uses: actions/checkout@v2
- name: 리포지토리를 가져옵니다
uses: actions/checkout@v2
with:
fetch-depth: 2

- name: JDK 17을 설치합니다
uses: actions/setup-java@v4
Expand All @@ -32,8 +34,42 @@ jobs:
- name: Gradle 명령 실행을 위한 권한을 부여합니다
run: chmod +x gradlew

- name: Gradle build를 수행합니다
run: ./gradlew build
- name: 변경된 모듈을 체크한다.
id: check_changes
run: |
git fetch origin main
if git diff --name-only origin/main...HEAD | grep -q "^domain/"; then
echo "domain 모듈이 변경되었습니다."
echo "::set-output name=changes::domain_changed"
elif git diff --name-only origin/main...HEAD | grep -q "^app-api/"; then
echo "api 모듈이 변경되었습니다."
echo "::set-output name=changes::api_changed"
elif git diff --name-only origin/main...HEAD | grep -q "^app-scheduler/"; then
echo "scheduler 모듈이 변경되었습니다."
echo "::set-output name=changes::scheduler_changed"
else
echo "모듈에 변경사항이 없습니다."
fi

- name: 변경된 모듈을 build한다.
run: |
case "${{ steps.check_changes.outputs.changes }}" in
domain_changed)
echo "전체 모듈을 빌드합니다."
./gradlew build --parallel
;;
api_changed)
echo "api 모듈을 빌드합니다."
./gradlew :app-api:build
;;
scheduler_changed)
echo "scheduler 모듈을 빌드합니다."
./gradlew :app-scheduler:build
;;
*)
echo "모듈에 변경 사항이 없습니다."
;;
esac

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
Expand All @@ -46,11 +82,26 @@ jobs:

- name: 도커 이미지 build 후 push
uses: docker/build-push-action@v2
if: |
steps.check_changes.outputs.changes == 'domain_changed' ||
steps.check_changes.outputs.changes == 'api_changed'
with:
context: .
file: Dockerfile
file: app-api/Dockerfile
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/pct-backend:${{ github.sha }}
tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.API_IMAGE }}:${{ github.sha }}
platforms: linux/amd64

- name: 도커 이미지 build 후 push
uses: docker/build-push-action@v2
if: |
steps.check_changes.outputs.changes == 'domain_changed' ||
steps.check_changes.outputs.changes == 'scheduler_changed'
with:
context: .
file: app-scheduler/Dockerfile
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.SCHEDULER_IMAGE }}:${{ github.sha }}
platforms: linux/amd64

deploy-to-ec2:
Expand Down
48 changes: 43 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ jobs:

steps:
- name: 리포지토리를 가져옵니다
uses: actions/checkout@v4
uses: actions/checkout@v2
with:
fetch-depth: 2

- name: JDK 17을 설치합니다
uses: actions/setup-java@v4
Expand All @@ -33,19 +35,55 @@ jobs:
- name: Gradle 명령 실행을 위한 권한을 부여합니다
run: chmod +x gradlew

- name: 테스트 수행
run: ./gradlew test -i
- name: 변경된 모듈을 체크한다.
id: check_changes
run: |
git fetch origin main
if git diff --name-only origin/main...HEAD | grep -q "^domain/"; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if 분기를 하니 ci flow 가 복잡한 느낌이 조금 드네요.

모듈 별로 ci 파일을 분기하는건 어떠신가요?

branches 트리거 부분을 paths 로 대체하여 "domain/**" 이런식으로 작성하면 해당 모듈에 변경이 발생하면 ci 가 동작하더라구요

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

트리거 부분 예시입니다

on:
  push:
    paths:
      - "domain/**" ```
      

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 처음에 path 로 트리거를 하고 모듈 별로 ci를 따로 하려고 했는데
그러면 다음과 같은 문제가 생깁니다.

  1. 테스트 수행을 제외한 이외의 step이 동일한데, 중복이 발생한다.
  2. 테스트가 중복된다. (Domain모듈이 변경되는 경우, Domain을 의존하는 API, Scheduler가 같이 테스트 되어야하는데 path로 트리거를 하고 Domain 및 API 가 변경되면 Domain에서도 API를 테스트하고, API 모듈에서도 API를 테스트하게 됩니다)
  3. 테스트 결과를 모아서 볼 수가 없다.

echo "domain 모듈이 변경되었습니다."
echo "::set-output name=changes::domain_changed"
elif git diff --name-only origin/main...HEAD | grep -q "^app-api/"; then
echo "api 모듈이 변경되었습니다."
echo "::set-output name=changes::api_changed"
elif git diff --name-only origin/main...HEAD | grep -q "^app-scheduler/"; then
echo "scheduler 모듈이 변경되었습니다."
echo "::set-output name=changes::scheduler_changed"
else
echo "모듈에 변경사항이 없습니다."
fi

- name: 변경된 모듈을 테스트한다.
run: |
case "${{ steps.check_changes.outputs.changes }}" in
domain_changed)
echo "도메인 모듈 및 하위 모듈을 테스트합니다."
./gradlew test --parallel
;;
api_changed)
echo "api 모듈을 테스트합니다."
./gradlew :app-api:test -i
;;
scheduler_changed)
echo "scheduler 모듈을 테스트합니다."
./gradlew :app-scheduler:test -i
;;
*)
echo "모듈에 변경 사항이 없습니다."
;;
esac
echo "테스트 결과를 하나의 디렉토리에 복사합니다."
./gradlew collectTestResults

- name: 테스트 결과를 PR에 코멘트로 등록합니다
uses: EnricoMi/publish-unit-test-result-action@v2
if: github.event_name == 'pull_request'
with:
files: '**/build/test-results/test/TEST-*.xml'
files: '**/build/allTestResults/TEST-*.xml'

- name: 테스트 실패 시, 실패한 코드 라인에 Check 코멘트를 등록합니다
uses: mikepenz/action-junit-report@v3
with:
report_paths: '**/build/test-results/test/TEST-*.xml'
report_paths: '**/build/allTestResults/TEST-*.xml'
token: ${{ github.token }}

- name: build 실패 시 Slack으로 알립니다
Expand Down
42 changes: 42 additions & 0 deletions app-api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
2 changes: 1 addition & 1 deletion Dockerfile → app-api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM amazoncorretto:17-alpine

COPY build/libs/parking-0.0.1-SNAPSHOT.jar app.jar
COPY build/libs/app-api-0.0.1-SNAPSHOT.jar app.jar

CMD ["java", "-jar", "app.jar"]
23 changes: 23 additions & 0 deletions app-api/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
dependencies {
implementation project(':domain')

testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation 'org.junit.jupiter:junit-jupiter'

implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
implementation group: 'org.hibernate.orm', name: 'hibernate-spatial', version: '6.3.1.Final'

// 메일
implementation 'org.springframework.boot:spring-boot-starter-mail'

// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

// testcontainer
testImplementation "org.testcontainers:testcontainers:1.19.6"
testImplementation "org.testcontainers:junit-jupiter:1.19.6"
testImplementation "com.redis:testcontainers-redis:2.2.0"
testImplementation "org.testcontainers:mysql:1.19.6"

testImplementation(testFixtures(project(":domain")))
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
package com.example.parking;
package com.parkingcomestrue;

import jakarta.annotation.PostConstruct;
import java.util.TimeZone;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableJpaAuditing
@EnableScheduling
@SpringBootApplication
public class ParkingApplication {
public class ApiApplication {

@PostConstruct
public void started() {
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"));
}

public static void main(String[] args) {
SpringApplication.run(ParkingApplication.class, args);
SpringApplication.run(ApiApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.example.parking.auth.authcode.api;
package com.parkingcomestrue.parking.api.auth.authcode;

import com.example.parking.auth.AuthService;
import com.example.parking.auth.authcode.application.dto.AuthCodeCertificateRequest;
import com.example.parking.auth.authcode.application.dto.AuthCodeRequest;
import com.example.parking.auth.authcode.application.dto.AuthCodeResponse;
import com.parkingcomestrue.parking.application.auth.AuthService;
import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeCertificateRequest;
import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeRequest;
import com.parkingcomestrue.parking.application.auth.authcode.dto.AuthCodeResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.example.parking.api.favorite;
package com.parkingcomestrue.parking.api.favorite;

import com.example.parking.application.favorite.FavoriteService;
import com.example.parking.application.favorite.dto.FavoriteCreateRequest;
import com.example.parking.application.favorite.dto.FavoriteDeleteRequest;
import com.example.parking.config.argumentresolver.MemberAuth;
import com.parkingcomestrue.parking.application.favorite.FavoriteService;
import com.parkingcomestrue.parking.application.favorite.dto.FavoriteCreateRequest;
import com.parkingcomestrue.parking.application.favorite.dto.FavoriteDeleteRequest;
import com.parkingcomestrue.parking.config.argumentresolver.MemberAuth;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.example.parking.api.member;

import com.example.parking.application.member.MemberService;
import com.example.parking.application.member.dto.MemberLoginRequest;
import com.example.parking.application.member.dto.MemberSignupRequest;
import com.example.parking.application.member.dto.PasswordChangeRequest;
import com.example.parking.auth.AuthService;
import com.example.parking.config.argumentresolver.MemberAuth;
package com.parkingcomestrue.parking.api.member;

import com.parkingcomestrue.parking.application.auth.AuthService;
import com.parkingcomestrue.parking.application.member.MemberService;
import com.parkingcomestrue.parking.application.member.dto.MemberLoginRequest;
import com.parkingcomestrue.parking.application.member.dto.MemberSignupRequest;
import com.parkingcomestrue.parking.application.member.dto.PasswordChangeRequest;
import com.parkingcomestrue.parking.config.argumentresolver.MemberAuth;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package com.example.parking.api.parking;
package com.parkingcomestrue.parking.api.parking;

import com.example.parking.application.parking.ParkingService;
import com.example.parking.application.parking.dto.ParkingDetailInfoResponse;
import com.example.parking.application.parking.dto.ParkingLotsResponse;
import com.example.parking.application.parking.dto.ParkingQueryRequest;
import com.example.parking.application.parking.dto.ParkingSearchConditionRequest;
import com.example.parking.config.argumentresolver.MemberAuth;
import com.example.parking.config.argumentresolver.parking.ParkingQuery;
import com.example.parking.config.argumentresolver.parking.ParkingSearchCondition;
import com.parkingcomestrue.parking.application.parking.ParkingService;
import com.parkingcomestrue.parking.application.parking.dto.ParkingDetailInfoResponse;
import com.parkingcomestrue.parking.application.parking.dto.ParkingLotsResponse;
import com.parkingcomestrue.parking.application.parking.dto.ParkingQueryRequest;
import com.parkingcomestrue.parking.application.parking.dto.ParkingSearchConditionRequest;
import com.parkingcomestrue.parking.config.argumentresolver.MemberAuth;
import com.parkingcomestrue.parking.config.argumentresolver.parking.ParkingQuery;
import com.parkingcomestrue.parking.config.argumentresolver.parking.ParkingSearchCondition;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.example.parking.api.review;
package com.parkingcomestrue.parking.api.review;

import com.example.parking.application.review.ReviewService;
import com.example.parking.application.review.dto.ReviewCreateRequest;
import com.example.parking.config.argumentresolver.MemberAuth;
import com.parkingcomestrue.parking.application.review.ReviewService;
import com.parkingcomestrue.parking.application.review.dto.ReviewCreateRequest;
import com.parkingcomestrue.parking.config.argumentresolver.MemberAuth;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.example.parking.api.searchcondition;
package com.parkingcomestrue.parking.api.searchcondition;

import com.example.parking.application.searchcondition.SearchConditionService;
import com.example.parking.application.searchcondition.dto.SearchConditionDto;
import com.example.parking.config.argumentresolver.MemberAuth;
import com.parkingcomestrue.parking.application.searchcondition.SearchConditionService;
import com.parkingcomestrue.parking.application.searchcondition.dto.SearchConditionDto;
import com.parkingcomestrue.parking.config.argumentresolver.MemberAuth;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.example.parking.application;
package com.parkingcomestrue.parking.application;

import com.example.parking.domain.searchcondition.SearchConditionAvailable;
import com.example.parking.support.exception.ClientException;
import com.example.parking.support.exception.ExceptionInformation;
import com.parkingcomestrue.common.domain.searchcondition.SearchConditionAvailable;
import com.parkingcomestrue.parking.support.exception.ClientException;
import com.parkingcomestrue.parking.support.exception.ClientExceptionInformation;
import java.util.Arrays;
import java.util.List;
import org.springframework.stereotype.Component;
Expand All @@ -24,7 +24,7 @@ public <E extends Enum<E> & SearchConditionAvailable> E toEnum(Class<E> searchCo
return Arrays.stream(conditions)
.filter(condition -> description.startsWith(condition.getDescription()))
.findAny()
.orElseThrow(() -> new ClientException(ExceptionInformation.INVALID_DESCRIPTION));
.orElseThrow(() -> new ClientException(ClientExceptionInformation.INVALID_DESCRIPTION));
}

public <E extends Enum<E> & SearchConditionAvailable> List<String> getValues(
Expand Down
Loading
Loading