Developing the Repository Infrastructure
May 2, 2026 ยท View on GitHub
This document summarizes those commands that you need to perform development tasks.
This repo is developed with IntelliJ. To initialize use:
intellij-idea-community ./
Always use the Gradle wrapper from the repository root:
- Unix:
./gradlew <task> [options] - Windows:
gradlew.bat <task> [options]
Prerequisites for most commands:
JAVA_HOMEshould be set to JDK 21 or later. GraalVM is recommended to match CI.- Docker (required for pulling/using allowed images during tests). Needs to work without
sudo:sudo usermod -aG docker $USERand reboot. grypeversion0.104.0for scanning docker images:curl -sSfL https://get.anchore.io/grype/v0.104.0/install.sh | sudo sh -s -- -b /usr/local/bin
Tip: When debugging locally, add --stacktrace for better error output.
End-to-end testing before the commit
./gradlew testAllInfra --stacktrace
To run the same coverage with future defaults enabled:
GVM_TCK_NATIVE_IMAGE_MODE=future-defaults-all ./gradlew testAllInfra --stacktrace
Style and formatting
-
To check style use
./gradlew checkstyleThis will run Checkstyle using
gradle/checkstyle.xml. -
Spotless Verifies formatting (used in release workflow prior to packaging):
./gradlew spotlessCheck -
Auto-fix license headers and formatting locally:
./gradlew spotlessApplySpotless enforces the CC0 license header on Java, Groovy, Gradle build scripts, and shell scripts. The metadata/** directory is excluded from header checks.
Testing one library locally
For a single coordinate, CI runs three steps in this order:
- Pull Docker images:
./gradlew pullAllowedDockerImages -Pcoordinates=org.postgresql:postgresql:42.7.3 - Validate index.json file integrity and schemas:
./gradlew validateIndexFiles -Pcoordinates=org.postgresql:postgresql:42.7.3 - Validate metadata:
./gradlew checkMetadataFiles -Pcoordinates=org.postgresql:postgresql:42.7.3 - Then run tests:
./gradlew test -Pcoordinates=org.postgresql:postgresql:42.7.3
To run the same coordinate with future defaults enabled:
GVM_TCK_NATIVE_IMAGE_MODE=future-defaults-all ./gradlew test -Pcoordinates=org.postgresql:postgresql:42.7.3
Testing libraries in bulk
To exercise many tests at once, you can target all coordinates or a slice of the test space via the N/M shard syntax.
All coordinates:
-
Test the whole repo:
./gradlew pullAllowedDockerImages -Pcoordinates=all ./gradlew checkMetadataFiles -Pcoordinates=all ./gradlew test -Pcoordinates=all -
Splitting the tests in batches (e.g., batch 1 of 16):
./gradlew pullAllowedDockerImages -Pcoordinates=1/16 ./gradlew checkMetadataFiles -Pcoordinates=1/16 ./gradlew test -Pcoordinates=1/16
Listing available coordinates
To print all testable GAV coordinates while honoring the same -Pcoordinates filter semantics used by the harness:
./gradlew listCoordinates -Pcoordinates=all
./gradlew listCoordinates -Pcoordinates=group:artifact
./gradlew listCoordinates -Pcoordinates=group:artifact:version
./gradlew listCoordinates -Pcoordinates=1/16
./gradlew listCoordinates -Pcoordinates=group:artifact -PstrictCoordinates=true
In GitHub Actions, this task also writes a space-separated list to the GITHUB_OUTPUT key "coordinates".
With -PstrictCoordinates=true, listCoordinates uses strict matching (getMatchingCoordinatesStrict) while keeping the same output format.
Generating dependency graphs
To print deps.dev dependency graphs for resolved GAV coordinates while honoring the same -Pcoordinates filter semantics used by the harness:
./gradlew generateDependencyGraph -Pcoordinates=all
./gradlew generateDependencyGraph -Pcoordinates=group:artifact
./gradlew generateDependencyGraph -Pcoordinates=group:artifact:version
./gradlew generateDependencyGraph -Pcoordinates=1/16
The task prints one JSON object per resolved coordinate to stdout. Each JSON object contains the root GAV in root and the transitively fetched Maven dependency graph in nodes[*].id and nodes[*].dependencies.
Testing individual stages
Each stage of the testing can be run with -Pcoordinates=[group:artifact:version|k/n|all]. Here are the examples:
./gradlew clean -Pcoordinates=[group:artifact:version|k/n|all]
./gradlew pullAllowedDockerImages -Pcoordinates=[group:artifact:version|k/n|all]
./gradlew validateIndexFiles -Pcoordinates=[group:artifact:version|k/n|all]
./gradlew checkMetadataFiles -Pcoordinates=[group:artifact:version|k/n|all]
./gradlew checkstyle -Pcoordinates=[group:artifact:version|k/n|all]
./gradlew compileTestJava -Pcoordinates=[group:artifact:version|k/n|all]
./gradlew javaTest -Pcoordinates=[group:artifact:version|k/n|all]
./gradlew nativeTestCompile -Pcoordinates=[group:artifact:version|k/n|all]
./gradlew listLibraryJars -Pcoordinates=[group:artifact:version|k/n|all]
./gradlew generateDynamicAccessReport -Pcoordinates=[group:artifact:version|k/n|all]
./gradlew generateLibraryStats -Pcoordinates=[group:artifact:version|group:artifact|k/n|all]
./gradlew validateLibraryStats
./gradlew test -Pcoordinates=[group:artifact:version|k/n|all]
Coverage (JaCoCo)
Generate coverage for the library under test exercised by our tests. Report contains coverage that focus exclusively on the provided library JARs, excluding unrelated external dependencies. Report format: XML only.
./gradlew jacocoTestReport -Pcoordinates=[group:artifact:version|k/n|all]
The root jacocoTestReport is a harness wrapper that invokes the per-project task across matching coordinates.
Native-image modes
Local runs default to current-defaults.
During the transition period, metadata CI runs both:
current-defaultsfuture-defaults-all
Select the future lane locally with GVM_TCK_NATIVE_IMAGE_MODE=future-defaults-all.
Library stats
generateLibraryStats writes exploded local stats files:
stats/<groupId>/<artifactId>/<metadata-version>/stats.json- One file per metadata-version directory
- Each local file contains the
versionsarray for that metadata-version only
Schema:
stats/schemas/library-stats-schema-v1.0.2.json
./gradlew generateLibraryStats -Pcoordinates=[group:artifact:version|group:artifact|k/n|all]
./gradlew validateLibraryStats
generateLibraryStats: recomputes selected coordinates and updates matching exploded stats files understats/.- Workflow scripts write execution metrics under
stats/<groupId>/<artifactId>/<metadata-version>/execution-metrics.json. validateLibraryStats: validates mirrored committed stats files, schema compliance, and normalized sorting without recomputing metrics.
For new-library issue triage, the repository also exposes:
./gradlew analyzeExternalLibraryDynamicAccess --coordinates=group:artifact:version
This resolves the requested library, runs Native Image with Preserve and TrackDynamicAccess, and prints a JSON summary suitable for issue comments.
Generating Metadata
Generates metadata for a single library coordinate. If agentAllowedPackages is provided, a new user-code-filter.json will be created or updated from those packages or from package roots derived from the resolved library JAR.
coordinates: group:artifact:version (single coordinate only)agentAllowedPackages: comma-separated package list,fromJar, or-for none
Examples:
./gradlew generateMetadata -Pcoordinates=org.postgresql:postgresql:42.7.3
./gradlew generateMetadata -Pcoordinates=org.postgresql:postgresql:42.7.3 --agentAllowedPackages=fromJar
./gradlew generateMetadata -Pcoordinates=org.postgresql:postgresql:42.7.3 --agentAllowedPackages=org.example.app,com.acme.service
Native metadata tracing and exact verification
These tasks use Native Image runtime metadata tracing. They require a GraalVM build that supports -H:+MetadataTracingSupport, -XX:TraceMetadata, and -XX:TraceMetadataConditionPackages.
Build a trace-enabled native test image:
./gradlew nativeTraceImage -Pcoordinates=<group:artifact:version>
Run the trace-enabled binary once and write runtime trace metadata. The trace binary is built with -H:+MetadataTracingSupport, --exact-reachability-metadata, and -H:MissingRegistrationReportingMode=Exit, so it exits with ExitStatus.MISSING_METADATA (172) when an access misses the supplied metadata. The Gradle Exec ignores the binary's exit code so the trace output can still be inspected or merged after a 172 exit; pass -PtraceBinaryExitFile=<absolute-path> to capture the exit code in a sentinel file (used by automated callers like the verification gate).
./gradlew runNativeTraceImage \
-Pcoordinates=<group:artifact:version> \
-PtraceMetadataPath=<absolute-trace-output-dir> \
-PtraceMetadataConditionPackages=<package1,package2,...>
Always write traces to a temporary directory, not to metadata/<group>/<artifact>/<version>. The trace output may be partial when the native test fails. Merge one or more trace output directories with:
./gradlew mergeNativeTraceMetadata \
-PinputDirs=<absolute-trace-output-dir-0>,<absolute-trace-output-dir-1>,... \
-PoutputDir=<absolute-merged-metadata-dir>
Rebuild with merged metadata for another tracing iteration:
./gradlew nativeTraceImage \
-Pcoordinates=<group:artifact:version> \
-PmetadataConfigDirs=<absolute-merged-metadata-dir>
Splitting test-only metadata
Moves test-only entries from library reachability-metadata.json in metadata/, into the corresponding test resources metadata file.
Examples:
./gradlew splitTestOnlyMetadata -Pcoordinates=org.postgresql:postgresql:42.7.3
./gradlew splitTestOnlyMetadata -Pcoordinates=org.postgresql:postgresql
./gradlew splitTestOnlyMetadata -Pcoordinates=1/16
Fix failing tasks
Use this when a library's new version causes native-image run test failures. The task will:
- Update the artifact's metadata index.json to mark the new version as latest
- Ensure the tests project has an agent block and a user-code-filter.json if missing
- Run the agent to collect metadata, then re-run tests (with a retry if needed)
Required properties:
- -PtestLibraryCoordinates=group:artifact:version (coordinates of an existing tested version whose tests you run)
- -PnewLibraryVersion=version (the new upstream version number only; do not include group or artifact)
Example:
./gradlew fixTestNativeImageRun -PtestLibraryCoordinates=org.postgresql:postgresql:42.7.3 -PnewLibraryVersion=42.7.4
Docker image vulnerability scanning
-
Scan only images affected in a commit range:
./gradlew checkAllowedDockerImages --baseCommit=$(git rev-parse origin/master) --newCommit=$(git rev-parse HEAD) -
Scan all allowed images
./gradlew checkAllowedDockerImages
Compatibility automation with latest library versions
These tasks support the scheduled workflow that checks newer upstream library versions and updates our metadata accordingly.
-
List supported libraries that have newer upstream versions
./gradlew fetchExistingLibrariesWithNewerVersions --quiet -
Mark a new tested version for a library
./gradlew addTestedVersion -Pcoordinates="group:artifact:newVersion" --lastSupportedVersion="oldVersion"For example:
./gradlew addTestedVersion -Pcoordinates="org.postgresql:postgresql:42.7.4" --lastSupportedVersion="42.7.3"
Releases and Packaging
./gradlew package
Quick reference (copy/paste)
- Style:
./gradlew checkstyle - Format check:
./gradlew spotlessCheck - Format apply:
./gradlew spotlessApply - Pull images (single lib):
./gradlew pullAllowedDockerImages -Pcoordinates=[group:artifact:version|k/n|all] - Check metadata (single lib):
./gradlew checkMetadataFiles -Pcoordinates=[group:artifact:version|k/n|all] - Generate metadata (single lib):
./gradlew generateMetadata -Pcoordinates=group:artifact:version - Build trace-enabled native image:
./gradlew nativeTraceImage -Pcoordinates=group:artifact:version - Run trace-enabled native image:
./gradlew runNativeTraceImage -Pcoordinates=group:artifact:version -PtraceMetadataPath=<absolute-trace-output-dir> -PtraceMetadataConditionPackages=<package1,package2,...> - Merge native trace metadata:
./gradlew mergeNativeTraceMetadata -PinputDirs=<absolute-trace-output-dir-0>,<absolute-trace-output-dir-1>,... -PoutputDir=<absolute-merged-metadata-dir> - Split test-only metadata:
./gradlew splitTestOnlyMetadata -Pcoordinates=[group:artifact:version|group:artifact|k/n|all] - Fix test that fails Native Image run for new library version:
./gradlew fixTestNativeImageRun -PtestLibraryCoordinates=group:artifact:version -PnewLibraryVersion=version - Test (single lib):
./gradlew test -Pcoordinates=[group:artifact:version|k/n|all] - List resolved tested-library jars:
./gradlew listLibraryJars -Pcoordinates=[group:artifact:version|k/n|all] - Generate dynamic access report:
./gradlew generateDynamicAccessReport -Pcoordinates=[group:artifact:version|k/n|all] - Generate dynamic access coverage report:
./gradlew generateDynamicAccessCoverageReport -Pcoordinates=[group:artifact:version|k/n|all]Output:metadata/<group>/<artifact>/<version>/test/build/reports/dynamic-access/dynamic-access-coverage.jsonJSON top-level fields:coordinate,hasDynamicAccess,totals,classes - Coverage (single lib):
./gradlew jacocoTestReport -Pcoordinates=[group:artifact:version|k/n|all] - Generate library stats:
./gradlew generateLibraryStats -Pcoordinates=[group:artifact:version|group:artifact|k/n|all] - Validate library stats:
./gradlew validateLibraryStats - List available coordinates:
./gradlew listCoordinates -Pcoordinates=[group:artifact:version|group:artifact|k/n|all] [-PstrictCoordinates=true] - Generate dependency graph:
./gradlew generateDependencyGraph -Pcoordinates=[group:artifact:version|group:artifact|k/n|all] - Analyze external dynamic access:
./gradlew analyzeExternalLibraryDynamicAccess --coordinates=group:artifact:version - Scan changed Docker images:
./gradlew checkAllowedDockerImages --baseCommit=<sha1> --newCommit=<sha2> - Scan all Docker images:
./gradlew checkAllowedDockerImages - List libs with newer versions:
./gradlew fetchExistingLibrariesWithNewerVersions --quiet - Record a newly tested version:
./gradlew addTestedVersion -Pcoordinates="group:artifact:newVersion" --lastSupportedVersion="oldVersion" - Package release artifacts:
./gradlew package