From 3df7b0ae93eaf08e87bf4198a208f31e5548d745 Mon Sep 17 00:00:00 2001 From: endorsement0912 Date: Wed, 13 Aug 2025 22:38:42 +0900 Subject: [PATCH 01/11] =?UTF-8?q?[EA3-212]=20chore:=20.gitignore=20?= =?UTF-8?q?=EA=B7=9C=EC=B9=99=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 810c7770..6b9f66de 100644 --- a/.gitignore +++ b/.gitignore @@ -85,7 +85,11 @@ replay_pid* # === Spring Boot 환경설정 파일 === application.properties -application-*.properties +application-local.properties +application-prod.properties +application-prod-aws.properties +application-prod-gcp.properties +*.env # === 기타 === HELP.md From 9840f08cf7017b4ab355243afe5aaeabc1000c5e Mon Sep 17 00:00:00 2001 From: endorsement0912 Date: Wed, 13 Aug 2025 22:45:11 +0900 Subject: [PATCH 02/11] =?UTF-8?q?[EA3-212]=20ci:=20main=20=EB=B8=8C?= =?UTF-8?q?=EB=9E=9C=EC=B9=98=20PR=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C=EC=9A=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci-pr.yml | 93 +++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 .github/workflows/ci-pr.yml diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml new file mode 100644 index 00000000..c20a2110 --- /dev/null +++ b/.github/workflows/ci-pr.yml @@ -0,0 +1,93 @@ +name: PR CI (main) + +on: + pull_request: + branches: [ "main" ] # main으로 향하는 PR만 검사 + types: [ opened, synchronize, reopened, ready_for_review ] # PR 열림/커밋추가/다시열기/드래프트해제 시 실행 + paths-ignore: + - '**.md' + - 'docs/**' + +jobs: + build-and-test: + runs-on: ubuntu-latest + timeout-minutes: 15 # CI가 너무 오래 걸릴 때 무한 대기 방지 (필요시 늘려도 됨) + strategy: + matrix: + dbmode: [ mysql, postgres ] # DB 의존 로직 호환성 점검을 위해 H2를 두 모드로 테스트 + fail-fast: false # 한 모드가 실패해도 나머지 모드는 계속 실행(진단에 유리) + + steps: + # 1) 코드 체크아웃 + - name: Checkout code + uses: actions/checkout@v4 + + # 2) JDK 설치 (프로젝트 toolchain=21과 일치) + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "21" + cache: gradle # Gradle 캐시 자동화( wrapper/caches ) + + # 3) gradlew 실행권한 부여 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + # 4) Gradle 래퍼 유효성 체크(선택이지만 문제 파악에 도움) + - name: Validate Gradle wrapper + run: ./gradlew --version + + # 5) 테스트 + - name: Run tests (H2 via ENV) + run: ./gradlew clean test --no-daemon --stacktrace --info + env: + # (스프링) test 프로필로 기동 — 실제 파일 없어도 ENV가 모든 값을 오버라이드 + SPRING_PROFILES_ACTIVE: test + + # (DB) H2 메모리 DB URL — dbmode 매트릭스 값에 따라 MySQL/Postgre 모드 전환 + SPRING_DATASOURCE_URL: ${{ matrix.dbmode == 'mysql' + && 'jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1;DATABASE_TO_LOWER=TRUE;DB_CLOSE_ON_EXIT=FALSE' + || 'jdbc:h2:mem:testdb;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DATABASE_TO_LOWER=TRUE;DB_CLOSE_ON_EXIT=FALSE' }} + SPRING_DATASOURCE_DRIVER_CLASS_NAME: org.h2.Driver + SPRING_DATASOURCE_USERNAME: sa + SPRING_DATASOURCE_PASSWORD: "" + + # (JPA) 테스트 중 스키마 자동 생성/삭제 — 외부 스키마 의존 제거 + SPRING_JPA_HIBERNATE_DDL_AUTO: create-drop + SPRING_SQL_INIT_MODE: never + + # 외부 리소스 자동설정 차단(네트워크 시도 방지) + SPRING_AUTOCONFIGURE_EXCLUDE: > + org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration, + org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration, + org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration, + org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration, + org.springframework.boot.autoconfigure.session.SessionAutoConfiguration, + org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration + + # 세션 저장소 비활성화 + SPRING_SESSION_STORE_TYPE: none + + # GCP Secret Manager 무력화 + SPRING_CLOUD_GCP_SECRET_MANAGER_ENABLED: "false" + SPRING_CONFIG_IMPORT: "" + + # Gemini 더미 키 (자동설정 실패 방지) + GEMINI_API_KEY: "dummy" + + # CI 로그 노이즈 감소 — 필요시 조정 + SPRING_JPA_SHOW_SQL: "false" + SPRING_JPA_PROPERTIES_HIBERNATE_FORMAT_SQL: "false" + LOGGING_LEVEL_ROOT: "warn" + LOGGING_LEVEL_ORG_SPRINGFRAMEWORK: "warn" + + # 6) 테스트 리포트 업로드 — 실패 시에도 항상 업로드하여 원인 파악 + - name: Upload test report + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-report-${{ matrix.dbmode }} + path: | + build/reports/tests/test + retention-days: 30 From 0a06a49639f953ff9bbebd55b61359069600538b Mon Sep 17 00:00:00 2001 From: endorsement0912 Date: Wed, 13 Aug 2025 22:49:10 +0900 Subject: [PATCH 03/11] =?UTF-8?q?[EA3-212]=20chore:=20=EB=A1=9C=EC=BB=AC/?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20=EC=84=A4=EC=A0=95=20=EC=B0=B8=EA=B3=A0?= =?UTF-8?q?=EC=9A=A9=20application-template.properties=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/application-template.properties | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 src/main/resources/application-template.properties diff --git a/src/main/resources/application-template.properties b/src/main/resources/application-template.properties new file mode 100644 index 00000000..9ed30d47 --- /dev/null +++ b/src/main/resources/application-template.properties @@ -0,0 +1,157 @@ +# ???????????????????????????????????????????????????????????????????????????????????????????? +# ??????????????????????? Application Template (DO NOT PUT SECRETS) ??????????????????????? +# ?? ?? ????/??? ???? ?????. +# - GCP: ${sm://secret-name} ?? ?? +# - AWS: ${ENV_NAME} ????/Secrets Manager ?? +# ????????????????????????????????????????????????????????????????????????????????????????? +# ???????????????????????????????????????????????????????????????????????????????????????????? + +# ---- Profile ---- +# ?? ??/?? ? -Dspring.profiles.active=prod-gcp ?? prod-aws ? ?? +spring.profiles.active= + +# ---- Server ---- +server.port=80 +server.servlet.encoding.charset=UTF-8 +server.servlet.encoding.enabled=true +server.servlet.encoding.force=true + +# ---- Domain / CORS (???? ?? ???) ---- +front-server.domain=${FRONT_SERVER_DOMAIN:https://example-frontend.com} +app.domain=${APP_DOMAIN:https://example-backend.com} + +# ---- File Upload / Multipart ---- +spring.servlet.multipart.max-file-size=10MB +spring.servlet.multipart.max-request-size=10MB + +# ---- Cache ---- +spring.cache.type=caffeine +spring.cache.cache-names=authority +spring.cache.caffeine.spec=expireAfterWrite=10s + +# ---- Logging ?? ---- +logging.level.root=info +logging.level.org.hibernate.SQL=info +logging.level.org.hibernate.type.descriptor.sql.BasicBinder=info +logging.level.org.hibernate.type.descriptor.sql=info +logging.level.org.springframework.cloud.openfeign=info +logging.level.org.springframework.security=info +logging.level.org.springframework.web.client.RestTemplate=info +logging.level.org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider=info +logging.level.org.springframework.security.oauth2.core.http.converter=info +spring.cloud.openfeign.client.config.default.logger-level=full + +# ---- JPA ?? ---- +spring.jpa.open-in-view=false +spring.sql.init.mode=never +spring.jpa.hibernate.ddl-auto=update +spring.jpa.properties.hibernate.format_sql=true +spring.jpa.defer-datasource-initialization=true +spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false +spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true +spring.sql.init.schema-locations=classpath:schema.sql +spring.sql.init.data-locations=classpath:data.sql + +# ?????????????????????????????????????????????????????????????????????????????????????????? +# ???????????????????????????? ??? ?? ??? ???? ?? ??????????????????????????? +# 1) GCP ?? (Secret Manager ?? ?) +# - spring.config.import=sm:// ? ??, ?? ?? ??? sm://? ?? +# 2) AWS ?? (ENV/Secrets Manager) +# - ${ENV_NAME} ??? ????, ECS/EC2?? ????? ?? +# ????????????????????????????????????????????????????????????????????????????????????????? +# ?????????????????????????????????????????????????????????????????????????????????????????? + +# [prod-gcp] ?? ========================================================================== +# spring.profiles: prod-gcp ?? ? ??? +# ?? ??: -Dspring.profiles.active=prod-gcp +# ========================================================================================== +# spring.config.import=sm:// # GCP Secret Manager ?? ? ?? + +# spring.cloud.gcp.secretmanager.enabled=true +# google.cloud.storage.bucket=YOUR_GCS_BUCKET +# google.cloud.storage.project-id=YOUR_GCP_PROJECT + +# ---- DB ---- +#spring.datasource.url=${sm://db-url} +#spring.datasource.username=${sm://db-username} +#spring.datasource.password=${sm://db-password} +#spring.datasource.driver-class-name=org.postgresql.Driver +#spring.datasource.hikari.maximum-pool-size=5 + +# ---- Redis ---- +#spring.data.redis.host=${sm://redis-host} +#spring.data.redis.port=${sm://redis-port} +#spring.data.redis.username=${sm://redis-username} +#spring.data.redis.password=${sm://redis-password} +#spring.data.redis.ssl.enabled=true + +# ---- JWT ---- +#jwt.expiration=${sm://jwt-expiration} +#jwt.refresh-expiration=${sm://jwt-refresh-expiration} +#jwt.secret=${sm://jwt-secret} + +# ---- Mail ---- +#spring.mail.host=smtp.gmail.com +#spring.mail.port=587 +#spring.mail.username=${sm://smtp-username} +#spring.mail.password=${sm://smtp-password} +#spring.mail.properties.mail.smtp.auth=true +#spring.mail.properties.mail.smtp.starttls.enable=true + +# ---- Google OAuth ---- +#spring.security.oauth2.client.registration.google.client-id=${sm://google-client-id} +#spring.security.oauth2.client.registration.google.client-secret=${sm://google-secret} +#spring.security.oauth2.client.registration.google.redirect-uri=${sm://google-redirect-uri} +#spring.security.oauth2.client.registration.google.scope=profile,email +#spring.security.oauth2.client.registration.google.client-name=Google + +# ---- LangChain/Gemini ---- +#langchain4j.google-ai-gemini.chat-model.model-name=${sm://gemini-chat-model-name} +#langchain4j.google-ai-gemini.chat-model.api-key=${sm://gemini-chat-model} +#langchain4j.google-ai-gemini.chat-model.log-requests-and-responses=true +#langchain4j.google-ai-gemini.chat-model.max-output-tokens=500 + +# [prod-aws] ?? ========================================================================== +# spring.profiles: prod-aws ?? ? ??? +# ?? ??: -Dspring.profiles.active=prod-aws +# ========================================================================================== + +# ---- DB ---- +spring.datasource.url=${SPRING_DATASOURCE_URL} +spring.datasource.username=${SPRING_DATASOURCE_USERNAME} +spring.datasource.password=${SPRING_DATASOURCE_PASSWORD} +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.datasource.hikari.maximum-pool-size=5 + +# ---- Redis ---- +spring.data.redis.host=${REDIS_HOST} +spring.data.redis.port=${REDIS_PORT} +spring.data.redis.username=${REDIS_USERNAME:default} +spring.data.redis.password=${REDIS_PASSWORD} +spring.data.redis.ssl.enabled=true + +# ---- JWT ---- +jwt.secret=${JWT_SECRET} +jwt.expiration=${JWT_EXPIRATION:31536000000} +jwt.refresh-expiration=${JWT_REFRESH_EXPIRATION:604800000} + +# ---- Mail ---- +spring.mail.host=smtp.gmail.com +spring.mail.port=587 +spring.mail.username=${SMTP_USERNAME} +spring.mail.password=${SMTP_PASSWORD} +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true + +# ---- Google OAuth ---- +spring.security.oauth2.client.registration.google.client-id=${GOOGLE_CLIENT_ID} +spring.security.oauth2.client.registration.google.client-secret=${GOOGLE_CLIENT_SECRET} +spring.security.oauth2.client.registration.google.redirect-uri=${GOOGLE_REDIRECT_URI} +spring.security.oauth2.client.registration.google.scope=profile,email +spring.security.oauth2.client.registration.google.client-name=Google + +# ---- LangChain/Gemini ---- +langchain4j.google-ai-gemini.chat-model.model-name=${GEMINI_MODEL_NAME:gemini-2.0-flash-lite} +langchain4j.google-ai-gemini.chat-model.api-key=${GEMINI_API_KEY} +langchain4j.google-ai-gemini.chat-model.log-requests-and-responses=true +langchain4j.google-ai-gemini.chat-model.max-output-tokens=500 From a40da87b156dd593cfb0046e826311e779e17d51 Mon Sep 17 00:00:00 2001 From: endorsement0912 Date: Wed, 13 Aug 2025 22:51:25 +0900 Subject: [PATCH 04/11] =?UTF-8?q?[EA3-212]=20feature:=20main=20=EB=B8=8C?= =?UTF-8?q?=EB=9E=9C=EC=B9=98=20PR=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C=EC=9A=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index c20a2110..d7d10a2f 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -2,7 +2,7 @@ name: PR CI (main) on: pull_request: - branches: [ "main" ] # main으로 향하는 PR만 검사 + branches: [ "main" ] # main으로 향하는 PR만 검사 types: [ opened, synchronize, reopened, ready_for_review ] # PR 열림/커밋추가/다시열기/드래프트해제 시 실행 paths-ignore: - '**.md' From 45e1e05109bd4a3bf4375fb7f34bc9735be4fcc6 Mon Sep 17 00:00:00 2001 From: endorsement0912 Date: Wed, 13 Aug 2025 22:51:49 +0900 Subject: [PATCH 05/11] =?UTF-8?q?[EA3-212]=20chore:=20.gitignore=20?= =?UTF-8?q?=EA=B7=9C=EC=B9=99=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6b9f66de..887cb848 100644 --- a/.gitignore +++ b/.gitignore @@ -89,7 +89,6 @@ application-local.properties application-prod.properties application-prod-aws.properties application-prod-gcp.properties -*.env # === 기타 === HELP.md From 7f3a23d51cb546325c16c0a02ce0cc8a08133635 Mon Sep 17 00:00:00 2001 From: endorsement0912 Date: Wed, 13 Aug 2025 23:05:33 +0900 Subject: [PATCH 06/11] =?UTF-8?q?[EA3-212]=20chore:=20.gitignore=20?= =?UTF-8?q?=EA=B7=9C=EC=B9=99=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8(test)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 887cb848..54c034c8 100644 --- a/.gitignore +++ b/.gitignore @@ -86,6 +86,7 @@ replay_pid* # === Spring Boot 환경설정 파일 === application.properties application-local.properties +application-test.properties application-prod.properties application-prod-aws.properties application-prod-gcp.properties From 0bcde7c560e92412ced921df00f5babd08483555 Mon Sep 17 00:00:00 2001 From: endorsement0912 Date: Wed, 13 Aug 2025 23:22:22 +0900 Subject: [PATCH 07/11] =?UTF-8?q?[EA3-212]=20refactor:=20=EB=8D=94?= =?UTF-8?q?=EB=AF=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci-pr.yml | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index d7d10a2f..9772a1ee 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -38,7 +38,11 @@ jobs: - name: Validate Gradle wrapper run: ./gradlew --version - # 5) 테스트 + # 5) 업로드 경로 더미 생성 (upload.path 값이 필요한 빈 대비) + - name: Prepare upload dir + run: mkdir -p /tmp/uploads + + # 6) 테스트 - name: Run tests (H2 via ENV) run: ./gradlew clean test --no-daemon --stacktrace --info env: @@ -73,7 +77,26 @@ jobs: SPRING_CLOUD_GCP_SECRET_MANAGER_ENABLED: "false" SPRING_CONFIG_IMPORT: "" - # Gemini 더미 키 (자동설정 실패 방지) + # ---- 자리값 더미(컨텍스트 부팅용) --- + # 파일 업로드 경로 (핵심) + UPLOAD_PATH: /tmp/uploads # upload.path와 자동 매핑 (relaxed binding) + # JWT / Mail + JWT_SECRET: dummy + SMTP_USERNAME: dummy@example.com + SMTP_PASSWORD: dummy + # OAuth2 + GOOGLE_CLIENT_ID: dummy + GOOGLE_CLIENT_SECRET: dummy + GOOGLE_REDIRECT_URI: http://localhost/login/oauth2/code/google + # Redis (값만 읽는 코드 대비) + REDIS_HOST: localhost + REDIS_PORT: "6379" + REDIS_USERNAME: default + REDIS_PASSWORD: dummy + # 도메인 기본값 + FRONT_SERVER_DOMAIN: http://localhost:3000 + APP_DOMAIN: http://localhost:8080 + # LangChain/Gemini GEMINI_API_KEY: "dummy" # CI 로그 노이즈 감소 — 필요시 조정 From 27c100816b5079faccccbd7212292977b21c06e8 Mon Sep 17 00:00:00 2001 From: endorsement0912 Date: Wed, 13 Aug 2025 23:36:20 +0900 Subject: [PATCH 08/11] =?UTF-8?q?[EA3-212]=20refactor:=20=EB=8D=94?= =?UTF-8?q?=EB=AF=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci-pr.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index 9772a1ee..e0702491 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -80,22 +80,28 @@ jobs: # ---- 자리값 더미(컨텍스트 부팅용) --- # 파일 업로드 경로 (핵심) UPLOAD_PATH: /tmp/uploads # upload.path와 자동 매핑 (relaxed binding) + # JWT / Mail JWT_SECRET: dummy SMTP_USERNAME: dummy@example.com SMTP_PASSWORD: dummy + # OAuth2 GOOGLE_CLIENT_ID: dummy GOOGLE_CLIENT_SECRET: dummy GOOGLE_REDIRECT_URI: http://localhost/login/oauth2/code/google + # Redis (값만 읽는 코드 대비) - REDIS_HOST: localhost - REDIS_PORT: "6379" - REDIS_USERNAME: default - REDIS_PASSWORD: dummy + SPRING_DATA_REDIS_HOST: localhost + SPRING_DATA_REDIS_PORT: "6379" + SPRING_DATA_REDIS_USERNAME: default + SPRING_DATA_REDIS_PASSWORD: dummy + SPRING_DATA_REDIS_SSL_ENABLED: "false" + # 도메인 기본값 FRONT_SERVER_DOMAIN: http://localhost:3000 - APP_DOMAIN: http://localhost:8080 + APP_DOMAIN: http://localhost:80 + # LangChain/Gemini GEMINI_API_KEY: "dummy" From 1b5c394fa05e47e30b0fce1f4e917749909c6ccd Mon Sep 17 00:00:00 2001 From: endorsement0912 Date: Wed, 13 Aug 2025 23:36:49 +0900 Subject: [PATCH 09/11] =?UTF-8?q?[EA3-212]=20refactor:=20job=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index e0702491..ac84e0a5 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -9,7 +9,7 @@ on: - 'docs/**' jobs: - build-and-test: + test: runs-on: ubuntu-latest timeout-minutes: 15 # CI가 너무 오래 걸릴 때 무한 대기 방지 (필요시 늘려도 됨) strategy: From 1f3f3b0f3259b44cf93e9ee1178963143ca64e3c Mon Sep 17 00:00:00 2001 From: endorsement0912 Date: Thu, 14 Aug 2025 00:01:44 +0900 Subject: [PATCH 10/11] =?UTF-8?q?[EA3-212]=20refactor:=20Draft=20PR=20?= =?UTF-8?q?=EC=8A=A4=ED=82=B5=20=EB=B0=8F=20PR=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci-pr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index ac84e0a5..3876c81d 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -10,6 +10,7 @@ on: jobs: test: + if: github.event.pull_request.draft == false runs-on: ubuntu-latest timeout-minutes: 15 # CI가 너무 오래 걸릴 때 무한 대기 방지 (필요시 늘려도 됨) strategy: From d6b55ed36051152f0351d6b5b2e8c1fc5ddcddae Mon Sep 17 00:00:00 2001 From: endorsement0912 Date: Thu, 14 Aug 2025 00:02:13 +0900 Subject: [PATCH 11/11] =?UTF-8?q?[EA3-212]=20test:=20=ED=86=B5=ED=95=A9?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=9A=A9=20=EC=8B=9C=ED=81=90?= =?UTF-8?q?=EB=A6=AC=ED=8B=B0=20=EB=AA=A9=20=EB=B9=88=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?(JWT=20=ED=95=84=ED=84=B0/=EC=98=88=EC=99=B8=ED=95=84=ED=84=B0/?= =?UTF-8?q?=EB=B8=94=EB=9E=99=EB=A6=AC=EC=8A=A4=ED=8A=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/IntegrationTestSupport.java | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/test/java/grep/neogulcoder/domain/IntegrationTestSupport.java b/src/test/java/grep/neogulcoder/domain/IntegrationTestSupport.java index 21eae885..36eadbb8 100644 --- a/src/test/java/grep/neogulcoder/domain/IntegrationTestSupport.java +++ b/src/test/java/grep/neogulcoder/domain/IntegrationTestSupport.java @@ -1,22 +1,46 @@ package grep.neogulcoder.domain; -import grep.neogulcoder.domain.review.service.ReviewService; import grep.neogulcoder.domain.review.repository.MyReviewTagRepository; import grep.neogulcoder.domain.review.repository.ReviewRepository; import grep.neogulcoder.domain.review.repository.ReviewTagRepository; +import grep.neogulcoder.domain.review.service.ReviewService; import grep.neogulcoder.domain.study.repository.StudyMemberRepository; import grep.neogulcoder.domain.study.repository.StudyRepository; import grep.neogulcoder.domain.users.repository.UserRepository; -import org.springframework.beans.factory.annotation.Autowired; +import grep.neogulcoder.global.auth.jwt.JwtAuthenticationFilter; +import grep.neogulcoder.global.auth.jwt.JwtExceptionFilter; +import grep.neogulcoder.global.auth.repository.UserBlackListRepository; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.transaction.annotation.Transactional; +import org.springframework.beans.factory.annotation.Autowired; @Transactional @ActiveProfiles("test") +@ExtendWith(SpringExtension.class) @SpringBootTest +@Import(IntegrationTestSupport.SecurityMocks.class) public abstract class IntegrationTestSupport { + @TestConfiguration + static class SecurityMocks { + @Bean JwtAuthenticationFilter jwtAuthenticationFilter() { + return Mockito.mock(JwtAuthenticationFilter.class); + } + @Bean JwtExceptionFilter jwtExceptionFilter() { + return Mockito.mock(JwtExceptionFilter.class); + } + @Bean UserBlackListRepository userBlackListRepository() { + return Mockito.mock(UserBlackListRepository.class); + } + } + @Autowired private UserRepository userRepository;