refactor: 각 어댑터터별 리펙토링 진행
This commit is contained in:
@@ -27,8 +27,15 @@ readonly MATRIX="${REPO_ROOT}/.github/ci-gate-matrix.yml"
|
||||
# Deliberately a literal: a gate silently appearing or disappearing is the drift this lint exists to
|
||||
# catch, so growing the matrix is an explicit edit here. 38 as of the HTTP Client platform hardening,
|
||||
# which registered httpclient-spring62-runtime as a delegated-pending control — the 6.2 *runtime*
|
||||
# claim, distinct from the API-surface scan that was standing in for it.
|
||||
readonly EXPECTED_GATE_COUNT=38
|
||||
# claim, distinct from the API-surface scan that was standing in for it. 40 after the Gradle
|
||||
# convention wave registered documented-leaf-count and declared-dependency-absence, then 46 after
|
||||
# the final qualification wave registered the four notification/runbook gates that existed but ran
|
||||
# nowhere and the two API-surface gates the convention had already wired into check. 48 once the
|
||||
# Compose runtime matrix and the GraphQL runtime JWT claim were registered as delegated-pending —
|
||||
# both are real and neither runs in CI. 49 once the messaging broker certification lane registered
|
||||
# its evidence gate — the first control in this repository whose subject is not "did the tests pass"
|
||||
# but "is the committed evidence what the run produced".
|
||||
readonly EXPECTED_GATE_COUNT=49
|
||||
|
||||
if [[ ! -f "${MATRIX}" ]]; then
|
||||
printf '::error::gate-matrix-lint: missing %s\n' "${MATRIX}" >&2
|
||||
@@ -135,6 +142,25 @@ gradle_custom_task_is_registered_in_build_file() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
# A lane declared through the `ca.strict-test-lane` convention. The convention exists because the
|
||||
# five lines every lane used to repeat were copied per lane and per leaf, and two copies had
|
||||
# already lost `failOnNoDiscoveredTests`; registering through it is still registering, so this lint
|
||||
# has to recognise the declaration or it reports every converted lane as missing.
|
||||
if grep -qsE -- "lane\\(['\"]${task_name}['\"]\\)" "${build_file}"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# An API surface gate declared through the `ca.api-surface` convention, which derives every task
|
||||
# name from one label so a leaf cannot verify one surface while telling the reader about another.
|
||||
# The name is computed, so there is no literal `tasks.register('verifyMongoApiSurface')` anywhere;
|
||||
# what the build file says is `apiSurface { label = 'Mongo' }`.
|
||||
if [[ "${task_name}" =~ ^verify(.+)ApiSurface$ ]]; then
|
||||
local surface_label="${BASH_REMATCH[1]}"
|
||||
if grep -qsE -- "label[[:space:]]*=[[:space:]]*['\"]${surface_label}['\"]" "${build_file}"; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
awk -v required_task="${task_name}" '
|
||||
index($0, "registerStrictQualificationTest(") > 0 { inside_registration=1 }
|
||||
inside_registration && /^[[:space:]]*name:[[:space:]]*/ {
|
||||
@@ -159,14 +185,64 @@ gradle_custom_task_is_registered_in_build_file() {
|
||||
' "${build_file}"
|
||||
}
|
||||
|
||||
# Every `dependsOn ... named('x')` in the build, collected once.
|
||||
#
|
||||
# This used to be one recursive grep per gate. That was affordable at 38 gates and stopped being so
|
||||
# at 48: the whole lint crossed the ten-second budget its own contract test asserts, and the first
|
||||
# symptom was that test failing rather than anything about gate coverage. One pass, then membership
|
||||
# tests against the result.
|
||||
CHECK_WIRING_CACHE=""
|
||||
load_check_wiring() {
|
||||
[[ -n "${CHECK_WIRING_CACHE}" ]] && return 0
|
||||
CHECK_WIRING_CACHE="$(grep -RhoE -- "dependsOn[^\n]*named\((['\"])[A-Za-z0-9_.-]+\1\)" \
|
||||
"${REPO_ROOT}/src" --include='build.gradle' --include='ca.*.gradle' 2>/dev/null \
|
||||
| grep -oE "(['\"])[A-Za-z0-9_.-]+\1" | tr -d "\"'" | sort -u)"
|
||||
# A build with no such wiring at all would leave this empty and make every membership test pass by
|
||||
# vacuity, so an empty result is a marker rather than an answer.
|
||||
[[ -z "${CHECK_WIRING_CACHE}" ]] && CHECK_WIRING_CACHE="<none>"
|
||||
return 0
|
||||
}
|
||||
|
||||
gradle_custom_task_wired_into_check() {
|
||||
local task_name="$1"
|
||||
load_check_wiring
|
||||
if printf '%s\n' "${CHECK_WIRING_CACHE}" | grep -qxF -- "${task_name}"; then
|
||||
return 0
|
||||
fi
|
||||
# `ca.api-surface` wires check as `dependsOn tasks.named(verifyName())`, where verifyName() is
|
||||
# derived from the leaf's label. The declaration that makes the gate real is the label, so that is
|
||||
# what proves the wiring — the convention has exactly one check wiring and it is unconditional.
|
||||
if [[ "${task_name}" =~ ^verify(.+)ApiSurface$ ]]; then
|
||||
local surface_label="${BASH_REMATCH[1]}"
|
||||
if grep -RqsE -- "label[[:space:]]*=[[:space:]]*['\"]${surface_label}['\"]" "${REPO_ROOT}/src" \
|
||||
--include='build.gradle' \
|
||||
&& grep -qsE -- "dependsOn tasks\.named\(verifyName\(\)\)" \
|
||||
"${REPO_ROOT}/src/build-logic/src/main/groovy/ca.api-surface.gradle"; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# The build files, found once rather than once per gate. Same reason as the wiring cache above: the
|
||||
# per-gate `find` was a fixed cost multiplied by a number that grew.
|
||||
GRADLE_FILE_CACHE=""
|
||||
load_gradle_files() {
|
||||
[[ -n "${GRADLE_FILE_CACHE}" ]] && return 0
|
||||
GRADLE_FILE_CACHE="$(find "${REPO_ROOT}/src" -type f -name '*.gradle' | sort)"
|
||||
return 0
|
||||
}
|
||||
|
||||
gradle_custom_task_is_registered() {
|
||||
local task_name="$1"
|
||||
local build_file
|
||||
while IFS= read -r -d '' build_file; do
|
||||
load_gradle_files
|
||||
while IFS= read -r build_file; do
|
||||
[[ -z "${build_file}" ]] && continue
|
||||
if gradle_custom_task_is_registered_in_build_file "${task_name}" "${build_file}"; then
|
||||
return 0
|
||||
fi
|
||||
done < <(find "${REPO_ROOT}/src" -type f -name '*.gradle' -print0)
|
||||
done <<< "${GRADLE_FILE_CACHE}"
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -325,9 +401,16 @@ while IFS=$'\t' read -r id blocking mechanism ref workflow job execution; do
|
||||
failures+=("gate '${id}' expects Gradle check in job '${job}'")
|
||||
continue
|
||||
fi
|
||||
# Build files *and* convention plugins. A gate can now be wired into check from an included
|
||||
# build's convention rather than from a leaf's build.gradle, and a lint that only reads
|
||||
# build.gradle would call such a gate unwired while it runs on every leaf — a false failure
|
||||
# that teaches the next author to delete the matrix row instead of trusting it.
|
||||
#
|
||||
# A convention that derives the task name from a label wires check by that derived name, so
|
||||
# there is no literal to grep for either; `gradle_custom_task_wired_into_check` handles both
|
||||
# the literal and the derived form.
|
||||
if [[ "${mechanism}" == "gradle-custom-task" ]] \
|
||||
&& ! grep -RqsE -- "dependsOn.*named\\(['\"]${ref}['\"]\\)" "${REPO_ROOT}/src" \
|
||||
--include='build.gradle'; then
|
||||
&& ! gradle_custom_task_wired_into_check "${ref}"; then
|
||||
failures+=("gate '${id}' task '${ref}' exists but is not wired into Gradle check")
|
||||
continue
|
||||
fi
|
||||
|
||||
@@ -27,11 +27,12 @@ readonly EXPECTED_WORKFLOW_LOCK=(
|
||||
'3be84c9f15fa3b2ac5a085f8d725ec6d05e7007ae0b433da9e79b3bf340d57ea .github/workflows/jpa-next-hibernate8.yml'
|
||||
'a2b74bfb3af12d6d03cd2ea8a5e48490dd131afb89b79694d498c5798387ac53 .github/workflows/jpa-next-jpa4.yml'
|
||||
'cd955ef4af895df477896dad9577810f010b2beea8570b09b008f9e94e928bd0 .github/workflows/jpa-next-postgresql19.yml'
|
||||
'b56b548a867b74eaeccb42e7df4f4e52cf7ce657ab27f91e2c8d7ea9944d64af .github/workflows/jpa-nightly.yml'
|
||||
'21e065880ef5d4c4ff973f52d8107ef08398ebaf9518ec6b2fd82d49c5d822c6 .github/workflows/jpa-nightly.yml'
|
||||
'04851f44ba94533bfbc8fabe2b3a2b408726a9996e86ed3864986d1499d16b50 .github/workflows/jpa-pr.yml'
|
||||
'59cb3a0ffc687a15eefe96bc5e3a70d42be78e1cc85d2e7f7880dac6124ca4c7 .github/workflows/jpa-r2-evidence.yml'
|
||||
'4748f2ba0a0b77dc1a858ebcfa7db6e41627d97843df5f0aa978bc2facccaad2 .github/workflows/jpa-release.yml'
|
||||
'cf4f80134197dd6d7dc177f0d21294a6b9ffe8709be67d05089f7ff0ce6c9429 .github/workflows/jpa-release.yml'
|
||||
'5be7e931db749029d89787da042d6d7cf8e683d60698bd8a2993c29db26355fb .github/workflows/link-check.yml'
|
||||
'8adafc59a2d87a6c65ef94b4726d7d036ac81b150ed3d301578308e6f9a3523f .github/workflows/messaging-certification.yml'
|
||||
'4e4ccfa267ecd63b9369803d49f2dbdb2fa899517ad4cf23ab11d29104557a91 .github/workflows/notification-platform.yml'
|
||||
'64245586cd5936f1a5647b57f2cd9acd316f96fd75f713b1890decb812e7d5fe .github/workflows/object-storage-qualification.yml'
|
||||
'cbc104ea486c746229895e804e3be7716e056a02cce0588c537bce9f442f8b38 .github/workflows/redis-sdk-topology.yml'
|
||||
|
||||
Reference in New Issue
Block a user