감사 remediation 의 마지막 항목 두 개. ## 아무 데서도 안 돌던 레인 등록 태스크 97개 중 어느 CI 경로로도 도달하지 않는 것이 20개였다. 있는 줄 알았는데 안 도는 상태 — 이번에 고친 `*CleanArchitectureTest` 와 같은 종류의 문제다. 각각 판단해서 처리했고, 삭제는 0건이다. - stage 2(`integration-main.yml`, push:main + 03:00) 에 잡 3개 신설: mongo 컨테이너 레인 6개 / messaging 계약 증거 3개 / app-bootstrap integrationTest. 컨테이너가 필요한 레인은 PR 에 두지 않는다 — PR 예산은 5분이고, 단계를 나눈 이유가 이것이다 - stage 3(`release.yml`) 에 `grpc-stable-release-gate` 신설 (inprocess/netty/fault) + `app-image-release` 의 needs 로 연결 - 수동 확정 3개: `grpcPerformanceTest`, `openapiCheckSnapshot`(드리프트 검사는 이미 stage 1 의 `check` 안에 있고 이 태스크는 승인 지점), `sampleOffCompile`(stage 1 `sampleOffTest` 의 진부분집합). 전용 레지스트리 대신 루트 README 에 적었다 — `verifyReadmeCommands` 가 거기 적힌 태스크의 실재를 검증하므로, 문서가 곧 검사 대상이 된다 - 게이트 매트릭스 행 11개 신설. 잡↔행 양방향 대조 결과 68개 잡 전부 행이 있고 행 없는 잡도, 어디서도 안 도는 잡도 없다 측정이 틀린 4건은 배선하지 않았다 — 이미 도달하고 있었다: `jpaPlatformReleaseGate`(`jpaReleaseGate dependsOn`), `generateJpaEvidenceManifests`(`verifyJpaCandidateEvidence` 경유), `messagingCertificationTest`(`verifyMessagingCertificationEvidence` 경유), `stageDockerJar`(호출자가 Gradle 이 아니라 `release.yml` 의 `docker build`). ## 버전 카탈로그 이관 카탈로그를 우회해 문자열로 박혀 있던 값 11개를 `gradle/libs.versions.toml` 로 옮겼다. plugin 5개는 `[plugins]` + `alias(...)`, 툴 3개는 `libs.versions.*.get()`. `grpcVersion`/`protobufVersion`/`awsSdkVersion` 은 이관이 불가하다고 넘어온 항목이었으나, `ext.x` 를 접근자로 남기고 값만 카탈로그에서 읽으면 소비 파일 9개와 `ca.grpc-platform-module.gradle:28` 의 `findProperty` 계약이 그대로이고 해석 결과도 동일하다. **lockfile 재생성 0건.** `commons-lang3` / `netty` 는 BOM 오버라이드라 그대로 둔다 — 오버라이드하는 이유가 주석과 분리되면 값만 남고 근거가 사라진다. ## 검증 (깨끗한 체크아웃, 커밋 전) `verify-gate-matrix.sh` → 107 gates, 101 verified, drift 0 · `verify-gradle-wrapper.sh` PASS · 워크플로 YAML 21개 파싱 OK · `gradlew help` · `verifyCleanArchitectureDependencies` · `build-logic test` · `:app-bootstrap:test` **1001 tests 실패 0** · `:domain-core:check` · `verifyDocumentationContracts` · `verifyDependencyLocks` · `verifyReadmeCommands`. ## 남은 문제 mongo 6레인 · `bootstrap-integration` · messaging 매니페스트 스키마 검증은 CI 에서 한 번도 돈 적이 없다. Docker 가 없으면 실패하도록 설계돼 있으므로 **첫 main push 와 03:00 run 이 빨간 것이 정상 시나리오**다. 로컬에서 Docker 레인을 돌려보지 않았고, `mongo-container-lanes` 의 timeout 90분은 실측이 아니라 추정치다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
141 lines
8.8 KiB
TOML
141 lines
8.8 KiB
TOML
# Version catalog — every dependency version this build pins itself.
|
|
#
|
|
# Versions managed by an imported BOM are NOT here: a BOM already owns them, and restating a managed
|
|
# version would create a second answer to the same question. The BOM's own coordinate is a different
|
|
# question and it is here — `awsSdk` and `grpc` below are the versions of the BOMs themselves, which
|
|
# this build does choose. What is here is the set a module used to spell out inline, once per usage.
|
|
#
|
|
# The reason is visibility, not reproducibility — `gradle.lockfile` already fixes what resolves.
|
|
# Before this file, 59 coordinate strings were scattered across 15 build files and nothing could
|
|
# show them side by side, so two artifacts had quietly reached two versions:
|
|
#
|
|
# * spock-core 2.3-groovy-4.0 and 2.4-groovy-5.0
|
|
# * protobuf-java 4.29.3 and 4.33.2
|
|
#
|
|
# Both are kept as separate aliases rather than unified. Unifying them here would change what
|
|
# resolves, in a change whose whole purpose is that it does not; the aliases make the split
|
|
# reviewable, and whoever converges them does so deliberately with the lockfiles regenerated.
|
|
#
|
|
# Tool and plugin versions live here too. They are not dependencies of any module, so they never
|
|
# appear in a gradle.lockfile and nothing but this file can show them side by side. Four of them
|
|
# (Spring Boot, spotless, spotbugs, errorprone) were spelled out in the root `plugins {}` block, and
|
|
# three more (google-java-format, the Checkstyle tool, the SpotBugs tool) inside the shared
|
|
# `configure(subprojects)` block; the errorprone *plugin* and the errorprone *checker* it runs were
|
|
# pinned in two different files, which is exactly the pair this file exists to put next to each
|
|
# other.
|
|
#
|
|
# What is deliberately NOT here: `ext['commons-lang3.version']` and `ext['netty.version']` in
|
|
# src/build.gradle. Neither is a version this build chooses — both are overrides of a version the
|
|
# Spring Boot BOM already manages, and each is valid only next to the sentence that says what breaks
|
|
# without it (a SpotBugs worker NoClassDefFoundError, and two named CVEs on shared runtime surface).
|
|
# Moving the number here would leave the reason behind.
|
|
|
|
[versions]
|
|
approvaltests = "31.0.0"
|
|
archunit = "1.3.0"
|
|
avro = "1.12.0"
|
|
# AWS SDK v2 BOM coordinate. Imported at MODULE scope by adapter:outbound:objectstorage,
|
|
# sample-portfolio and app-bootstrap through `ext.awsSdkVersion`, which reads this key.
|
|
awsSdk = "2.30.0"
|
|
blockhound = "1.0.17.RELEASE"
|
|
# Checkstyle *tool* version (the `checkstyle` extension), not a plugin: Checkstyle is a Gradle
|
|
# built-in plugin with no coordinate of its own.
|
|
checkstyle = "13.5.0"
|
|
cloudevents = "4.0.1"
|
|
errorprone = "2.49.0"
|
|
# The Gradle plugin that runs the checker above. Two different artifacts, two different version
|
|
# lines, deliberately adjacent so a bump of one is visibly not a bump of the other.
|
|
errorpronePlugin = "5.1.0"
|
|
findsecbugs = "1.14.0"
|
|
# Spotless's google-java-format step. A formatter version is a repository-wide decision: a bump
|
|
# reformats every file.
|
|
googleJavaFormat = "1.35.0"
|
|
# io.grpc BOM. Read through `ext.grpcVersion`; adapter:inbound:grpc and the five grpc:* leaves
|
|
# import it at MODULE scope to keep the strict-locking blast radius off the shared platform.
|
|
grpc = "1.68.1"
|
|
jmh = "1.37"
|
|
jnats = "2.26.2"
|
|
jqwik = "1.9.1"
|
|
# Jackson 3 and the JSON-Schema validator share a number today by coincidence, not by
|
|
# contract; separate keys so bumping one cannot move the other.
|
|
jackson3 = "3.0.2"
|
|
jsonSchemaValidator = "3.0.2"
|
|
junitJupiter = "5.11.3"
|
|
logstashLogbackEncoder = "8.0"
|
|
okhttp = "4.12.0"
|
|
protobuf = "4.33.2"
|
|
# The third live protobuf version, and the reason this file now shows all three. adapter:inbound:grpc
|
|
# imports protobuf-bom at this major to match the gRPC BOM above; it is read through
|
|
# `ext.protobufVersion`.
|
|
protobufGrpc = "3.25.5"
|
|
# The websocket leaf's proto contract is generated against an older runtime and has not been
|
|
# requalified; see the coordinate's own comment in that leaf.
|
|
protobufLegacy = "4.29.3"
|
|
pulsarClient = "4.0.3"
|
|
resilience4j = "2.2.0"
|
|
# Two Groovy generations, deliberately not merged. See the header.
|
|
spockGroovy4 = "2.3-groovy-4.0"
|
|
spockGroovy5 = "2.4-groovy-5.0"
|
|
# SpotBugs *tool* version (the `spotbugs` extension). The plugin that runs it is spotbugsPlugin.
|
|
spotbugs = "4.10.2"
|
|
spotbugsPlugin = "6.5.6"
|
|
spotless = "8.6.0"
|
|
springBoot = "4.0.8"
|
|
springCloudContext = "4.1.4"
|
|
springDependencyManagement = "1.1.6"
|
|
springDotenv = "4.0.0"
|
|
springdoc = "3.0.0"
|
|
toxiproxy = "2.1.7"
|
|
uuidCreator = "6.1.1"
|
|
|
|
[libraries]
|
|
approvaltests = { module = "com.approvaltests:approvaltests", version.ref = "approvaltests" }
|
|
archunit-junit5 = { module = "com.tngtech.archunit:archunit-junit5", version.ref = "archunit" }
|
|
avro = { module = "org.apache.avro:avro", version.ref = "avro" }
|
|
blockhound = { module = "io.projectreactor.tools:blockhound", version.ref = "blockhound" }
|
|
cloudevents-api = { module = "io.cloudevents:cloudevents-api", version.ref = "cloudevents" }
|
|
cloudevents-core = { module = "io.cloudevents:cloudevents-core", version.ref = "cloudevents" }
|
|
errorprone-core = { module = "com.google.errorprone:error_prone_core", version.ref = "errorprone" }
|
|
findsecbugs-plugin = { module = "com.h3xstream.findsecbugs:findsecbugs-plugin", version.ref = "findsecbugs" }
|
|
jackson-databind-nullable = { module = "org.openapitools:jackson-databind-nullable", version = "0.2.6" }
|
|
jackson3-core = { module = "tools.jackson.core:jackson-core", version.ref = "jackson3" }
|
|
jackson3-databind = { module = "tools.jackson.core:jackson-databind", version.ref = "jackson3" }
|
|
jmh-core = { module = "org.openjdk.jmh:jmh-core", version.ref = "jmh" }
|
|
jmh-generator-annprocess = { module = "org.openjdk.jmh:jmh-generator-annprocess", version.ref = "jmh" }
|
|
jnats = { module = "io.nats:jnats", version.ref = "jnats" }
|
|
jqwik = { module = "net.jqwik:jqwik", version.ref = "jqwik" }
|
|
json-schema-validator = { module = "com.networknt:json-schema-validator", version.ref = "jsonSchemaValidator" }
|
|
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junitJupiter" }
|
|
logstash-logback-encoder = { module = "net.logstash.logback:logstash-logback-encoder", version.ref = "logstashLogbackEncoder" }
|
|
mockwebserver = { module = "com.squareup.okhttp3:mockwebserver", version.ref = "okhttp" }
|
|
okhttp-tls = { module = "com.squareup.okhttp3:okhttp-tls", version.ref = "okhttp" }
|
|
protobuf-java = { module = "com.google.protobuf:protobuf-java", version.ref = "protobuf" }
|
|
protobuf-java-legacy = { module = "com.google.protobuf:protobuf-java", version.ref = "protobufLegacy" }
|
|
pulsar-client = { module = "org.apache.pulsar:pulsar-client", version.ref = "pulsarClient" }
|
|
resilience4j-bulkhead = { module = "io.github.resilience4j:resilience4j-bulkhead", version.ref = "resilience4j" }
|
|
resilience4j-circuitbreaker = { module = "io.github.resilience4j:resilience4j-circuitbreaker", version.ref = "resilience4j" }
|
|
resilience4j-micrometer = { module = "io.github.resilience4j:resilience4j-micrometer", version.ref = "resilience4j" }
|
|
resilience4j-ratelimiter = { module = "io.github.resilience4j:resilience4j-ratelimiter", version.ref = "resilience4j" }
|
|
resilience4j-retry = { module = "io.github.resilience4j:resilience4j-retry", version.ref = "resilience4j" }
|
|
spock-core-groovy4 = { module = "org.spockframework:spock-core", version.ref = "spockGroovy4" }
|
|
spock-core-groovy5 = { module = "org.spockframework:spock-core", version.ref = "spockGroovy5" }
|
|
spring-cloud-context = { module = "org.springframework.cloud:spring-cloud-context", version.ref = "springCloudContext" }
|
|
spring-dotenv = { module = "me.paulschwarz:spring-dotenv", version.ref = "springDotenv" }
|
|
springdoc-openapi-starter-webmvc-api = { module = "org.springdoc:springdoc-openapi-starter-webmvc-api", version.ref = "springdoc" }
|
|
toxiproxy-java = { module = "eu.rekawek.toxiproxy:toxiproxy-java", version.ref = "toxiproxy" }
|
|
uuid-creator = { module = "com.github.f4b6a3:uuid-creator", version.ref = "uuidCreator" }
|
|
|
|
# Plugin coordinates for the root `plugins {}` block. Declared here so that a plugin version and the
|
|
# library version it governs cannot drift in two files — errorprone is the live example: the plugin
|
|
# (errorpronePlugin) and the checker jar it puts on the compile classpath (errorprone, referenced by
|
|
# libs.errorprone.core below) are now one screen apart.
|
|
#
|
|
# The convention plugins from the included build (`ca.*`) are NOT here and cannot be: an included
|
|
# build supplies the plugin itself, so there is no coordinate and no version to pin.
|
|
[plugins]
|
|
spring-boot = { id = "org.springframework.boot", version.ref = "springBoot" }
|
|
spring-dependency-management = { id = "io.spring.dependency-management", version.ref = "springDependencyManagement" }
|
|
spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }
|
|
spotbugs = { id = "com.github.spotbugs", version.ref = "spotbugsPlugin" }
|
|
errorprone = { id = "net.ltgt.errorprone", version.ref = "errorpronePlugin" }
|