Skip to content

chore: JaCoCo와 SonarCloud를 연동한 Gradle 빌드 및 품질 관리 시스템 구축 #30

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

Merged
merged 17 commits into from
Jul 7, 2025

Conversation

hoonyworld
Copy link
Member

@hoonyworld hoonyworld commented Jul 6, 2025

🔗 관련 이슈

📘 작업 유형

  • ✨ Feature (기능 추가)
  • 🐞 Bugfix (버그 수정)
  • 🔧 Refactor (코드 리팩토링)
  • ⚙️ Chore (환경 설정)
  • 📝 Docs (문서 작성 및 수정)
  • ✅ Test (기능 테스트)
  • 🎨 style (코드 스타일 수정)

📙 작업 내역

🎯 개요

  • 프로젝트의 안정성과 개발 생산성을 향상시키기 위해 Gradle 기반의 빌드 자동화 및 코드 품질 관리 시스템을 구축했습니다.
  • 이제 PR을 통해 JaCoCo를 이용한 테스트 커버리지 측정, SonarCloud를 이용한 정적 코드 분석 및 품질 게이트 관리가 자동화됩니다.

✨ 주요 변경 사항

0. kover 대신 JaCoCo 사용

  • Kover는 JetBrains에서 개발한 Kotlin 전용 코드 커버리지 도구로 잠재력은 있지만, Kover에 대한 참고 자료가 매우 부족했습니다.
  • 따라서, 현재 시점에서는 JaCoCo를 선택하는 것이 더 실용적이라고 판단했습니다.
  • 추후, Kover 관련 충분한 자료가 축적되면 JaCoCo에서 Kover로의 마이그레이션을 고려할 예정입니다.

1. JaCoCo 테스트 커버리지 설정

  • 멀티모듈 환경에 맞춰 각 하위 모듈의 테스트 커버리지를 측정하도록 설정했습니다.
  • 루트 프로젝트에서 모든 모듈의 커버리지를 취합하는 통합 리포트(jacocoRootReport)를 생성하여 프로젝트 전체의 커버리지를 한눈에 파악할 수 있습니다.
  • testExclusionPatterns 변수를 통해 DTO, Entity 등 테스트가 불필요한 클래스를 커버리지 측정에서 일관되게 제외하여 리포트의 정확성을 높였습니다.

2. SonarQube 정적 분석 연동

  • 생성된 JaCoCo 통합 리포트를 SonarCloud 분석에 활용하도록 연동했습니다.
  • sonarGlobalExclusions 변수를 통해 빌드 결과물 등 분석이 무의미한 파일을 제외하여 분석 효율을 높였습니다.
  • .yml, .properties 파일을 분석 대상에 포함하여, SonarCloud가 하드코딩된 API 키나 비밀번호 등 보안 비밀(Secrets)을 탐지할 수 있도록 했습니다.

3. Gradle 빌드 스크립트 고도화

  • tasks.named, dependsOn("이름") 등 Gradle의 지연 설정(Lazy Configuration) 방식을 전면 적용하여 빌드 성능을 최적화하고 잠재적 오류를 방지했습니다.

4. 편의 태스크 추가 및 정리

  • 개발 및 CI/CD 환경의 목적에 맞는 다양한 편의 태스크를 추가했습니다.
  • fullCheck (CI/CD용): 테스트, 커버리지, SonarCloud 분석까지 전체 파이프라인을 한 번에 실행합니다.
  • checkCoverage (로컬용): SonarCloud 분석 없이 로컬에서 빠르게 커버리지만 확인합니다.
  • cleanReports (로컬용): 생성된 모든 리포트를 삭제합니다.

5. CI 워크플로우 간소화 (GitHub Actions)

  • 기존에 여러 단계로 나뉘어 있던 Gradle 실행 명령을 새로 추가한 fullCheck 태스크 하나로 통합했습니다.
  • 이를 통해 CI 스크립트의 가독성과 유지보수성을 크게 향상시켰습니다.

🚀 실행 방법

  • 로컬에서 커버리지 확인: ./gradlew checkCoverage
  • 로컬에서 리포트 삭제 : ./gradlew cleanReports
  • CI: Pull Request 생성 시 GitHub Actions에서 ./gradlew fullCheck가 자동으로 실행됩니다.

🧪 테스트 내역

  • 브라우저/기기에서 동작 확인
  • 엣지 케이스 테스트 완료
  • 기존 기능 영향 없음

🎨 스크린샷 또는 시연 영상 (선택)

기능 미리보기 기능 미리보기
기능 설명 기능 설명

✅ PR 체크리스트

  • 커밋 메시지가 명확합니다
  • PR 제목이 컨벤션에 맞습니다
  • 관련 이슈 번호를 작성했습니다
  • 기능이 정상적으로 작동합니다
  • 불필요한 코드를 제거했습니다

💬 추가 설명 or 리뷰 포인트 (선택)

  • 실행 방법 부분에 대해서 민우님의 생각이 궁금합니다!

Summary by CodeRabbit

Summary by CodeRabbit

  • 새로운 기능

    • 코드 커버리지 및 정적 분석을 위한 JaCoCo와 SonarQube 통합이 추가되었습니다.
    • 모든 서브프로젝트에 대해 테스트, 커버리지 리포트, SonarQube 분석을 실행하는 편리한 Gradle 태스크가 도입되었습니다.
    • 코드 품질 및 커버리지 리포트 집계를 위한 집계 리포트 태스크가 추가되었습니다.
  • 개선 사항

    • CI 워크플로우에서 SonarCloud 패키지 캐싱 및 전체 코드 분석이 가능해졌습니다.
    • 프로젝트 이름이 "multi-module-test"에서 "reed"로 변경되었습니다.

Copy link

coderabbitai bot commented Jul 6, 2025

📝 Walkthrough
## Walkthrough

SonarCloud와 JaCoCo 통합을 위해 Gradle 빌드 스크립트와 GitHub Actions CI 워크플로가 대폭 수정되었습니다. 모든 서브프로젝트에 JaCoCo 적용, 커버리지 집계, SonarQube 분석 및 연동, CI에서 SonarCloud 인증 및 캐시 사용, 편의성 높은 Gradle 태스크 추가 등이 이루어졌습니다.

## Changes

| 파일/경로                                                         | 변경 요약                                                                                                       |
|-------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|
| .github/workflows/ci-pr.yml                                       | PR CI 워크플로: 타임아웃 15분으로 증가, SonarCloud 캐시 추가, Gradle 태스크를 fullCheck 및 Sonar 분석으로 변경   |
| build.gradle.kts                                                  | JaCoCo/ SonarQube 플러그인 통합, 커버리지 집계, SonarQube 설정, 커버리지 제외 패턴, 여러 편의 태스크 추가      |
| buildSrc/src/main/kotlin/Plugins.kt, buildSrc/src/main/kotlin/Versions.kt | JaCoCo 및 SonarQube 플러그인/버전 상수 추가                                                                   |
| settings.gradle.kts                                               | 루트 프로젝트명 "reed"로 변경                                                                                  |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Developer
    participant GitHub Actions
    participant Gradle
    participant SonarCloud

    Developer->>GitHub Actions: PR 생성/업데이트
    GitHub Actions->>Gradle: ./gradlew fullCheck
    Gradle->>Gradle: 모든 서브모듈 테스트, JaCoCo 리포트 생성
    Gradle->>Gradle: jacocoRootReport(집계 커버리지)
    Gradle->>SonarCloud: SonarQube 분석 및 커버리지 업로드
    SonarCloud-->>Gradle: 분석 결과 반환
    Gradle-->>GitHub Actions: 빌드 및 분석 완료

Assessment against linked issues

Objective Addressed Explanation
SonarCloud와 JaCoCo 연동을 통한 코드 커버리지 분석 및 시각화 설정 (#28)

Assessment against linked issues: Out-of-scope changes

해당 변경사항들은 모두 SonarCloud와 JaCoCo 연동, 커버리지 분석 및 CI 설정에 집중되어 있으며, 명시된 이슈(#28)의 범위를 벗어나는 기능적 변경이나 불필요한 코드 추가는 발견되지 않았습니다.


</details>

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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= -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=YAPP-Github/Reed-Server&utm_content=30):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb55e09 and 34bfabd.

📒 Files selected for processing (5)
  • .github/workflows/ci-pr.yml (2 hunks)
  • build.gradle.kts (4 hunks)
  • buildSrc/src/main/kotlin/Plugins.kt (1 hunks)
  • buildSrc/src/main/kotlin/Versions.kt (1 hunks)
  • settings.gradle.kts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-validation
🔇 Additional comments (4)
settings.gradle.kts (1)

1-1: 프로젝트 이름 변경 후 레거시 참조 없음 확인

전체 코드베이스에서 multi-module-test 문자열을 검색한 결과가 없으므로 하드코딩된 참조는 더 이상 존재하지 않습니다.

buildSrc/src/main/kotlin/Versions.kt (1)

7-8: 버전 상수 추가 👍

SonarQube / JaCoCo 버전을 상수로 관리한 점이 가독성과 유지보수에 도움이 됩니다.

buildSrc/src/main/kotlin/Plugins.kt (1)

6-7: 플러그인 상수 정의 적절

JACOCO, SONAR_QUBE 상수 추가가 일관된 DSL 구성을 돕습니다.

.github/workflows/ci-pr.yml (1)

57-62: GITHUB_TOKEN 은 기본 제공 토큰 사용을 권장

CI 실행 환경에는 secrets.GITHUB_TOKEN이 자동 주입됩니다. 별도의 PAT_TOKEN을 지정할 필요가 없다면 기본 토큰으로 대체해 보안 노출을 줄이세요.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (1)
build.gradle.kts (1)

13-13: 루트·서브모듈 중복 Jacoco 플러그인 적용

이전 리뷰에서 이미 동일한 제안을 드렸습니다. 여전히 루트와 서브모듈에 모두 id(Plugins.JACOCO) 가 선언되어 있습니다. 루트에는 불필요하므로 제거하여 설정 중복과 태스크 생성 오버헤드를 줄이십시오.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 34bfabd and 41a17e4.

📒 Files selected for processing (1)
  • build.gradle.kts (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-validation
🔇 Additional comments (1)
build.gradle.kts (1)

164-165: sonar.kotlin.source.version 값 형식 확인 필요

SonarCloud 문서상 해당 속성은 1.9 처럼 메이저.마이너 를 기대합니다. Versions.KOTLIN 상수가 1.9.22 같은 패치 버전까지 포함하면 파싱 오류가 날 수 있으니 실제 분석 로그를 확인하십시오.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
build.gradle.kts (1)

12-13: 플러그인 적용 중복 이슈 확인 필요

루트 프로젝트와 모든 서브모듈에 JaCoCo 플러그인을 중복 적용하고 있습니다. 이는 빌드 성능에 영향을 줄 수 있습니다.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 41a17e4 and 252293f.

📒 Files selected for processing (2)
  • build.gradle.kts (4 hunks)
  • buildSrc/src/main/kotlin/Versions.kt (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-validation
🔇 Additional comments (7)
buildSrc/src/main/kotlin/Versions.kt (1)

6-7: 새로운 도구 버전 상수 추가가 적절합니다

JaCoCo 0.8.13과 SonarQube 6.2.0.5505는 안정적이고 최신 기능을 지원하는 버전입니다. Kover에서 JaCoCo로의 전환에 맞춰 적절히 업데이트되었습니다.

build.gradle.kts (6)

1-1: SonarQube 확장 임포트 추가가 적절합니다

SonarQube 설정을 위한 필수 임포트문이 올바르게 추가되었습니다.


24-44: 제외 패턴 정의가 체계적이고 포괄적입니다

테스트 제외 패턴과 SonarQube 전체 분석 제외 패턴이 잘 정의되어 있습니다. 특히 DTO, Entity, Config 클래스들을 적절히 제외하여 의미 있는 커버리지 측정이 가능합니다.


85-118: 서브모듈 JaCoCo 설정이 잘 구성되었습니다

각 서브모듈의 JaCoCo 설정이 체계적으로 구성되어 있습니다. 특히 executionData.setFrom(fileTree(...))를 사용하여 이전 리뷰에서 지적된 실행 데이터 누락 문제가 해결되었습니다.


139-143: 실행 데이터 수집 방식이 개선되었습니다

하드코딩된 .exec 파일 경로 대신 fileTreeinclude("*.exec")를 사용하여 모든 실행 데이터 파일을 안전하게 수집하도록 개선되었습니다. 이는 이전 리뷰에서 지적된 문제를 해결합니다.


186-229: 편의성 태스크들이 잘 설계되었습니다

fullCheck, checkCoverage, cleanReports 등의 편의성 태스크들이 명확한 목적과 적절한 의존성을 가지고 잘 구성되어 있습니다. 특히 CI/CD 파이프라인과 로컬 개발 환경을 고려한 구분이 훌륭합니다.


75-78: Kotlin 컴파일러 플래그 지원 여부 검증 필요

File: build.gradle.kts
Lines: 75–78

            freeCompilerArgs = listOf(
                "-Xjsr305=strict",
                "-Xconsistent-data-class-copy-visibility"
            )

현재 Kotlin 1.9.25에서 -Xconsistent-data-class-copy-visibility 플래그의 공식 지원 여부는 확인되지 않습니다. 아래를 검토해 주세요:

  • JetBrains 공식 문서 및 블로그
  • Kotlin GitHub 저장소의 1.9.25 릴리스 노트

해당 플래그가 지원되지 않으면 제거하거나, 필요시 Kotlin 버전 업그레이드를 고려해야 합니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
.github/workflows/ci-pr.yml (1)

47-52: SonarCloud 캐시 키에 의존성 해시를 포함하세요

지난 리뷰에서 동일 지적이 있었습니다만 아직 runner.os만 사용하고 있습니다. Sonar 플러그인 버전이나 Gradle 스크립트 변경 시 캐시 미스가 잦아집니다.

-key: ${{ runner.os }}-sonar
-restore-keys: ${{ runner.os }}-sonar
+key: ${{ runner.os }}-sonar-${{ hashFiles('**/build.gradle.kts', '**/gradle.properties') }}
+restore-keys: |
+  ${{ runner.os }}-sonar-
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 252293f and 774ef36.

📒 Files selected for processing (1)
  • .github/workflows/ci-pr.yml (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-validation
🔇 Additional comments (1)
.github/workflows/ci-pr.yml (1)

20-20: 타임아웃 15 분 증설 👍

빌드 + Sonar 분석을 고려하면 10 분은 촉박했습니다. 15 분 증설 잘 반영되었습니다.

- 현재 프로젝트는 Kotlin으로만 작성되어 'build/classes/java/main' 디렉토리가 존재하지 않습니다.
- 하지만 JaCoCo는 기본적으로 이 경로를 확인하려 시도하여 불필요한 "not found" 경고가 발생했습니다.
- 이를 해결하기 위해, classDirectories가 실제로 컴파일된 클래스 파일이 있는 경로('classesDirs')만 참조하도록 설정을 최적화하여 경고 로그를 제거했습니다.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (4)
.github/workflows/ci-pr.yml (2)

47-53: SonarCloud 캐시 키 세분화 제안이 아직 반영되지 않았습니다
key: ${{ runner.os }}-sonar 한 줄만으로는 Sonar 패키지 버전 변경 시 캐시 적중률이 급락합니다.
이전 리뷰에서 제안드린 hashFiles('**/build.gradle.kts') 등 의존 파일 해시를 포함하는 방식으로 수정해 주세요.


57-61: PAT_TOKEN 사용 이유가 명확하지 않습니다
여전히 GITHUB_TOKEN 대신 PAT_TOKEN을 주입하고 있습니다. 기본 제공 토큰으로도 PR 데코레이션이 가능하므로 불필요할 경우 제거하거나, 꼭 필요하다면 최소 권한으로 축소해 주세요.

build.gradle.kts (2)

12-13: 루트·서브모듈에 Jacoco 플러그인이 중복 적용되고 있습니다
루트에만 적용해도 통합 리포트 생성에는 지장이 없습니다. 중복 선언을 제거해 빌드 시간을 단축하세요.

Also applies to: 52-53


154-156: 프로젝트 키·조직 하드코딩이 여전히 남아 있습니다
다른 환경 재사용성을 위해 Gradle 속성이나 환경변수로 분리하는 지난 제안이 반영되지 않았습니다.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 77a7b26 and 09284b2.

📒 Files selected for processing (2)
  • .github/workflows/ci-pr.yml (2 hunks)
  • build.gradle.kts (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-validation
🔇 Additional comments (2)
.github/workflows/ci-pr.yml (1)

20-20: 빌드 타임아웃 15 분 상향은 합리적입니다
CI 환경(ubuntu-24.04)에서 fullCheck 전체 파이프라인을 돌릴 때 10 분은 촉박하므로 15 분 상향을 승인합니다.

build.gradle.kts (1)

75-78: Kotlin 컴파일러 플래그 추가 승인
-Xconsistent-data-class-copy-visibility 플래그 추가는 호환성 유지에 도움이 됩니다. 문제 없다고 판단됩니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (4)
.github/workflows/ci-pr.yml (2)

47-52: SonarCloud 캐시 키 세분화 제안이 아직 반영되지 않았습니다
runner.os만 사용하면 패키지 버전 변경 시 캐시 적중률이 급격히 떨어집니다. 이전 리뷰에서 제안된 hashFiles('**/build.gradle.kts') 등을 포함한 키로 세분화해 주세요.


57-61: PAT_TOKEN 대신 기본 GITHUB_TOKEN 사용 검토 필요
별도 PAT를 쓰지 않아도 PR 데코레이션이 가능합니다. 불필요한 범위 확장을 피하기 위해 기본 토큰으로 교체하거나, 꼭 필요하다면 최소 권한만 부여해 주세요.

build.gradle.kts (2)

12-13: 루트 프로젝트에 JaCoCo 플러그인 중복 적용
서브모듈 전역 apply(plugin = Plugins.JACOCO) 호출이 이미 있으므로 루트 선언은 불필요합니다. 빌드 속도·가독성 개선을 위해 제거를 권장합니다.


151-175: SonarQube 프로젝트 키·조직명 하드코딩 유지
다른 환경 재사용성을 위해 Gradle 속성·환경변수로 분리하라는 이전 제안이 아직 반영되지 않았습니다. 추후 멀티 환경 지원을 고려해 동적 값으로 전환해 주세요.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 09284b2 and bf4fe3d.

📒 Files selected for processing (2)
  • .github/workflows/ci-pr.yml (2 hunks)
  • build.gradle.kts (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-validation

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (3)
build.gradle.kts (3)

11-12: 루트·서브모듈 모두에 JaCoCo 플러그인 적용 – 여전히 중복입니다
루트(plugins 블록)와 subprojects 블록(50 라인) 양쪽에서 id(Plugins.JACOCO)를 선언하고 있습니다. 루트에서 굳이 적용하지 않아도 통합 리포트 생성에는 지장이 없으니, 빌드 시간·설정 복잡도를 줄이려면 한쪽(보통 서브모듈)만 남기는 편이 좋습니다.


118-118: BootJar 비활성화 범위가 루트만 포함 – 서브모듈까지 확장 필요
withType<BootJar> { enabled = false } 가 루트의 tasks 컨테이너에만 적용돼 서브모듈의 bootJar 태스크는 그대로 남아 있습니다. 모든 모듈에서 BootJar 출력을 막으려면

subprojects { tasks.withType<BootJar> { enabled = false } }

형태로 변경해 주세요.


150-156: SonarCloud 프로젝트 키·조직명 하드코딩 – 환경변수/Gradle 프로퍼티로 분리 권장
재사용성과 보안을 위해 sonar.projectKey, sonar.organization 값을 하드코딩 대신 project.findProperty(...)System.getenv(...) 로 주입하도록 이전 리뷰에서 제안드렸습니다. 아직 반영되지 않았습니다.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d6d0bda and a15892a.

📒 Files selected for processing (1)
  • build.gradle.kts (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-validation

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (3)
build.gradle.kts (3)

11-12: 루트·서브모듈에 JaCoCo 플러그인이 중복 적용되고 있습니다

지난 라운드에서 동일한 사안이 지적되었으나 여전히 남아 있습니다. 루트와 서브모듈 모두에 id(Plugins.JACOCO)를 선언하면 설정 난해도·태스크 중복이 발생합니다. 루트 집계 리포트만 필요하다면 루트에서 제거하고 서브모듈에만 유지하는 편이 깔끔합니다.

Also applies to: 50-51


113-116: BootJar 비활성화 범위가 서브모듈에 적용되지 않았습니다

이전 리뷰에서 동일 내용이 언급됐습니다. 서브모듈의 bootJar 태스크도 함께 끄려면 다음과 같이 추가하세요.

subprojects {
    tasks.withType<BootJar> { enabled = false }
}

145-161: SonarCloud 설정 값 하드코딩 지속

프로젝트 키·조직명이 그대로 하드코딩되어 있어 포크/다른 조직 사용 시 변경이 번거롭습니다. project.findProperty("sonar.projectKey") ?: "default" 형태로 외부 프로퍼티를 우선시하도록 한 번 더 검토해 주세요.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a15892a and e57c642.

📒 Files selected for processing (1)
  • build.gradle.kts (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-validation
🔇 Additional comments (1)
build.gradle.kts (1)

69-72: 컴파일러 플래그 누적 방식 적용 👍

+= 형태로 변경돼 기존 플래그 손실 우려가 해소되었습니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (4)
build.gradle.kts (4)

11-12: 루트·서브모듈에 jacoco 중복 적용 문제 여전히 존재

이 줄에서 루트에 jacoco 플러그인을 적용하고, 아래 subprojects { ... } 블록에서도 다시 적용하고 있습니다. 이전 리뷰에서도 동일 지적이 있었으나 반영되지 않았습니다. 루트 선언을 제거하거나 apply false 처리해 중복을 없애세요.


84-92: finalizedBy("jacocoTestReport") — 문자열 참조는 다중 Test 태스크에서 누락 가능

integrationTestfunctionalTest 등 추가 Test 태스크가 있는 모듈은 jacocoTestReport 실행이 보장되지 않습니다.
이전 리뷰와 동일한 지적이므로 finalizedBy(tasks.named<JacocoReport>("jacocoTestReport")) 로 변경하거나, 특정 테스트 태스크만 선택적으로 지정하세요.


107-109: 존재하지 않는 .exec 파일 접근 시 경고 발생 가능

fileTree 결과에 filter { it.exists() } 가 없어 빌드 초기 경고가 그대로 발생합니다. 지난 리뷰와 동일 지적입니다.


144-160: Sonar 설정 하드코딩 및 속성 오용

  1. sonar.projectKey, sonar.organization 값이 그대로 하드코딩돼 있습니다. 지난 리뷰와 동일 지적입니다. project.findProperty(...) ?: System.getenv(...) 방식으로 분리해 주세요.
  2. sonar.kotlin.coveragePluginPlugins.JACOCO 상수를 넘기면 실제 값이 jacoco 가 아닐 수 있습니다. 문서상 허용 값은 "jacoco" 문자열입니다. 확인 후 문자열 리터럴로 지정하거나 속성을 제거하세요.
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b9ea80 and cd1c928.

📒 Files selected for processing (1)
  • build.gradle.kts (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-validation
🔇 Additional comments (1)
build.gradle.kts (1)

69-72: 컴파일러 플래그 누적 방식 변경 반영 👍
+= 로 누적하도록 수정되어 기존 플래그 손실 위험이 해소됐습니다.

Comment on lines +118 to +135
// 루트 프로젝트 JaCoCo 통합 리포트 설정
tasks.register<JacocoReport>("jacocoRootReport") {
description = "Generates an aggregate report from all subprojects"
group = "reporting"

dependsOn(subprojects.map { it.tasks.named("test") })

sourceDirectories.setFrom(subprojects.map { it.the<SourceSetContainer>()["main"].allSource.srcDirs })
classDirectories.setFrom(subprojects.map { subproject ->
subproject.fileTree(subproject.layout.buildDirectory.get().asFile.resolve("classes/kotlin/main")) {
exclude(testExclusionPatterns)
}
})
executionData.from(subprojects.map { subproject ->
subproject.fileTree(subproject.layout.buildDirectory.dir("jacoco")) {
include("**/*.exec")
}
})
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

통합 리포트에도 .exec 존재 여부 필터 필요

jacocoRootReportexecutionData.from(...) 에서도 .exec 파일이 없을 때 경고가 출력됩니다. 아래처럼 필터를 추가해 안전하게 수집하세요.

-    executionData.from(subprojects.map { subproject ->
-        subproject.fileTree(subproject.layout.buildDirectory.dir("jacoco")) {
-            include("**/*.exec")
-        }
-    })
+    executionData.from(subprojects.map { sp ->
+        sp.fileTree("${sp.buildDir}/jacoco") {
+            include("**/*.exec")
+        }.filter { it.exists() }
+    })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// 루트 프로젝트 JaCoCo 통합 리포트 설정
tasks.register<JacocoReport>("jacocoRootReport") {
description = "Generates an aggregate report from all subprojects"
group = "reporting"
dependsOn(subprojects.map { it.tasks.named("test") })
sourceDirectories.setFrom(subprojects.map { it.the<SourceSetContainer>()["main"].allSource.srcDirs })
classDirectories.setFrom(subprojects.map { subproject ->
subproject.fileTree(subproject.layout.buildDirectory.get().asFile.resolve("classes/kotlin/main")) {
exclude(testExclusionPatterns)
}
})
executionData.from(subprojects.map { subproject ->
subproject.fileTree(subproject.layout.buildDirectory.dir("jacoco")) {
include("**/*.exec")
}
})
// 루트 프로젝트 JaCoCo 통합 리포트 설정
tasks.register<JacocoReport>("jacocoRootReport") {
description = "Generates an aggregate report from all subprojects"
group = "reporting"
dependsOn(subprojects.map { it.tasks.named("test") })
sourceDirectories.setFrom(subprojects.map { it.the<SourceSetContainer>()["main"].allSource.srcDirs })
classDirectories.setFrom(subprojects.map { subproject ->
subproject.fileTree(subproject.layout.buildDirectory.get().asFile.resolve("classes/kotlin/main")) {
exclude(testExclusionPatterns)
}
})
executionData.from(subprojects.map { sp ->
sp.fileTree("${sp.buildDir}/jacoco") {
include("**/*.exec")
}.filter { it.exists() }
})
}
🤖 Prompt for AI Agents
In build.gradle.kts around lines 118 to 135, the jacocoRootReport task's
executionData.from(...) collects .exec files without checking if they exist,
causing warnings when no .exec files are present. Modify the code to filter out
empty file collections by adding a check to include only non-empty file trees,
ensuring safe and warning-free aggregation of execution data.

Copy link

sonarqubecloud bot commented Jul 6, 2025

Copy link
Member

@minwoo1999 minwoo1999 left a comment

Choose a reason for hiding this comment

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

테스트 커버리지 측정은 저 커맨트 명령어로 해도 좋은 것 같아요!
추후에 테스트코드 작성할 때 최소 몇퍼 커버리지로 가져갈지
테스트 코드에 대한 컨벤션도 맞춰보면 좋을 것 같습니다
고생하셨습니다~

@hoonyworld hoonyworld merged commit a857ca5 into develop Jul 7, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BOOK-94/chore] SonarCloud와 JaCoCo 연동을 통한 코드 커버리지 분석 및 시각화 설정
2 participants