Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 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
20 changes: 11 additions & 9 deletions .github/workflows/_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ on:
description: 'Build outcome (success/failure)'
# jobs.build.outputs.outcome 값을 외부로 노출
value: ${{ jobs.build.outputs.outcome }}
build-scan-url:
build-scan:
description: 'Gradle Build Scan URL'
value: ${{ jobs.build.outputs.build-scan-url }}
value: ${{ jobs.build.outputs.build-scan }}

jobs:
build:
Expand All @@ -50,7 +50,10 @@ jobs:
# outputs: 이 job의 결과를 다른 job이나 워크플로우에서 참조 가능하게 함
outputs:
outcome: ${{ steps.build.outcome }}
build-scan-url: ${{ steps.gradle-build.outputs.build-scan-url }}
build-scan: ${{ steps.gradle-build.outputs.build-scan }}
# env: secrets를 환경변수로 변환 (if 조건에서 secrets 직접 참조 불가)
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down Expand Up @@ -118,14 +121,13 @@ jobs:
path: '**/build/test-results/'
retention-days: 7

# Slack 알림 (빌드 실패 시 또는 Build Scan URL 공유)
# Slack 알림 (빌드 실패 시)
- name: Notify Slack on failure
# secrets.SLACK_WEBHOOK_URL이 설정되어 있고 빌드 실패 시에만 실행
if: failure() && secrets.SLACK_WEBHOOK_URL != ''
# env.SLACK_WEBHOOK_URL 사용 (secrets는 if 조건에서 직접 참조 불가)
if: failure() && env.SLACK_WEBHOOK_URL != ''
uses: slackapi/[email protected]
with:
# webhook: Slack Incoming Webhook URL
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook: ${{ env.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
# payload: Slack 메시지 JSON 형식
payload: |
Expand All @@ -144,7 +146,7 @@ jobs:
"fields": [
{
"type": "mrkdwn",
"text": "*Build Scan:*\n${{ steps.gradle-build.outputs.build-scan-url || 'N/A' }}"
"text": "*Build Scan:*\n${{ steps.gradle-build.outputs.build-scan || 'N/A' }}"
},
{
"type": "mrkdwn",
Expand Down
41 changes: 2 additions & 39 deletions .github/workflows/pr-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ jobs:

- name: Analyze with SonarCloud
uses: SonarSource/sonarcloud-github-action@master
# Quality Gate 실패 시 PR 차단을 원하면 아래 줄 제거
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.SECRET_GITHUB_BOT }}
Expand All @@ -86,45 +87,7 @@ jobs:
-Dsonar.projectKey=${{ env.SONAR_PROJECT_KEY }}
-Dsonar.organization=f-lab-edu-1

# 4. Qodana 정적 분석 (JetBrains)
qodana:
name: Qodana
needs: [ build ]
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
checks: write
security-events: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0

- name: Qodana Scan
uses: JetBrains/[email protected]
continue-on-error: true
env:
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
with:
# PR 모드: 변경된 파일만 분석하여 속도 향상
pr-mode: true
use-caches: true
post-pr-comment: true
use-annotations: true
upload-result: true
push-fixes: 'none'

- name: Upload SARIF to GitHub Security
if: always()
uses: github/codeql-action/upload-sarif@v3
continue-on-error: true
with:
sarif_file: ${{ runner.temp }}/qodana/results/qodana.sarif.json

# 5. 자동 리뷰어 할당
# 4. 자동 리뷰어 할당
auto-assign:
name: Auto Assign
runs-on: ubuntu-latest
Expand Down
25 changes: 21 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,23 +114,40 @@ jobs:
notify:
name: Notify Release
needs: [ docker ]
if: always() && secrets.SLACK_WEBHOOK_URL != ''
if: always()
runs-on: ubuntu-latest
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
steps:
# 릴리스 결과에 따라 메시지 설정
- name: Set notification message
id: message
env:
DOCKER_RESULT: ${{ needs.docker.result }}
run: |
if [ "$DOCKER_RESULT" == "success" ]; then
echo "status=Release 성공" >> $GITHUB_OUTPUT
echo "status_bold=*Release 성공*" >> $GITHUB_OUTPUT
else
echo "status=Release 실패" >> $GITHUB_OUTPUT
echo "status_bold=*Release 실패*" >> $GITHUB_OUTPUT
fi

- name: Send Slack notification
if: env.SLACK_WEBHOOK_URL != ''
uses: slackapi/[email protected]
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook: ${{ env.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
{
"text": "${{ needs.docker.result == 'success' && 'Release 성공' || 'Release 실패' }}",
"text": "${{ steps.message.outputs.status }}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "${{ needs.docker.result == 'success' && '*Release 성공*' || '*Release 실패*' }}\n*Version:* `${{ github.ref_name }}`\n*Image:* `${{ needs.docker.outputs.image-name }}`"
"text": "${{ steps.message.outputs.status_bold }}\n*Version:* `${{ github.ref_name }}`\n*Image:* `${{ needs.docker.outputs.image-name }}`"
}
},
{
Expand Down
3 changes: 3 additions & 0 deletions build-logic/src/main/kotlin/lm.java-infra.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ dependencies {
"runtimeOnly"(catalog.findLibrary("jjwt-impl").get())
"runtimeOnly"(catalog.findLibrary("jjwt-jackson").get())

// jjwt-impl이 내부적으로 Jackson 어노테이션 사용 - 컴파일 경고 방지
"compileOnly"(catalog.findLibrary("jackson-annotations").get())

"implementation"(catalog.findLibrary("slf4j-api").get())
}
2 changes: 1 addition & 1 deletion build-logic/src/main/kotlin/lm.java-jacoco.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ tasks.named<JacocoReport>("jacocoTestReport") {
html.required.set(true)
csv.required.set(false)
}
}
}
22 changes: 11 additions & 11 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,12 @@ tasks.register<JacocoReport>("jacocoAggregatedReport") {
group = "verification"
description = "Generates aggregated Jacoco coverage report for all subprojects"

// Configuration Phase: jacoco 플러그인이 있는 모든 서브프로젝트 선택
// (파일 존재 여부는 체크하지 않음)
// jacoco 플러그인이 적용된 서브프로젝트만 필터링
val jacocoSubprojects = subprojects.filter { it.plugins.hasPlugin("jacoco") }

// 모든 test 태스크에 의존
dependsOn(jacocoSubprojects.mapNotNull { it.tasks.findByName("test") })
// 모든 서브프로젝트의 test 태스크에 의존
dependsOn(jacocoSubprojects.map { it.tasks.named("test") })

// 소스/클래스는 Configuration Phase에서 설정 가능
additionalSourceDirs.setFrom(
jacocoSubprojects.flatMap { it.the<SourceSetContainer>()["main"].allSource.srcDirs }
)
Expand All @@ -38,12 +36,14 @@ tasks.register<JacocoReport>("jacocoAggregatedReport") {
jacocoSubprojects.flatMap { it.the<SourceSetContainer>()["main"].output }
)

// Execution Phase: 실제 존재하는 .exec 파일만 수집
executionData.setFrom(
jacocoSubprojects
.map { file("${it.layout.buildDirectory.get()}/jacoco/test.exec") }
.filter { it.exists() }
)
// fileTree는 Execution Phase에서 평가되며, 존재하지 않는 디렉토리는 무시됨
jacocoSubprojects.forEach { subproject ->
executionData.from(
fileTree(subproject.layout.buildDirectory) {
include("jacoco/test.exec")
}
)
}

reports {
xml.required.set(true)
Expand Down
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ jjwt-api = { module = "io.jsonwebtoken:jjwt-api", version.ref = "jjwt" }
jjwt-impl = { module = "io.jsonwebtoken:jjwt-impl", version.ref = "jjwt" }
jjwt-jackson = { module = "io.jsonwebtoken:jjwt-jackson", version.ref = "jjwt" }

# Jackson (Spring Boot BOM에서 버전 관리)
jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations" }

# Password
jbcrypt = { module = "org.mindrot:jbcrypt", version.ref = "jbcrypt" }

Expand Down
49 changes: 0 additions & 49 deletions qodana.yaml

This file was deleted.

2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SonarCloud Configuration
sonar.sources=core/domain/src/main/java,core/service/src/main/java,adapter/persistence/src/main/java,adapter/mongo/src/main/java,adapter/infra/src/main/java,app/api/src/main/java
sonar.sources=.
sonar.sourceEncoding=UTF-8
# Java source directories
sonar.java.source=17
Expand Down
Loading