Files
llm-wiki/raw/errors/gradle-custom-source-set-isolation-failures-2026-06-25.md

46 lines
2.2 KiB
Markdown

---
title: Gradle custom source set isolation failures
source_type: error-note
status: raw
tags: [gradle, test-source-set, sample-off, archunit, ca-skeleton]
created: 2026-06-25
---
# Gradle custom source set isolation failures
## Parent
- [[raw/branch-notes/feature-sample-removal-adoption-contract]]
## Symptom
`app-bootstrap`에 sample 없는 검증 축을 추가하기 위해 `sampleOffTest` source set/task를 만들자 단일 원인이 아니라 여러 tooling 경계가 순차적으로 실패했다.
## Causes
- Strict dependency locking은 새 configuration마다 lock state가 필요하다.
- Custom test source set은 `main` output을 명시하지 않으면 테스트 컴파일/실행 classpath가 일반 `test`와 달라진다.
- ArchUnit `ImportOption.DoNotIncludeTests`는 Gradle 기본 test output은 제외하지만 custom `sampleOffTest` output은 production class처럼 import할 수 있다.
- sample을 제거하면 일부 ArchUnit 규칙은 빈 corpus가 되어 `allowEmptyShould(true)`가 필요할 수 있다.
- MVC slice smoke는 core controller를 명시 import하지 않으면 sample-off classpath에서 404가 날 수 있다.
- `check`가 custom source set의 checkstyle/spotbugs task까지 전이 실행하면, 테스트 fixture용 스타일 위반이 release gate를 과도하게 막을 수 있다.
## Fix
- `resolveAndLockAll --write-locks``gradle.lockfile` 갱신.
- `sampleOffTest``sourceSets.main.output` 포함.
- `ProductionClassImportOption`으로 기본 test output과 `sampleOffTest` output을 모두 제외.
- sample 없는 corpus가 정상인 계약에는 `allowEmptyShould(true)` 적용.
- `/healthcheck` smoke에 `HealthcheckController` 명시 import.
- `checkstyleSampleOffTest`/`spotbugsSampleOffTest`는 warning-only policy로 두고, 실제 release-blocking sample-off 계약은 `sampleOffTest`에 둠.
## Verification
- `./gradlew :app-bootstrap:sampleOffTest --no-daemon`
- `./gradlew check verifyPublicPathSnapshot --no-daemon`
- `bash .github/scripts/verify-gate-matrix.sh`
## Prevention
Custom source set은 dependency graph만이 아니라 compile output, static-analysis task, ArchUnit import option, empty-corpus semantics까지 함께 설계한다.