From c6f75d4de25586c5ebabe4ea8f3b275cd57e7d20 Mon Sep 17 00:00:00 2001 From: jvukicev Date: Wed, 3 Dec 2025 15:36:04 +0100 Subject: [PATCH 1/9] Add initial schemas --- .../metadata-library-index-schema-v1.0.0.json | 100 ++++++++++++++++++ .../metadata-root-index-schema-v1.0.0.json | 61 +++++++++++ .../metadata-version-index-schema-v1.0.0.json | 35 ++++++ 3 files changed, 196 insertions(+) create mode 100644 docs/schemas/metadata-library-index-schema-v1.0.0.json create mode 100644 docs/schemas/metadata-root-index-schema-v1.0.0.json create mode 100644 docs/schemas/metadata-version-index-schema-v1.0.0.json diff --git a/docs/schemas/metadata-library-index-schema-v1.0.0.json b/docs/schemas/metadata-library-index-schema-v1.0.0.json new file mode 100644 index 000000000..be07451cb --- /dev/null +++ b/docs/schemas/metadata-library-index-schema-v1.0.0.json @@ -0,0 +1,100 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/oracle/graalvm-reachability-metadata/schemas/metadata-library-index.schema.json", + "description": "Schema for metadata///index.json. Each entry describes a metadata bundle for a range of library versions.", + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "module", + "metadata-version", + "tested-versions" + ], + "properties": { + "module": { + "$ref": "#/$defs/moduleCoordinate", + "description": "Maven coordinates in the form ':'." + }, + "metadata-version": { + "type": "string", + "minLength": 1, + "description": "Subdirectory name where the metadata files for this entry reside, e.g. '7.1.0.Final'." + }, + "tested-versions": { + "type": "array", + "description": "Explicitly tested upstream library versions that this metadata is known to support.", + "minItems": 1, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1 + } + }, + "latest": { + "type": "boolean", + "description": "Marks this entry as the latest/default metadata for currently supported versions." + }, + "default-for": { + "type": "string", + "description": "Java regular expression describing the version range for which this entry should be used by default (e.g. '7\\\\.1\\\\..*')." + }, + "override": { + "type": "boolean", + "description": "When true, expresses the intent to exclude outdated built-in metadata shipped with Native Image for the matched versions." + }, + "skipped-versions": { + "type": "array", + "description": "Versions explicitly excluded from support, each with a reason.", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ "version", "reason" ], + "properties": { + "version": { + "type": "string", + "minLength": 1 + }, + "reason": { + "type": "string", + "minLength": 1 + } + } + } + } + } + }, + "$defs": { + "moduleCoordinate": { + "type": "string", + "pattern": "^[^:]+:[^:]+$" + } + }, + "examples": [ + [ + { + "metadata-version": "0.0.1", + "module": "org.example:library", + "tested-versions": [ "0.0.1", "0.0.2" ], + "default-for": "0\\.0\\..*" + }, + { + "latest": true, + "metadata-version": "1.0.0", + "module": "org.example:library", + "tested-versions": [ "1.0.0", "1.1.0-M1", "1.1.0" ] + }, + { + "metadata-version": "1.19.0", + "module": "io.opentelemetry:opentelemetry-exporter-logging", + "tested-versions": [ "1.19.0" ], + "override": true, + "skipped-versions": [ + { "version": "1.0.5", "reason": "Known incompatible API change." } + ] + } + ] + ] +} diff --git a/docs/schemas/metadata-root-index-schema-v1.0.0.json b/docs/schemas/metadata-root-index-schema-v1.0.0.json new file mode 100644 index 000000000..07ffae34b --- /dev/null +++ b/docs/schemas/metadata-root-index-schema-v1.0.0.json @@ -0,0 +1,61 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/oracle/graalvm-reachability-metadata/schemas/metadata-root-index.schema.json", + "description": "Schema for metadata/index.json. This file lists modules known to the repository and optionally the directory where their metadata is stored, the allowed package prefixes for metadata, and inter-module requirements. See docs/CONTRIBUTING.md (Metadata structure).", + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["module"], + "properties": { + "module": { + "$ref": "#/$defs/moduleCoordinate", + "description": "Maven coordinates for the module in the form ':'." + }, + "directory": { + "type": "string", + "minLength": 1, + "pattern": "^[^\\s].*$", + "description": "Repository-relative path under 'metadata/' containing this module's metadata (e.g. 'org.example/library'). If omitted, the entry may reference requirements only." + }, + "allowed-packages": { + "type": "array", + "description": "List of package (or fully-qualified name) prefixes considered valid sources of metadata entries for this module. Used to filter-in relevant JSON entries.", + "minItems": 1, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1 + } + }, + "requires": { + "type": "array", + "description": "Optional list of module coordinates this module depends on. Each item is ':'.", + "minItems": 1, + "uniqueItems": true, + "items": { + "$ref": "#/$defs/moduleCoordinate" + } + } + } + }, + "$defs": { + "moduleCoordinate": { + "type": "string", + "pattern": "^[^:]+:[^:]+$" + } + }, + "examples": [ + [ + { + "directory": "org.example/library", + "module": "org.example:library" + }, + { + "module": "org.example:dependant-library", + "requires": ["org.example:library"], + "allowed-packages": ["org.package.name"] + } + ] + ] +} diff --git a/docs/schemas/metadata-version-index-schema-v1.0.0.json b/docs/schemas/metadata-version-index-schema-v1.0.0.json new file mode 100644 index 000000000..cb2f3a637 --- /dev/null +++ b/docs/schemas/metadata-version-index-schema-v1.0.0.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/oracle/graalvm-reachability-metadata/schemas/metadata-version-index.schema.json", + "description": "Schema for metadata////index.json. Enumerates only allowed config JSON files contained in that metadata-version directory.", + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "type": "string", + "enum": [ + "jni-config.json", + "proxy-config.json", + "reflect-config.json", + "resource-config.json", + "serialization-config.json" + ], + "description": "Allowed metadata config filenames contained in the version directory." + }, + "examples": [ + [ + "proxy-config.json", + "reflect-config.json", + "resource-config.json" + ], + [ + "reflect-config.json", + "resource-config.json", + "serialization-config.json" + ], + [ + "jni-config.json", + "reflect-config.json" + ] + ] +} From ed195f78ca95a22ee4db040f2e0b1f775dc3ec19 Mon Sep 17 00:00:00 2001 From: jvukicev Date: Thu, 4 Dec 2025 14:22:23 +0100 Subject: [PATCH 2/9] Add initial test index schemas, and move and add version to library-and-framework-list-schema --- .../library-and-framework-list-validation.yml | 2 +- docs/CONTRIBUTING.md | 2 +- ...rary-and-framework-list-schema-v1.0.0.json | 0 .../tests-project-index-schema-v1.0.0.json | 30 ++++++++ .../tests-root-index-schema-v1.0.0.json | 70 +++++++++++++++++++ 5 files changed, 102 insertions(+), 2 deletions(-) rename library-and-framework-list-schema.json => docs/schemas/library-and-framework-list-schema-v1.0.0.json (100%) create mode 100644 docs/schemas/tests-project-index-schema-v1.0.0.json create mode 100644 docs/schemas/tests-root-index-schema-v1.0.0.json diff --git a/.github/workflows/library-and-framework-list-validation.yml b/.github/workflows/library-and-framework-list-validation.yml index 70343b417..3d6e0d671 100644 --- a/.github/workflows/library-and-framework-list-validation.yml +++ b/.github/workflows/library-and-framework-list-validation.yml @@ -43,4 +43,4 @@ jobs: if: steps.filter.outputs.changed == 'true' run: | pip install check-jsonschema - check-jsonschema --schemafile library-and-framework-list-schema.json library-and-framework-list.json + check-jsonschema --schemafile docs/schemas/library-and-framework-list-schema-v1.0.0.json library-and-framework-list.json diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index f52b8d6b0..5339146eb 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -344,4 +344,4 @@ Where: **Note:** To pass format and style checks, please run `sorted="$(jq -s '.[] | sort_by(.artifact)' library-and-framework-list.json)" && echo -E "${sorted}" > library-and-framework-list.json` before submitting a PR. -**Note:** The entries you add will be validated against [library-and-framework-list-schema.json](https://github.com/oracle/graalvm-reachability-metadata/blob/master/library-and-framework-list-schema.json) +**Note:** The entries you add will be validated against [library-and-framework-list-schema-v1.0.0.json](https://github.com/oracle/graalvm-reachability-metadata/blob/master/library-and-framework-list-schema-v1.0.0.json) diff --git a/library-and-framework-list-schema.json b/docs/schemas/library-and-framework-list-schema-v1.0.0.json similarity index 100% rename from library-and-framework-list-schema.json rename to docs/schemas/library-and-framework-list-schema-v1.0.0.json diff --git a/docs/schemas/tests-project-index-schema-v1.0.0.json b/docs/schemas/tests-project-index-schema-v1.0.0.json new file mode 100644 index 000000000..4702514c0 --- /dev/null +++ b/docs/schemas/tests-project-index-schema-v1.0.0.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/oracle/graalvm-reachability-metadata/docs/schemas/tests-project-index-schema-v1.0.0.json", + "title": "Test Project Index", + "description": "Schema for tests/src////index.json. This file optionally customizes the test invocation via 'test-command'. If omitted or if the property is not present, a default command will be used (gradlew nativeTest with environment overrides) per TestInvocationTask.", + "type": "object", + "additionalProperties": false, + "properties": { + "test-command": { + "type": "array", + "description": "Command line to run for this test project. Supports template parameters: , , , .", + "minItems": 1, + "items": { + "type": "string", + "minLength": 1, + "description": "Part of the command line. May include template parameters like , , , ." + } + } + }, + "examples": [ + { + "test-command": [ + "gradle", + "nativeTest", + "-Pmetadata.dir=", + "-Plibrary.version=" + ] + } + ] +} diff --git a/docs/schemas/tests-root-index-schema-v1.0.0.json b/docs/schemas/tests-root-index-schema-v1.0.0.json new file mode 100644 index 000000000..3d8ec8e4c --- /dev/null +++ b/docs/schemas/tests-root-index-schema-v1.0.0.json @@ -0,0 +1,70 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/oracle/graalvm-reachability-metadata/docs/schemas/tests-root-index-schema-v1.0.0.json", + "title": "Tests Root Index", + "description": "Schema for tests/src/index.json mapping test projects to libraries and versions (see docs/CONTRIBUTING.md).", + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ "test-project-path", "libraries" ], + "properties": { + "test-project-path": { + "type": "string", + "minLength": 1, + "pattern": "^[^\\s/]+/[^\\s/]+/[^\\s/]+$", + "description": "Path under tests/src: // (e.g. 'org.example/library/1.0.0' or 'samples/docker/image-pull')." + }, + "libraries": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ "name", "versions" ], + "properties": { + "name": { + "type": "string", + "pattern": "^[^:]+:[^:]+$", + "description": "Library coordinates in the form ':' (e.g. 'org.example:library', 'samples:docker')." + }, + "versions": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1 + }, + "description": "List of library versions covered by this test project (strings as published upstream, e.g. '1.1.0', '7.1.0.Final', 'image-pull')." + } + } + }, + "description": "Libraries covered by this test project path with the versions to run." + } + } + }, + "examples": [ + [ + { + "test-project-path": "org.example/library/0.0.1", + "libraries": [ + { + "name": "org.example:library", + "versions": [ "0.0.1" ] + } + ] + }, + { + "test-project-path": "samples/docker/image-pull", + "libraries": [ + { + "name": "samples:docker", + "versions": [ "image-pull" ] + } + ] + } + ] + ] +} From ca796fecc7ff3e473704c00106141b6e388532bf Mon Sep 17 00:00:00 2001 From: jvukicev Date: Thu, 4 Dec 2025 14:35:33 +0100 Subject: [PATCH 3/9] Improve examples --- .../metadata-library-index-schema-v1.0.0.json | 2 +- .../metadata-root-index-schema-v1.0.0.json | 12 +++++++--- .../metadata-version-index-schema-v1.0.0.json | 2 +- .../tests-project-index-schema-v1.0.0.json | 2 +- .../tests-root-index-schema-v1.0.0.json | 22 +++++++++++-------- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/docs/schemas/metadata-library-index-schema-v1.0.0.json b/docs/schemas/metadata-library-index-schema-v1.0.0.json index be07451cb..1e09a68f2 100644 --- a/docs/schemas/metadata-library-index-schema-v1.0.0.json +++ b/docs/schemas/metadata-library-index-schema-v1.0.0.json @@ -1,6 +1,6 @@ { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://github.com/oracle/graalvm-reachability-metadata/schemas/metadata-library-index.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", "description": "Schema for metadata///index.json. Each entry describes a metadata bundle for a range of library versions.", "type": "array", "minItems": 1, diff --git a/docs/schemas/metadata-root-index-schema-v1.0.0.json b/docs/schemas/metadata-root-index-schema-v1.0.0.json index 07ffae34b..0a5703ec3 100644 --- a/docs/schemas/metadata-root-index-schema-v1.0.0.json +++ b/docs/schemas/metadata-root-index-schema-v1.0.0.json @@ -1,6 +1,6 @@ { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://github.com/oracle/graalvm-reachability-metadata/schemas/metadata-root-index.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", "description": "Schema for metadata/index.json. This file lists modules known to the repository and optionally the directory where their metadata is stored, the allowed package prefixes for metadata, and inter-module requirements. See docs/CONTRIBUTING.md (Metadata structure).", "type": "array", "items": { @@ -52,9 +52,15 @@ "module": "org.example:library" }, { + "allowed-packages": ["org.package.name"], "module": "org.example:dependant-library", - "requires": ["org.example:library"], - "allowed-packages": ["org.package.name"] + "requires": ["org.example:library"] + }, + { + "allowed-packages" : [ "org.hibernate", "jakarta" ], + "directory" : "org.hibernate.orm/hibernate-envers", + "module" : "org.hibernate.orm:hibernate-envers", + "requires" : [ "org.hibernate.orm:hibernate-core" ] } ] ] diff --git a/docs/schemas/metadata-version-index-schema-v1.0.0.json b/docs/schemas/metadata-version-index-schema-v1.0.0.json index cb2f3a637..dde29db69 100644 --- a/docs/schemas/metadata-version-index-schema-v1.0.0.json +++ b/docs/schemas/metadata-version-index-schema-v1.0.0.json @@ -1,6 +1,6 @@ { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://github.com/oracle/graalvm-reachability-metadata/schemas/metadata-version-index.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", "description": "Schema for metadata////index.json. Enumerates only allowed config JSON files contained in that metadata-version directory.", "type": "array", "minItems": 1, diff --git a/docs/schemas/tests-project-index-schema-v1.0.0.json b/docs/schemas/tests-project-index-schema-v1.0.0.json index 4702514c0..089ec5720 100644 --- a/docs/schemas/tests-project-index-schema-v1.0.0.json +++ b/docs/schemas/tests-project-index-schema-v1.0.0.json @@ -1,6 +1,6 @@ { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://github.com/oracle/graalvm-reachability-metadata/docs/schemas/tests-project-index-schema-v1.0.0.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Test Project Index", "description": "Schema for tests/src////index.json. This file optionally customizes the test invocation via 'test-command'. If omitted or if the property is not present, a default command will be used (gradlew nativeTest with environment overrides) per TestInvocationTask.", "type": "object", diff --git a/docs/schemas/tests-root-index-schema-v1.0.0.json b/docs/schemas/tests-root-index-schema-v1.0.0.json index 3d8ec8e4c..8e6050987 100644 --- a/docs/schemas/tests-root-index-schema-v1.0.0.json +++ b/docs/schemas/tests-root-index-schema-v1.0.0.json @@ -1,6 +1,6 @@ { - "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://github.com/oracle/graalvm-reachability-metadata/docs/schemas/tests-root-index-schema-v1.0.0.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Tests Root Index", "description": "Schema for tests/src/index.json mapping test projects to libraries and versions (see docs/CONTRIBUTING.md).", "type": "array", @@ -14,7 +14,7 @@ "type": "string", "minLength": 1, "pattern": "^[^\\s/]+/[^\\s/]+/[^\\s/]+$", - "description": "Path under tests/src: // (e.g. 'org.example/library/1.0.0' or 'samples/docker/image-pull')." + "description": "Path under tests/src: // (e.g. 'org.hibernate.orm/hibernate-core/7.1.0.Final')." }, "libraries": { "type": "array", @@ -27,7 +27,7 @@ "name": { "type": "string", "pattern": "^[^:]+:[^:]+$", - "description": "Library coordinates in the form ':' (e.g. 'org.example:library', 'samples:docker')." + "description": "Library coordinates in the form ':' (e.g. 'org.hibernate.orm:hibernate-core')." }, "versions": { "type": "array", @@ -37,7 +37,7 @@ "type": "string", "minLength": 1 }, - "description": "List of library versions covered by this test project (strings as published upstream, e.g. '1.1.0', '7.1.0.Final', 'image-pull')." + "description": "List of library versions covered by this test project (strings as published upstream, e.g. '1.1.0', '7.1.0.Final')." } } }, @@ -52,16 +52,20 @@ "libraries": [ { "name": "org.example:library", - "versions": [ "0.0.1" ] + "versions": [ + "0.0.1" + ] } ] }, { - "test-project-path": "samples/docker/image-pull", - "libraries": [ + "test-project-path" : "org.hibernate.orm/hibernate-core/7.1.0.Final", + "libraries" : [ { - "name": "samples:docker", - "versions": [ "image-pull" ] + "name" : "org.hibernate.orm:hibernate-core", + "versions" : [ + "7.1.0.Final" + ] } ] } From 8c815879d3075338ccb862c4315319a52a705a30 Mon Sep 17 00:00:00 2001 From: jvukicev Date: Mon, 8 Dec 2025 15:06:19 +0100 Subject: [PATCH 4/9] Move schemas directory to the project root --- .github/workflows/library-and-framework-list-validation.yml | 3 ++- docs/CONTRIBUTING.md | 2 +- .../library-and-framework-list-schema-v1.0.0.json | 0 .../metadata-library-index-schema-v1.0.0.json | 0 .../schemas => schemas}/metadata-root-index-schema-v1.0.0.json | 0 .../metadata-version-index-schema-v1.0.0.json | 0 .../schemas => schemas}/tests-project-index-schema-v1.0.0.json | 0 {docs/schemas => schemas}/tests-root-index-schema-v1.0.0.json | 0 8 files changed, 3 insertions(+), 2 deletions(-) rename {docs/schemas => schemas}/library-and-framework-list-schema-v1.0.0.json (100%) rename {docs/schemas => schemas}/metadata-library-index-schema-v1.0.0.json (100%) rename {docs/schemas => schemas}/metadata-root-index-schema-v1.0.0.json (100%) rename {docs/schemas => schemas}/metadata-version-index-schema-v1.0.0.json (100%) rename {docs/schemas => schemas}/tests-project-index-schema-v1.0.0.json (100%) rename {docs/schemas => schemas}/tests-root-index-schema-v1.0.0.json (100%) diff --git a/.github/workflows/library-and-framework-list-validation.yml b/.github/workflows/library-and-framework-list-validation.yml index 3d6e0d671..00170e21b 100644 --- a/.github/workflows/library-and-framework-list-validation.yml +++ b/.github/workflows/library-and-framework-list-validation.yml @@ -18,6 +18,7 @@ jobs: with: file-patterns: | - 'library-and-framework-list*.json' + - 'schemas/library-and-framework-list*.json' - uses: actions/setup-python@v4 with: @@ -43,4 +44,4 @@ jobs: if: steps.filter.outputs.changed == 'true' run: | pip install check-jsonschema - check-jsonschema --schemafile docs/schemas/library-and-framework-list-schema-v1.0.0.json library-and-framework-list.json + check-jsonschema --schemafile schemas/library-and-framework-list-schema-v1.0.0.json library-and-framework-list.json diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 5339146eb..c803a4afe 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -344,4 +344,4 @@ Where: **Note:** To pass format and style checks, please run `sorted="$(jq -s '.[] | sort_by(.artifact)' library-and-framework-list.json)" && echo -E "${sorted}" > library-and-framework-list.json` before submitting a PR. -**Note:** The entries you add will be validated against [library-and-framework-list-schema-v1.0.0.json](https://github.com/oracle/graalvm-reachability-metadata/blob/master/library-and-framework-list-schema-v1.0.0.json) +**Note:** The entries you add will be validated against [library-and-framework-list-schema-v1.0.0.json](https://github.com/oracle/graalvm-reachability-metadata/blob/master/schemas/library-and-framework-list-schema-v1.0.0.json) diff --git a/docs/schemas/library-and-framework-list-schema-v1.0.0.json b/schemas/library-and-framework-list-schema-v1.0.0.json similarity index 100% rename from docs/schemas/library-and-framework-list-schema-v1.0.0.json rename to schemas/library-and-framework-list-schema-v1.0.0.json diff --git a/docs/schemas/metadata-library-index-schema-v1.0.0.json b/schemas/metadata-library-index-schema-v1.0.0.json similarity index 100% rename from docs/schemas/metadata-library-index-schema-v1.0.0.json rename to schemas/metadata-library-index-schema-v1.0.0.json diff --git a/docs/schemas/metadata-root-index-schema-v1.0.0.json b/schemas/metadata-root-index-schema-v1.0.0.json similarity index 100% rename from docs/schemas/metadata-root-index-schema-v1.0.0.json rename to schemas/metadata-root-index-schema-v1.0.0.json diff --git a/docs/schemas/metadata-version-index-schema-v1.0.0.json b/schemas/metadata-version-index-schema-v1.0.0.json similarity index 100% rename from docs/schemas/metadata-version-index-schema-v1.0.0.json rename to schemas/metadata-version-index-schema-v1.0.0.json diff --git a/docs/schemas/tests-project-index-schema-v1.0.0.json b/schemas/tests-project-index-schema-v1.0.0.json similarity index 100% rename from docs/schemas/tests-project-index-schema-v1.0.0.json rename to schemas/tests-project-index-schema-v1.0.0.json diff --git a/docs/schemas/tests-root-index-schema-v1.0.0.json b/schemas/tests-root-index-schema-v1.0.0.json similarity index 100% rename from docs/schemas/tests-root-index-schema-v1.0.0.json rename to schemas/tests-root-index-schema-v1.0.0.json From c2877e08b22f622a2b93868ed56f1b1c2f0e715a Mon Sep 17 00:00:00 2001 From: jvukicev Date: Wed, 10 Dec 2025 14:52:25 +0100 Subject: [PATCH 5/9] Package schemas with GraalVM Reachability Metadata releases --- .../library-and-framework-list-validation.yml | 4 ++-- build.gradle | 11 +++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/library-and-framework-list-validation.yml b/.github/workflows/library-and-framework-list-validation.yml index 00170e21b..703d5764e 100644 --- a/.github/workflows/library-and-framework-list-validation.yml +++ b/.github/workflows/library-and-framework-list-validation.yml @@ -17,8 +17,8 @@ jobs: uses: ./.github/actions/detect-file-changes with: file-patterns: | - - 'library-and-framework-list*.json' - - 'schemas/library-and-framework-list*.json' + - 'library-and-framework-list.json' + - 'schemas/library-and-framework-list-schema*.json' - uses: actions/setup-python@v4 with: diff --git a/build.gradle b/build.gradle index abd10a873..c2fc5b6b8 100644 --- a/build.gradle +++ b/build.gradle @@ -99,10 +99,17 @@ tasks.register('package', Zip) { task -> task.destinationDirectory = layout.buildDirectory from(tck.metadataRoot) - // library-and-framework-list.json is used by Native Build Tools to provide additional - // information on library and framework support to the native image Build Report + from(project.rootDir) { + // library-and-framework-list.json is used by Native Build Tools to provide additional + // information on library and framework support to the native image Build Report include("library-and-framework-list.json") + + // Schemas are included in the ZIP root to allow Native Build Tools to verify + // structural compatibility with this release of GraalVM Reachability Metadata + include("schemas/metadata-root-index-schema-v1.0.0.json") + include("schemas/metadata-library-index-schema-v1.0.0.json") + include("schemas/library-and-framework-list-schema-v1.0.0.json") } } From a7805bd574f23e60934494d0f96ca76e427c9c98 Mon Sep 17 00:00:00 2001 From: jvukicev Date: Thu, 11 Dec 2025 13:33:59 +0100 Subject: [PATCH 6/9] Remove unused schema and fix action.yml typo --- .../actions/detect-file-changes/action.yml | 2 +- .../metadata-version-index-schema-v1.0.0.json | 35 ------------------- 2 files changed, 1 insertion(+), 36 deletions(-) delete mode 100644 schemas/metadata-version-index-schema-v1.0.0.json diff --git a/.github/actions/detect-file-changes/action.yml b/.github/actions/detect-file-changes/action.yml index 6d3e19bbe..9c5cb25d4 100644 --- a/.github/actions/detect-file-changes/action.yml +++ b/.github/actions/detect-file-changes/action.yml @@ -13,5 +13,5 @@ runs: using: "node20" main: "detect-file-changes.js" outputs: - changes_detected: + changed: description: "Returns `true` if any changed file matches the specified patterns, `false` otherwise." diff --git a/schemas/metadata-version-index-schema-v1.0.0.json b/schemas/metadata-version-index-schema-v1.0.0.json deleted file mode 100644 index dde29db69..000000000 --- a/schemas/metadata-version-index-schema-v1.0.0.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "$id": "https://github.com/oracle/graalvm-reachability-metadata/schemas/metadata-version-index.schema.json", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "Schema for metadata////index.json. Enumerates only allowed config JSON files contained in that metadata-version directory.", - "type": "array", - "minItems": 1, - "uniqueItems": true, - "items": { - "type": "string", - "enum": [ - "jni-config.json", - "proxy-config.json", - "reflect-config.json", - "resource-config.json", - "serialization-config.json" - ], - "description": "Allowed metadata config filenames contained in the version directory." - }, - "examples": [ - [ - "proxy-config.json", - "reflect-config.json", - "resource-config.json" - ], - [ - "reflect-config.json", - "resource-config.json", - "serialization-config.json" - ], - [ - "jni-config.json", - "reflect-config.json" - ] - ] -} From fb1331831cc75c8a445bbda480381a6abaf1e9df Mon Sep 17 00:00:00 2001 From: jvukicev Date: Thu, 11 Dec 2025 14:52:08 +0100 Subject: [PATCH 7/9] Add schema validation workflow and update detect-file-changes github action to output the detected files --- .../actions/detect-file-changes/action.yml | 2 + .../detect-file-changes.js | 14 ++- .github/workflows/index-file-validation.yml | 90 +++++++++++++++++++ 3 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/index-file-validation.yml diff --git a/.github/actions/detect-file-changes/action.yml b/.github/actions/detect-file-changes/action.yml index 9c5cb25d4..f1a92f6f7 100644 --- a/.github/actions/detect-file-changes/action.yml +++ b/.github/actions/detect-file-changes/action.yml @@ -15,3 +15,5 @@ runs: outputs: changed: description: "Returns `true` if any changed file matches the specified patterns, `false` otherwise." + changed_files: + description: "Returns a space-separated list of all changed files that match the specified patterns, or an empty list if none match." diff --git a/.github/actions/detect-file-changes/detect-file-changes.js b/.github/actions/detect-file-changes/detect-file-changes.js index 8be819051..48bff2e7b 100644 --- a/.github/actions/detect-file-changes/detect-file-changes.js +++ b/.github/actions/detect-file-changes/detect-file-changes.js @@ -232,15 +232,23 @@ function fileMatches(file, compiled) { changedFiles.forEach(f => console.log(`- ${f}`)); // Check if any file matches - const matched = changedFiles.some(f => fileMatches(f, compiled)); + const matchedFiles = changedFiles.filter(f => fileMatches(f, compiled)); + const matched = matchedFiles.length > 0; - // Write GitHub Action output + // Write GitHub Action outputs fs.appendFileSync( process.env.GITHUB_OUTPUT, `changed=${matched ? 'true' : 'false'}\n` ); - console.log(`Files match filter β†’ ${matched}`); + // Write the list of matched files as a multiline output + fs.appendFileSync( + process.env.GITHUB_OUTPUT, + `changed_files=${matchedFiles.join(' ')}\n` + ); + + console.log(`Files matching filter (${matchedFiles.length}):`); + matchedFiles.forEach(f => console.log(`- ${f}`)); } catch (err) { console.log(`file-filter encountered an error: ${err?.message || err}`); process.exit(0); // Non-fatal for CI diff --git a/.github/workflows/index-file-validation.yml b/.github/workflows/index-file-validation.yml new file mode 100644 index 000000000..bc5eae99a --- /dev/null +++ b/.github/workflows/index-file-validation.yml @@ -0,0 +1,90 @@ +name: "Validate index.json files" + +on: + pull_request: + +jobs: + validate-json: + name: "πŸ“‹ Validate changed JSON files" + runs-on: ubuntu-22.04 + timeout-minutes: 10 + + steps: + - name: "☁️ Checkout repository" + uses: actions/checkout@v4 + + - name: "πŸ”Ž Detect relevant file changes" + id: filter + uses: ./.github/actions/detect-file-changes + with: + file-patterns: | + - 'metadata/index.json' + - 'metadata/*/*/index.json' + - 'tests/src/index.json' + - 'tests/src/*/*/*/index.json' + github_token: ${{ secrets.GITHUB_TOKEN }} + + - name: "Setup Python" + if: steps.filter.outputs.changed == 'true' + uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - name: "Install validation tools" + if: steps.filter.outputs.changed == 'true' + run: | + pip install jq check-jsonschema + + - name: "Check that the changed index.json files conform to their schemas" + if: steps.filter.outputs.changed == 'true' + run: | + set -e + + # Treat changed_files as a proper array + FILES=(${{ steps.filter.outputs.changed_files }}) + + # Track failures + FAILURES=() + + for FILE in "${FILES[@]}"; do + + # Determine schema for each file + if [[ "$FILE" == "metadata/index.json" ]]; then + SCHEMA="schemas/metadata-root-index-schema-v1.0.0.json" + elif [[ "$FILE" == metadata/*/*/index.json ]]; then + SCHEMA="schemas/metadata-library-index-schema-v1.0.0.json" + elif [[ "$FILE" == "tests/src/index.json" ]]; then + SCHEMA="schemas/tests-root-index-schema-v1.0.0.json" + elif [[ "$FILE" == tests/src/*/*/*/index.json ]]; then + SCHEMA="schemas/tests-project-index-schema-v1.0.0.json" + else + echo "ℹ️ Skipping: $FILE (no schema mapping)" + continue + fi + + echo "πŸ” Validating $FILE using $SCHEMA" + + # Step 1: Check JSON well-formedness + if ! jq -e . "$FILE" >/dev/null; then + echo "❌ $FILE is not valid JSON" + FAILURES+=("$FILE (invalid JSON)") + continue + fi + + # Step 2: Validate against schema + if ! check-jsonschema --schemafile "$SCHEMA" "$FILE"; then + FAILURES+=("$FILE (schema validation failed)") + continue + fi + + echo "βœ… $FILE validated successfully" + done + + # Fail at the end if any errors occurred + if [ ${#FAILURES[@]} -ne 0 ]; then + echo "::error ::Some files failed validation:" + for f in "${FAILURES[@]}"; do + echo "::error :: $f" + done + exit 1 + fi From 89f8e23f0536999a51fb22f930db88def85d913a Mon Sep 17 00:00:00 2001 From: jvukicev Date: Fri, 12 Dec 2025 10:00:44 +0100 Subject: [PATCH 8/9] Use gradle task when collecting changed file list --- .../actions/detect-file-changes/action.yml | 2 - .../detect-file-changes.js | 14 +--- .github/workflows/index-file-validation.yml | 36 ++++++++-- ci.json | 4 ++ .../org.graalvm.internal.tck-harness.gradle | 71 +++++++++++++++++++ .../internal/tck/harness/TckExtension.java | 22 ++++++ 6 files changed, 130 insertions(+), 19 deletions(-) diff --git a/.github/actions/detect-file-changes/action.yml b/.github/actions/detect-file-changes/action.yml index f1a92f6f7..9c5cb25d4 100644 --- a/.github/actions/detect-file-changes/action.yml +++ b/.github/actions/detect-file-changes/action.yml @@ -15,5 +15,3 @@ runs: outputs: changed: description: "Returns `true` if any changed file matches the specified patterns, `false` otherwise." - changed_files: - description: "Returns a space-separated list of all changed files that match the specified patterns, or an empty list if none match." diff --git a/.github/actions/detect-file-changes/detect-file-changes.js b/.github/actions/detect-file-changes/detect-file-changes.js index 48bff2e7b..8be819051 100644 --- a/.github/actions/detect-file-changes/detect-file-changes.js +++ b/.github/actions/detect-file-changes/detect-file-changes.js @@ -232,23 +232,15 @@ function fileMatches(file, compiled) { changedFiles.forEach(f => console.log(`- ${f}`)); // Check if any file matches - const matchedFiles = changedFiles.filter(f => fileMatches(f, compiled)); - const matched = matchedFiles.length > 0; + const matched = changedFiles.some(f => fileMatches(f, compiled)); - // Write GitHub Action outputs + // Write GitHub Action output fs.appendFileSync( process.env.GITHUB_OUTPUT, `changed=${matched ? 'true' : 'false'}\n` ); - // Write the list of matched files as a multiline output - fs.appendFileSync( - process.env.GITHUB_OUTPUT, - `changed_files=${matchedFiles.join(' ')}\n` - ); - - console.log(`Files matching filter (${matchedFiles.length}):`); - matchedFiles.forEach(f => console.log(`- ${f}`)); + console.log(`Files match filter β†’ ${matched}`); } catch (err) { console.log(`file-filter encountered an error: ${err?.message || err}`); process.exit(0); // Non-fatal for CI diff --git a/.github/workflows/index-file-validation.yml b/.github/workflows/index-file-validation.yml index bc5eae99a..cea5fe7bb 100644 --- a/.github/workflows/index-file-validation.yml +++ b/.github/workflows/index-file-validation.yml @@ -12,6 +12,8 @@ jobs: steps: - name: "☁️ Checkout repository" uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: "πŸ”Ž Detect relevant file changes" id: filter @@ -22,7 +24,22 @@ jobs: - 'metadata/*/*/index.json' - 'tests/src/index.json' - 'tests/src/*/*/*/index.json' - github_token: ${{ secrets.GITHUB_TOKEN }} + + - name: "πŸ”§ Setup Java" + if: steps.filter.outputs.changed == 'true' + uses: actions/setup-java@v4 + with: + distribution: 'graalvm' + java-version: '21' + + - name: "πŸ•ΈοΈ Populate matrix" + id: set-matrix + if: steps.filter.outputs.changed == 'true' + run: | + ./gradlew generateChangedIndexFileMatrix -PbaseCommit=${{ github.event.pull_request.base.sha }} -PnewCommit=${{ github.event.pull_request.head.sha }} + + echo "Matrix output:" + echo "${{ steps.set-matrix.outputs.matrix }}" - name: "Setup Python" if: steps.filter.outputs.changed == 'true' @@ -38,16 +55,23 @@ jobs: - name: "Check that the changed index.json files conform to their schemas" if: steps.filter.outputs.changed == 'true' run: | - set -e + set -euo pipefail + + MATRIX='${{ steps.set-matrix.outputs.matrix }}' - # Treat changed_files as a proper array - FILES=(${{ steps.filter.outputs.changed_files }}) + # Convert matrix JSON into an array of file paths + FILES=($(echo "$MATRIX" | jq -r '.index_files[]')) + + if [ ${#FILES[@]} -eq 0 ]; then + echo "No changed index.json files to validate." + exit 0 + fi # Track failures FAILURES=() for FILE in "${FILES[@]}"; do - + # Determine schema for each file if [[ "$FILE" == "metadata/index.json" ]]; then SCHEMA="schemas/metadata-root-index-schema-v1.0.0.json" @@ -73,7 +97,7 @@ jobs: # Step 2: Validate against schema if ! check-jsonschema --schemafile "$SCHEMA" "$FILE"; then - FAILURES+=("$FILE (schema validation failed)") + FAILURES+=("$FILE (schema failure)") continue fi diff --git a/ci.json b/ci.json index 24aad6e87..8a7c2d905 100644 --- a/ci.json +++ b/ci.json @@ -15,5 +15,9 @@ "generateMatrixMatchingCoordinates": { "java": ["25","latest-ea"], "os": ["ubuntu-latest"] + }, + "generateChangedIndexFileMatrix": { + "java": ["latest-ea"], + "os": ["ubuntu-latest"] } } diff --git a/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck-harness.gradle b/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck-harness.gradle index 05a9eaaf9..a691009ee 100644 --- a/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck-harness.gradle +++ b/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck-harness.gradle @@ -150,6 +150,13 @@ if (project.hasProperty("baseCommit")) { } } +List diffIndexFiles = new ArrayList<>() +if (project.hasProperty("baseCommit")) { + String baseCommit = project.findProperty("baseCommit") + String newCommit = Objects.requireNonNullElse(project.findProperty("newCommit"), "HEAD") + diffIndexFiles.addAll(tck.diffIndexFiles(baseCommit, newCommit)) +} + Map loadCi() { File f = project.file("ci.json") if (!f.exists()) { @@ -223,6 +230,32 @@ Provider generateChangedCoordinatesMatrix = tasks.register("generateChange } } +// gradle generateChangedIndexFileMatrix -PbaseCommit= -PnewCommit= +Provider generateChangedIndexFileMatrix = tasks.register("generateChangedIndexFileMatrix", DefaultTask) { task -> + task.setDescription("Returns matrix definition populated with changed index.json files") + task.setGroup(METADATA_GROUP) + + task.doFirst { + if (!project.hasProperty("baseCommit")) { + throw new GradleException("Missing 'baseCommit' property! Rerun Gradle with '-PbaseCommit='") + } + + boolean noneFound = diffIndexFiles.isEmpty() + + def matrix = [ + "index_files": noneFound ? [] : diffIndexFiles + ] + matrix.putAll(matrixDefaultsFor("generateChangedIndexFileMatrix")) + + if (noneFound) { + println "No changed index.json files were found!" + } + + writeGithubOutput("matrix", JsonOutput.toJson(matrix)) + writeGithubOutput("none-found", noneFound.toString()) + } +} + // gradle generateInfrastructureChangedCoordinatesMatrix -PbaseCommit= -PnewCommit= Provider generateInfrastructureChangedCoordinatesMatrix = tasks.register("generateInfrastructureChangedCoordinatesMatrix", DefaultTask) { task -> task.setDescription("Returns matrix definition populated with pre-selected coordinates when test infrastructure has changed") @@ -268,6 +301,44 @@ Provider generateInfrastructureChangedCoordinatesMatrix = tasks.register(" } } +tasks.register("generateChangedJsonFiles", DefaultTask) { task -> + task.group = METADATA_GROUP + task.description = "Returns the list of changed JSON files in the repository between two commits" + + doFirst { + if (!project.hasProperty("baseCommit") || !project.hasProperty("newCommit")) { + throw new GradleException("Missing 'baseCommit' or 'newCommit'! Rerun Gradle with '-PbaseCommit= -PnewCommit='") + } + + def base = project.property("baseCommit") + def head = project.property("newCommit") + + // Run git diff to get changed files + def stdout = new ByteArrayOutputStream() + exec { + commandLine "git", "diff", "--name-only", base, head + standardOutput = stdout + } + + def changedFiles = stdout.toString().readLines() + + // Filter only the JSON files we care about + def jsonFiles = changedFiles.findAll { + it == "metadata/index.json" || + it ==~ /metadata\/[^\/]+\/[^\/]+\/index\.json/ || + it.startsWith("tests/src/") && it.endsWith("index.json") || + it == "library-and-framework-list.json" + } + + println "Found ${jsonFiles.size()} changed JSON file(s):" + jsonFiles.each { println " - $it" } + + // Write outputs for GitHub Actions + writeGithubOutput("changed_files", JsonOutput.toJson(jsonFiles)) + writeGithubOutput("changed", (jsonFiles.size() > 0).toString()) + } +} + // new library version updaters tasks tasks.register("fetchExistingLibrariesWithNewerVersions", FetchExistingLibrariesWithNewerVersionsTask.class) { task -> task.setGroup(METADATA_GROUP) diff --git a/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/TckExtension.java b/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/TckExtension.java index c62423971..cb34d8c1e 100644 --- a/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/TckExtension.java +++ b/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/TckExtension.java @@ -184,6 +184,28 @@ List diffCoordinates(String baseCommit, String newCommit) { return changedCoordinates; } + /** + * Returns a list of changed index.json files between baseCommit and newCommit. + * + * @return List of index.json files + */ + public List diffIndexFiles(String baseCommit, String newCommit) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + getExecOperations().exec(spec -> { + spec.setStandardOutput(baos); + spec.commandLine("git", "diff", "--name-only", "--diff-filter=ACMRT", + baseCommit, newCommit); + }); + + String output = baos.toString(StandardCharsets.UTF_8); + List diffFiles = Arrays.asList(output.split("\\r?\\n")); + + return diffFiles.stream() + .filter(f -> f.endsWith("index.json")) + .distinct() + .collect(Collectors.toList()); + } + private boolean metadataIndexContainsChangedEntries(Set changedCoordinates, List changedEntries) { boolean containsAll = true; for (var n : changedEntries) { From edf77b7ed0a9f84c56b31aff5eadc937cfb53db7 Mon Sep 17 00:00:00 2001 From: jvukicev Date: Fri, 12 Dec 2025 10:09:15 +0100 Subject: [PATCH 9/9] Code cleanup --- .../org.graalvm.internal.tck-harness.gradle | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck-harness.gradle b/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck-harness.gradle index a691009ee..513d6144e 100644 --- a/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck-harness.gradle +++ b/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck-harness.gradle @@ -301,44 +301,6 @@ Provider generateInfrastructureChangedCoordinatesMatrix = tasks.register(" } } -tasks.register("generateChangedJsonFiles", DefaultTask) { task -> - task.group = METADATA_GROUP - task.description = "Returns the list of changed JSON files in the repository between two commits" - - doFirst { - if (!project.hasProperty("baseCommit") || !project.hasProperty("newCommit")) { - throw new GradleException("Missing 'baseCommit' or 'newCommit'! Rerun Gradle with '-PbaseCommit= -PnewCommit='") - } - - def base = project.property("baseCommit") - def head = project.property("newCommit") - - // Run git diff to get changed files - def stdout = new ByteArrayOutputStream() - exec { - commandLine "git", "diff", "--name-only", base, head - standardOutput = stdout - } - - def changedFiles = stdout.toString().readLines() - - // Filter only the JSON files we care about - def jsonFiles = changedFiles.findAll { - it == "metadata/index.json" || - it ==~ /metadata\/[^\/]+\/[^\/]+\/index\.json/ || - it.startsWith("tests/src/") && it.endsWith("index.json") || - it == "library-and-framework-list.json" - } - - println "Found ${jsonFiles.size()} changed JSON file(s):" - jsonFiles.each { println " - $it" } - - // Write outputs for GitHub Actions - writeGithubOutput("changed_files", JsonOutput.toJson(jsonFiles)) - writeGithubOutput("changed", (jsonFiles.size() > 0).toString()) - } -} - // new library version updaters tasks tasks.register("fetchExistingLibrariesWithNewerVersions", FetchExistingLibrariesWithNewerVersionsTask.class) { task -> task.setGroup(METADATA_GROUP)