Skip to content

Complete Spring Boot 4 and Java 25 migration (#4) #28

Complete Spring Boot 4 and Java 25 migration (#4)

Complete Spring Boot 4 and Java 25 migration (#4) #28

name: CodeQL verification
on:
pull_request:
branches:
- main
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
concurrency:
group: distributed-cache-codeql-${{ github.ref }}
cancel-in-progress: false
jobs:
analyze:
runs-on: ubuntu-24.04
timeout-minutes: 120
steps:
- name: Check out candidate
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Install verified Temurin LTS JDK
shell: bash
env:
JDK_URL: https://github.com/adoptium/temurin25-binaries/releases/download/jdk-25.0.4.1%2B1/OpenJDK25U-jdk_x64_linux_hotspot_25.0.4.1_1.tar.gz
JDK_SHA256: dbb698396d478e7fa2b1e50f4103324b2a99b90569ee27c33f2261f9215cf41e
run: |
set -euo pipefail
archive="$RUNNER_TEMP/temurin-jdk.tar.gz"
java_home="$RUNNER_TEMP/temurin-jdk"
curl --proto '=https' --tlsv1.2 --fail --silent --show-error --location \
--output "$archive" "$JDK_URL"
printf '%s %s\n' "$JDK_SHA256" "$archive" | sha256sum -c -
mkdir -p "$java_home"
tar -xzf "$archive" -C "$java_home" --strip-components=1
printf 'JAVA_HOME=%s\n' "$java_home" >> "$GITHUB_ENV"
printf '%s/bin\n' "$java_home" >> "$GITHUB_PATH"
"$java_home/bin/java" -version
- name: Install pinned evidence verifier runtime
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.14.7'
check-latest: false
update-environment: true
- name: Verify source and wrapper integrity
shell: bash
run: |
set -euo pipefail
test -z "$(git status --porcelain)"
test "$(git rev-parse 520a6d217e8809bd2a0d44ecbae5a8bcdb958b2c^{commit})" = \
520a6d217e8809bd2a0d44ecbae5a8bcdb958b2c
git merge-base --is-ancestor 520a6d217e8809bd2a0d44ecbae5a8bcdb958b2c HEAD
grep -Fxq 'distributionSha256Sum=5af3b743dd8b876b5c45da33b676251e5f1687712644abb4ee519ca56e1d89ce' \
.mvn/wrapper/maven-wrapper.properties
test "$(python --version)" = 'Python 3.14.7'
- name: Initialize CodeQL
uses: github/codeql-action/init@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8
with:
languages: java-kotlin
build-mode: manual
config: |
queries:
- uses: security-extended
threat-models: local
- name: Build complete affected module graph
shell: bash
run: |
set -euo pipefail
./mvnw -B \
-pl hazelcast,hazelcast-build-utils,hazelcast-sql,extensions/cdc-debezium,extensions/mongodb \
-am \
-DskipTests \
-Dcheckstyle.skip=true \
-Dlicense.skip=true \
-Dmaven.compiler.fork=false \
-Dkotlin.compiler.daemon=false \
-Dassembly.skipAssembly=true \
test-compile
- name: Analyze without publishing temporary alerts
uses: github/codeql-action/analyze@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8
with:
category: '/language:java-kotlin'
upload: never
output: codeql-results
- name: Reject Critical and High findings
shell: bash
run: |
set -euo pipefail
python3 - <<'PY'
import glob
import json
blocked = []
unresolved = []
total = 0
for path in glob.glob('codeql-results/**/*.sarif', recursive=True):
with open(path, encoding='utf-8') as stream:
sarif = json.load(stream)
for run in sarif.get('runs', []):
driver_rules = {
rule.get('id'): rule
for rule in run.get('tool', {}).get('driver', {}).get('rules', [])
}
extension_rules = [
{
rule.get('id'): rule
for rule in extension.get('rules', [])
}
for extension in run.get('tool', {}).get('extensions', [])
]
for result in run.get('results', []):
total += 1
rule_id = result.get('ruleId')
rule = None
component_index = (
result.get('rule', {})
.get('toolComponent', {})
.get('index')
)
if component_index is not None and component_index < len(extension_rules):
rule = extension_rules[component_index].get(rule_id)
if rule is None:
rule = driver_rules.get(rule_id)
if rule is None:
rule = next(
(rules.get(rule_id) for rules in extension_rules if rule_id in rules),
None,
)
if rule is None:
unresolved.append((rule_id, 'missing rule metadata'))
continue
try:
score = float(rule.get('properties', {}).get('security-severity', '0'))
except (TypeError, ValueError):
unresolved.append((rule_id, 'invalid security severity'))
continue
if score >= 7.0:
location = result.get('locations', [{}])[0].get('physicalLocation', {})
blocked.append((
rule_id,
score,
location.get('artifactLocation', {}).get('uri', 'unknown'),
location.get('region', {}).get('startLine', 0),
))
print(f'codeql_total={total}')
print(f'codeql_critical_high={len(blocked)}')
print(f'codeql_unresolved_rule_metadata={len(unresolved)}')
for rule_id, score, path, line in blocked:
print(f'{rule_id}\t{score}\t{path}:{line}')
for rule_id, reason in unresolved:
print(f'{rule_id}\t{reason}')
if blocked or unresolved:
raise SystemExit(1)
PY
- name: Upload verification evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: distributed-cache-codeql-${{ github.sha }}
path: codeql-results/
if-no-files-found: error
retention-days: 7
compression-level: 9
include-hidden-files: false