From da38f44e2a58b1a1825d3f73e40a4602845c3071 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 16 Oct 2024 17:27:04 +0200 Subject: [PATCH 01/23] Scan new versions for existing libraries --- .../workflows/check-new-library-versions.yml | 144 ++++++++++++++++++ .github/workflows/tryPushVersionsUpdate.sh | 31 ++++ metadata/com.itextpdf/forms/index.json | 1 + metadata/com.itextpdf/io/index.json | 1 + metadata/com.itextpdf/kernel/index.json | 1 + metadata/com.itextpdf/layout/index.json | 1 + metadata/com.itextpdf/svg/index.json | 1 + .../org.graalvm.internal.tck-harness.gradle | 51 +++++++ .../groovy/org.graalvm.internal.tck.gradle | 2 +- .../internal/tck/harness/TckExtension.java | 58 ++++++- .../tck/TestedVersionUpdaterTask.java | 66 ++++++++ .../tck/model/MetadataVersionsIndexEntry.java | 16 ++ 12 files changed, 364 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/check-new-library-versions.yml create mode 100644 .github/workflows/tryPushVersionsUpdate.sh create mode 100644 tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java create mode 100644 tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/model/MetadataVersionsIndexEntry.java diff --git a/.github/workflows/check-new-library-versions.yml b/.github/workflows/check-new-library-versions.yml new file mode 100644 index 000000000..41d23d712 --- /dev/null +++ b/.github/workflows/check-new-library-versions.yml @@ -0,0 +1,144 @@ +name: "Check new library versions" + +on: + schedule: + - cron: "0 0 8 * *" + - cron: "0 0 22 * *" + workflow_dispatch: + +permissions: + contents: write + actions: write + +concurrency: + group: "workflow = ${{ github.workflow }}, ref = ${{ github.event.ref }}, pr = ${{ github.event.pull_request.id }}" + cancel-in-progress: true + +jobs: + get-all-libraries: + if: github.repository == 'oracle/graalvm-reachability-metadata' + name: "πŸ“‹ Get list of all supported libraries" + permissions: write-all + runs-on: "ubuntu-20.04" + timeout-minutes: 5 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + issue: ${{ steps.set-issue.outputs.issue }} + steps: + - name: "☁️ Checkout repository" + uses: actions/checkout@v4 + - name: "πŸ”§ Prepare environment" + uses: graalvm/setup-graalvm@v1 + with: + java-version: '21' + distribution: 'graalvm' + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: "πŸ•ΈοΈ Populate matrix" + id: set-matrix + run: | + ./gradlew getExistingLibraries + - name: "Create branch" + run: | + git config --local user.email "actions@github.com" + git config --local user.name "Github Actions" + git switch -C libraryVersionsDependabot/$(date '+%Y-%m-%d') + git push origin libraryVersionsDependabot/$(date '+%Y-%m-%d') + - name: "Create issue" + id: set-issue + run: | + git config --local user.email "actions@github.com" + git config --local user.name "Github Actions" + + issue_url=$(gh issue create --title "List unsupported library versions" --body "This issue lists unsupported versions of the existing libraries in the repo") + echo "::set-output name=issue::$issue_url" + + test-all-metadata: + name: "πŸ§ͺ ${{ matrix.coordinates }} (GraalVM for JDK ${{ matrix.version }} @ ${{ matrix.os }})" + permissions: write-all + runs-on: ${{ matrix.os }} + timeout-minutes: 20 + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + needs: get-all-libraries + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.get-all-libraries.outputs.matrix) }} + steps: + - name: "☁️ Checkout repository" + uses: actions/checkout@v4 + - name: "πŸ”§ Setup java" + uses: actions/setup-java@v4 + with: + distribution: 'oracle' + java-version: '21' + - name: "πŸ”§ Prepare environment" + uses: graalvm/setup-graalvm@v1 + with: + set-java-home: 'false' + java-version: ${{ matrix.version }} + distribution: 'graalvm' + github-token: ${{ secrets.GITHUB_TOKEN }} + native-image-job-reports: 'true' + - name: "Extract test path and library version" + run: | + LIBRARY_PATH=$(echo ${{ matrix.coordinates }} | cut -d ':' -f1-2 | sed 's/:/\//g') + LATEST_VERSION=$(find tests/src/$LIBRARY_PATH/* -maxdepth 1 -type d | sort -V | tail -1 | cut -d '/' -f5) + TEST_PATH="$LIBRARY_PATH/$LATEST_VERSION" + TEST_COORDINATES=$(echo "$TEST_PATH" | tr / :) + + echo "LATEST_VERSION=$LATEST_VERSION" >> ${GITHUB_ENV} + echo "TEST_PATH=$TEST_PATH" >> ${GITHUB_ENV} + echo "TEST_COORDINATES=$TEST_COORDINATES" >> ${GITHUB_ENV} + - name: "Pull allowed docker images" + run: | + ./gradlew pullAllowedDockerImages --coordinates=${{ env.TEST_COORDINATES }} + - name: "Disable docker" + run: | + sudo apt-get install openbsd-inetd + sudo bash -c "cat ./.github/workflows/discard-port.conf >> /etc/inetd.conf" + sudo systemctl start inetd + sudo mkdir /etc/systemd/system/docker.service.d + sudo bash -c "cat ./.github/workflows/dockerd.service > /etc/systemd/system/docker.service.d/http-proxy.conf" + sudo systemctl daemon-reload + sudo systemctl restart docker + - name: "Replace version" + run: | + CURRENT_VERSION=$(echo ${{ matrix.coordinates }} | cut -d ":" -f3) + sed -i "s/library.version\s*=\s*${{ env.LATEST_VERSION }}/library.version = $CURRENT_VERSION/g" tests/src/${{ env.TEST_PATH }}/gradle.properties + - name: "πŸ§ͺ Run '${{ env.TEST_COORDINATES }}' tests" + run: | + ./gradlew test -Pcoordinates=${{ env.TEST_COORDINATES }} + git stash + - name: "New library is supported" + if: success() + run: | + sh ./.github/workflows/tryPushVersionsUpdate.sh ${{ matrix.coordinates }} + - name: "New library is not supported" + if: failure() + run: | + git config --local user.email "actions@github.com" + git config --local user.name "Github Actions" + gh issue comment "${{ needs.get-all-libraries.outputs.issue }}" --body "${{ matrix.coordinates }}" + + process-results: + name: "πŸ§ͺ Process results" + runs-on: "ubuntu-20.04" + if: ${{ always() }} + needs: + - get-all-libraries + - test-all-metadata + permissions: write-all + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: "☁️ Checkout repository" + uses: actions/checkout@v4 + - name: "PR for supported versions" + run: | + git config --local user.email "actions@github.com" + git config --local user.name "Github Actions" + git fetch origin libraryVersionsDependabot/$(date '+%Y-%m-%d') + git checkout libraryVersionsDependabot/$(date '+%Y-%m-%d') + gh pr create --title "Update supported library versions" --body "This pull request updates supported versions of the existing libraries in the repo" \ No newline at end of file diff --git a/.github/workflows/tryPushVersionsUpdate.sh b/.github/workflows/tryPushVersionsUpdate.sh new file mode 100644 index 000000000..c0fbc67b6 --- /dev/null +++ b/.github/workflows/tryPushVersionsUpdate.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -x + +git config --local user.email "actions@github.com" +git config --local user.name "Github Actions" + +BRANCH="libraryVersionsDependabot/$(date '+%Y-%m-%d')" +git fetch origin "$BRANCH" +git checkout "$BRANCH" + +while [ true ] +do + ./gradlew addTestedVersion --coordinates="$1" + git add -u + git commit -m "$1" + if [ "$(git rev-list --count origin/$BRANCH --not $BRANCH)" -eq 0 ] + then + git push origin "$BRANCH" + PUSH_RETVAL=$? + if [ "$PUSH_RETVAL" -eq 0 ] + then + break + fi + fi + + git reset --hard HEAD~1 + git fetch origin "$BRANCH" + git rebase -X theirs "origin/$BRANCH" +done + + diff --git a/metadata/com.itextpdf/forms/index.json b/metadata/com.itextpdf/forms/index.json index f7ca2c17d..d65fc7dee 100644 --- a/metadata/com.itextpdf/forms/index.json +++ b/metadata/com.itextpdf/forms/index.json @@ -1,5 +1,6 @@ [ { + "latest": true, "metadata-version": "8.0.3", "module": "com.itextpdf:forms", "tested-versions": [ diff --git a/metadata/com.itextpdf/io/index.json b/metadata/com.itextpdf/io/index.json index d13a5b341..08e188820 100644 --- a/metadata/com.itextpdf/io/index.json +++ b/metadata/com.itextpdf/io/index.json @@ -1,5 +1,6 @@ [ { + "latest": true, "metadata-version": "8.0.3", "module": "com.itextpdf:io", "tested-versions": [ diff --git a/metadata/com.itextpdf/kernel/index.json b/metadata/com.itextpdf/kernel/index.json index d8c7b64d9..8a047a84f 100644 --- a/metadata/com.itextpdf/kernel/index.json +++ b/metadata/com.itextpdf/kernel/index.json @@ -1,5 +1,6 @@ [ { + "latest": true, "metadata-version": "8.0.3", "module": "com.itextpdf:kernel", "tested-versions": [ diff --git a/metadata/com.itextpdf/layout/index.json b/metadata/com.itextpdf/layout/index.json index 4019110df..09545fe27 100644 --- a/metadata/com.itextpdf/layout/index.json +++ b/metadata/com.itextpdf/layout/index.json @@ -1,5 +1,6 @@ [ { + "latest": true, "metadata-version": "8.0.3", "module": "com.itextpdf:layout", "tested-versions": [ diff --git a/metadata/com.itextpdf/svg/index.json b/metadata/com.itextpdf/svg/index.json index 27cd14a5a..0ef68772d 100644 --- a/metadata/com.itextpdf/svg/index.json +++ b/metadata/com.itextpdf/svg/index.json @@ -1,5 +1,6 @@ [ { + "latest": true, "metadata-version": "8.0.3", "module": "com.itextpdf:svg", "tested-versions": [ 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 e6f86c486..53e3a2a37 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 @@ -14,6 +14,7 @@ import org.graalvm.internal.tck.DockerTask import org.graalvm.internal.tck.ConfigFilesChecker import org.graalvm.internal.tck.ScaffoldTask import org.graalvm.internal.tck.GrypeTask +import org.graalvm.internal.tck.TestedVersionUpdaterTask import org.graalvm.internal.tck.harness.tasks.CheckstyleInvocationTask import org.graalvm.internal.tck.harness.tasks.TestInvocationTask @@ -102,6 +103,51 @@ def matrixDefault = [ final String METADATA_GROUP = "Metadata" +List getNewerVersionsFor(String library, String startingVersion) { + def baseUrl = "https://repo1.maven.org/maven2" + String group = library.split(":")[0].replace(".", "/") + String artifact = library.split(":")[1] + def data = new URL(baseUrl + "/" + group + "/" + artifact + "/" + "maven-metadata.xml").getText() + + return tck.getNewerVersionsFromLibraryIndex(data, startingVersion, library) +} + +// gradle getExistingLibrariesWithNewVersions +Provider getExistingLibrariesWithNewVersions = tasks.register("getExistingLibraries", DefaultTask) { task -> + task.setDescription("Returns list of all libraries coordinates") + task.setGroup(METADATA_GROUP) + task.doFirst { + Set libraries = [] + matchingCoordinates.forEach { + libraries.add(it.substring(0, it.lastIndexOf(":"))) + } + + List newerVersions = new ArrayList<>() + libraries.forEach { + String libraryName = it + if (!libraryName.contains("samples") && !libraryName.contains("example")) { + List versions = getNewerVersionsFor(libraryName, tck.getLatestLibraryVersion(libraryName)) + versions.forEach { + newerVersions.add(libraryName.concat(":").concat(it)) + } + } + } + + // workflows limitation to only accept up to 255 parallel jobs + if (newerVersions.size() > 254) { + // for testing we will keep 5, and return to 255 once everything work + newerVersions = newerVersions.subList(0, 254) + } + + def matrix = [ + "coordinates": newerVersions + ] + matrix.putAll(matrixDefault) + + println "::set-output name=matrix::${JsonOutput.toJson(matrix)}" + } +} + // gradle generateMatrixMatchingCoordinates -Pcoordinates= Provider generateMatrixMatchingCoordinates = tasks.register("generateMatrixMatchingCoordinates", DefaultTask) { task -> task.setDescription("Returns matrix definition populated with all matching coordinates") @@ -182,3 +228,8 @@ tasks.register("checkConfigFiles", ConfigFilesChecker.class) { task -> task.setDescription("Checks content of config files for a new library.") task.setGroup(METADATA_GROUP) } + +tasks.register("addTestedVersion", TestedVersionUpdaterTask.class) { task -> + task.setDescription("Updates list of tested versions.") + task.setGroup(METADATA_GROUP) +} diff --git a/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck.gradle b/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck.gradle index 7c413161c..13b73f05c 100644 --- a/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck.gradle +++ b/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck.gradle @@ -42,7 +42,7 @@ String metadataPath = Objects.requireNonNullElse( providers.gradleProperty('metadata.dir').get() ) -String libraryVersion = System.getenv("GVM_TCK_LV") ?: providers.gradleProperty('library.version').get() +String libraryVersion = providers.gradleProperty('library.version').get() ?: System.getenv("GVM_TCK_LV") String libraryGAV = System.getenv("GVM_TCK_LC") ?: providers.gradleProperty('library.coordinates').getOrElse(null) libraryGAV = libraryGAV ?: "" 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 2cff195d9..c5300f2cb 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 @@ -13,6 +13,7 @@ import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; import org.gradle.process.ExecOperations; +import org.gradle.util.internal.VersionNumber; import javax.inject.Inject; import java.io.ByteArrayOutputStream; @@ -22,15 +23,10 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -351,4 +347,50 @@ List getMetadataFileList(Path directory) throws IOException { return foundFiles; } } + + @SuppressWarnings("unchecked") + String getLatestLibraryVersion(String module) { + String libraryIndex = module.replace(":", "/"); + List allTested = new ArrayList<>(); + List> index = (List>) readIndexFile(metadataRoot().resolve(libraryIndex)); + for (Map entry : index) { + List testedVersions = (List) entry.get("tested-versions"); + allTested.addAll(testedVersions); + } + + if (allTested.isEmpty()) { + throw new RuntimeException("Cannot find any tested version for: " + module); + } + + allTested.sort(Comparator.comparing(VersionNumber::parse)); + return allTested.get(allTested.size() - 1); + } + + List getNewerVersionsFromLibraryIndex(String index, String startingVersion, String libraryName) { + Pattern pattern = Pattern.compile("(.*)"); + Matcher matcher = pattern.matcher(index); + List allVersions = new ArrayList<>(); + + if (matcher.groupCount() < 1) { + throw new RuntimeException("Cannot find versions in the given index file: " + libraryName); + } + + while (matcher.find()) { + allVersions.add(matcher.group(1)); + } + + int indexOfStartingVersion = allVersions.indexOf(startingVersion); + if (indexOfStartingVersion < 0) { + System.out.println("Cannot find starting version in index file: " + libraryName + " for version " + startingVersion); + return new ArrayList<>(); + } + + allVersions = allVersions.subList(indexOfStartingVersion, allVersions.size()); + if (allVersions.size() <= 1) { + System.out.println("Cannot find newer versions for " + libraryName + " after the version " + startingVersion); + } + + return allVersions.subList(1, allVersions.size()); + } + } diff --git a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java new file mode 100644 index 000000000..8dd1efd53 --- /dev/null +++ b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java @@ -0,0 +1,66 @@ +package org.graalvm.internal.tck; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.core.util.DefaultIndenter; +import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import org.graalvm.internal.tck.model.MetadataVersionsIndexEntry; +import org.gradle.api.DefaultTask; +import org.gradle.api.tasks.TaskAction; +import org.gradle.api.tasks.options.Option; +import org.gradle.util.internal.VersionNumber; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +public abstract class TestedVersionUpdaterTask extends DefaultTask { + + private final ObjectMapper objectMapper = new ObjectMapper() + .enable(SerializationFeature.INDENT_OUTPUT) + .setSerializationInclusion(JsonInclude.Include.NON_NULL); + + @Option(option = "coordinates", description = "GAV coordinates of the library") + void setCoordinates(String coordinates) { + this.coordinates = coordinates; + } + + private String coordinates; + + @SuppressWarnings("unchecked") + @TaskAction + void run() throws IllegalStateException, IOException { + List GAVCoordinates = Arrays.stream(coordinates.split(":")).toList(); + if (GAVCoordinates.size() != 3) { + throw new IllegalArgumentException("Maven coordinates should have 3 parts"); + } + + String group = GAVCoordinates.get(0); + String artifact = GAVCoordinates.get(1); + String version = GAVCoordinates.get(2); + Coordinates c = new Coordinates(group, artifact, version); + addToMetadataIndexJson(c); + } + + private void addToMetadataIndexJson(Coordinates c) throws IOException { + File coordinatesMetadataIndex = getProject().file(CoordinateUtils.replace("metadata/$group$/$artifact$/index.json", c)); + List entries = objectMapper.readValue(coordinatesMetadataIndex, new TypeReference<>() { + }); + + for (MetadataVersionsIndexEntry entry : entries) { + if (entry.latest() != null && entry.latest()) { + entry.testedVersions().add(c.version()); + entry.testedVersions().sort(Comparator.comparing(VersionNumber::parse)); + } + } + + DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter(); + prettyPrinter.indentArraysWith(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE); + + objectMapper.writer(prettyPrinter).writeValue(coordinatesMetadataIndex, entries); + } +} diff --git a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/model/MetadataVersionsIndexEntry.java b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/model/MetadataVersionsIndexEntry.java new file mode 100644 index 000000000..ad0a31e95 --- /dev/null +++ b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/model/MetadataVersionsIndexEntry.java @@ -0,0 +1,16 @@ +package org.graalvm.internal.tck.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public record MetadataVersionsIndexEntry ( + Boolean latest, + String module, + @JsonProperty("default-for") + String defaultFor, + @JsonProperty("metadata-version") + String metadataVersion, + @JsonProperty("tested-versions") + List testedVersions +){} From 92e4e153c6e66d8887af40b470262fad3616d455 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Fri, 25 Oct 2024 18:35:26 +0200 Subject: [PATCH 02/23] Remove redudant changes left from testing --- metadata/com.itextpdf/forms/index.json | 1 - metadata/com.itextpdf/io/index.json | 1 - metadata/com.itextpdf/kernel/index.json | 1 - metadata/com.itextpdf/layout/index.json | 1 - metadata/com.itextpdf/svg/index.json | 1 - 5 files changed, 5 deletions(-) diff --git a/metadata/com.itextpdf/forms/index.json b/metadata/com.itextpdf/forms/index.json index d65fc7dee..f7ca2c17d 100644 --- a/metadata/com.itextpdf/forms/index.json +++ b/metadata/com.itextpdf/forms/index.json @@ -1,6 +1,5 @@ [ { - "latest": true, "metadata-version": "8.0.3", "module": "com.itextpdf:forms", "tested-versions": [ diff --git a/metadata/com.itextpdf/io/index.json b/metadata/com.itextpdf/io/index.json index 08e188820..d13a5b341 100644 --- a/metadata/com.itextpdf/io/index.json +++ b/metadata/com.itextpdf/io/index.json @@ -1,6 +1,5 @@ [ { - "latest": true, "metadata-version": "8.0.3", "module": "com.itextpdf:io", "tested-versions": [ diff --git a/metadata/com.itextpdf/kernel/index.json b/metadata/com.itextpdf/kernel/index.json index 8a047a84f..d8c7b64d9 100644 --- a/metadata/com.itextpdf/kernel/index.json +++ b/metadata/com.itextpdf/kernel/index.json @@ -1,6 +1,5 @@ [ { - "latest": true, "metadata-version": "8.0.3", "module": "com.itextpdf:kernel", "tested-versions": [ diff --git a/metadata/com.itextpdf/layout/index.json b/metadata/com.itextpdf/layout/index.json index 09545fe27..4019110df 100644 --- a/metadata/com.itextpdf/layout/index.json +++ b/metadata/com.itextpdf/layout/index.json @@ -1,6 +1,5 @@ [ { - "latest": true, "metadata-version": "8.0.3", "module": "com.itextpdf:layout", "tested-versions": [ diff --git a/metadata/com.itextpdf/svg/index.json b/metadata/com.itextpdf/svg/index.json index 0ef68772d..27cd14a5a 100644 --- a/metadata/com.itextpdf/svg/index.json +++ b/metadata/com.itextpdf/svg/index.json @@ -1,6 +1,5 @@ [ { - "latest": true, "metadata-version": "8.0.3", "module": "com.itextpdf:svg", "tested-versions": [ From 3e538b2aba8c6351a389d409e126e18c1c2835db Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Mon, 28 Oct 2024 10:55:37 +0100 Subject: [PATCH 03/23] Fix function call after refactoring --- .github/workflows/check-new-library-versions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-new-library-versions.yml b/.github/workflows/check-new-library-versions.yml index 41d23d712..ee2cc7b4b 100644 --- a/.github/workflows/check-new-library-versions.yml +++ b/.github/workflows/check-new-library-versions.yml @@ -38,7 +38,7 @@ jobs: - name: "πŸ•ΈοΈ Populate matrix" id: set-matrix run: | - ./gradlew getExistingLibraries + ./gradlew getExistingLibrariesWithNewVersions - name: "Create branch" run: | git config --local user.email "actions@github.com" From f1f45fb0549d4fbf0055ba7d5849e5f3f4199349 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Mon, 28 Oct 2024 11:54:51 +0100 Subject: [PATCH 04/23] Fix task registration after refactoring --- .../src/main/groovy/org.graalvm.internal.tck-harness.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 53e3a2a37..3c5d35977 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 @@ -113,7 +113,7 @@ List getNewerVersionsFor(String library, String startingVersion) { } // gradle getExistingLibrariesWithNewVersions -Provider getExistingLibrariesWithNewVersions = tasks.register("getExistingLibraries", DefaultTask) { task -> +Provider getExistingLibrariesWithNewVersions = tasks.register("getExistingLibrariesWithNewVersions", DefaultTask) { task -> task.setDescription("Returns list of all libraries coordinates") task.setGroup(METADATA_GROUP) task.doFirst { From 289954e6eb71d7736f5066c827cdc37d56a9728f Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Mon, 28 Oct 2024 12:16:26 +0100 Subject: [PATCH 05/23] Reduce number of jobs to pass github limitations --- .../main/groovy/org.graalvm.internal.tck-harness.gradle | 7 +++---- 1 file changed, 3 insertions(+), 4 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 3c5d35977..95ed7ed20 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 @@ -133,10 +133,9 @@ Provider getExistingLibrariesWithNewVersions = tasks.register("getExisting } } - // workflows limitation to only accept up to 255 parallel jobs - if (newerVersions.size() > 254) { - // for testing we will keep 5, and return to 255 once everything work - newerVersions = newerVersions.subList(0, 254) + // save github resources as workflows has limitation to only accept up to 255 parallel jobs + if (newerVersions.size() > 200) { + newerVersions = newerVersions.subList(0, 200) } def matrix = [ From 43df0e04f0abc8264191a5705fbfc411ae0b6653 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Mon, 28 Oct 2024 13:02:35 +0100 Subject: [PATCH 06/23] Use simple matrix --- .../src/main/groovy/org.graalvm.internal.tck-harness.gradle | 5 +++-- 1 file changed, 3 insertions(+), 2 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 95ed7ed20..c332c8fdd 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 @@ -139,9 +139,10 @@ Provider getExistingLibrariesWithNewVersions = tasks.register("getExisting } def matrix = [ - "coordinates": newerVersions + "coordinates" : newerVersions, + "version" : ["17"], + "os" : ["ubuntu-latest"] ] - matrix.putAll(matrixDefault) println "::set-output name=matrix::${JsonOutput.toJson(matrix)}" } From 38b848c614c8ed09c703c790484822776165a0b8 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Tue, 29 Oct 2024 11:32:26 +0100 Subject: [PATCH 07/23] Use env variable to specify library version --- .github/workflows/check-new-library-versions.yml | 8 +++----- .../src/main/groovy/org.graalvm.internal.tck.gradle | 2 +- .../tck/harness/tasks/AbstractSubprojectTask.groovy | 5 ++++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/check-new-library-versions.yml b/.github/workflows/check-new-library-versions.yml index ee2cc7b4b..b57008fbf 100644 --- a/.github/workflows/check-new-library-versions.yml +++ b/.github/workflows/check-new-library-versions.yml @@ -103,14 +103,12 @@ jobs: sudo bash -c "cat ./.github/workflows/dockerd.service > /etc/systemd/system/docker.service.d/http-proxy.conf" sudo systemctl daemon-reload sudo systemctl restart docker - - name: "Replace version" - run: | - CURRENT_VERSION=$(echo ${{ matrix.coordinates }} | cut -d ":" -f3) - sed -i "s/library.version\s*=\s*${{ env.LATEST_VERSION }}/library.version = $CURRENT_VERSION/g" tests/src/${{ env.TEST_PATH }}/gradle.properties - name: "πŸ§ͺ Run '${{ env.TEST_COORDINATES }}' tests" run: | + TESTING_VERSION=$(echo ${{ matrix.coordinates }} | cut -d ":" -f3) + export GVM_TCK_LV=TESTING_VERSION + ./gradlew test -Pcoordinates=${{ env.TEST_COORDINATES }} - git stash - name: "New library is supported" if: success() run: | diff --git a/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck.gradle b/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck.gradle index 13b73f05c..7c413161c 100644 --- a/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck.gradle +++ b/tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck.gradle @@ -42,7 +42,7 @@ String metadataPath = Objects.requireNonNullElse( providers.gradleProperty('metadata.dir').get() ) -String libraryVersion = providers.gradleProperty('library.version').get() ?: System.getenv("GVM_TCK_LV") +String libraryVersion = System.getenv("GVM_TCK_LV") ?: providers.gradleProperty('library.version').get() String libraryGAV = System.getenv("GVM_TCK_LC") ?: providers.gradleProperty('library.coordinates').getOrElse(null) libraryGAV = libraryGAV ?: "" diff --git a/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/tasks/AbstractSubprojectTask.groovy b/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/tasks/AbstractSubprojectTask.groovy index e41c58761..8940a5ca4 100644 --- a/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/tasks/AbstractSubprojectTask.groovy +++ b/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/tasks/AbstractSubprojectTask.groovy @@ -93,7 +93,10 @@ abstract class AbstractSubprojectTask extends DefaultTask { // Environment variables for setting up TCK env.put("GVM_TCK_LC", coordinates) env.put("GVM_TCK_EXCLUDE", override.toString()) - env.put("GVM_TCK_LV", version) + if (System.getenv("GVM_TCK_LV") == null) { + // we only set this env variable if user didn't specify it manually + env.put("GVM_TCK_LV", version) + } env.put("GVM_TCK_MD", metadataDir.toAbsolutePath().toString()) env.put("GVM_TCK_TCKDIR", tckExtension.getTckRoot().get().getAsFile().toPath().toAbsolutePath().toString()) spec.environment(env) From 00006aa5c22fe4ef3aa54b120311559b38b90a71 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Tue, 29 Oct 2024 12:03:31 +0100 Subject: [PATCH 08/23] Find update entry based on the latest supported version --- .github/workflows/check-new-library-versions.yml | 4 ++-- .github/workflows/tryPushVersionsUpdate.sh | 2 +- .../graalvm/internal/tck/TestedVersionUpdaterTask.java | 9 ++++++++- .../internal/tck/model/MetadataVersionsIndexEntry.java | 1 + 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check-new-library-versions.yml b/.github/workflows/check-new-library-versions.yml index b57008fbf..556fa7fab 100644 --- a/.github/workflows/check-new-library-versions.yml +++ b/.github/workflows/check-new-library-versions.yml @@ -106,13 +106,13 @@ jobs: - name: "πŸ§ͺ Run '${{ env.TEST_COORDINATES }}' tests" run: | TESTING_VERSION=$(echo ${{ matrix.coordinates }} | cut -d ":" -f3) - export GVM_TCK_LV=TESTING_VERSION + export GVM_TCK_LV=$TESTING_VERSION ./gradlew test -Pcoordinates=${{ env.TEST_COORDINATES }} - name: "New library is supported" if: success() run: | - sh ./.github/workflows/tryPushVersionsUpdate.sh ${{ matrix.coordinates }} + sh ./.github/workflows/tryPushVersionsUpdate.sh ${{ matrix.coordinates }} ${{ env.LATEST_VERSION }} - name: "New library is not supported" if: failure() run: | diff --git a/.github/workflows/tryPushVersionsUpdate.sh b/.github/workflows/tryPushVersionsUpdate.sh index c0fbc67b6..9b8a8e8df 100644 --- a/.github/workflows/tryPushVersionsUpdate.sh +++ b/.github/workflows/tryPushVersionsUpdate.sh @@ -10,7 +10,7 @@ git checkout "$BRANCH" while [ true ] do - ./gradlew addTestedVersion --coordinates="$1" + ./gradlew addTestedVersion --coordinates="$1" --lastSupportedVersion="$2" git add -u git commit -m "$1" if [ "$(git rev-list --count origin/$BRANCH --not $BRANCH)" -eq 0 ] diff --git a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java index 8dd1efd53..9c7d14533 100644 --- a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java +++ b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java @@ -29,7 +29,14 @@ void setCoordinates(String coordinates) { this.coordinates = coordinates; } + @Option(option = "lastSupportedVersion", description = "Last version of the library that passed tests") + void setLastSupportedVersion(String version) { + this.lastSupportedVersion = version; + } + private String coordinates; + private String lastSupportedVersion; + @SuppressWarnings("unchecked") @TaskAction @@ -52,7 +59,7 @@ private void addToMetadataIndexJson(Coordinates c) throws IOException { }); for (MetadataVersionsIndexEntry entry : entries) { - if (entry.latest() != null && entry.latest()) { + if (entry.testedVersions().contains(lastSupportedVersion)) { entry.testedVersions().add(c.version()); entry.testedVersions().sort(Comparator.comparing(VersionNumber::parse)); } diff --git a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/model/MetadataVersionsIndexEntry.java b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/model/MetadataVersionsIndexEntry.java index ad0a31e95..ce2e28132 100644 --- a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/model/MetadataVersionsIndexEntry.java +++ b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/model/MetadataVersionsIndexEntry.java @@ -6,6 +6,7 @@ public record MetadataVersionsIndexEntry ( Boolean latest, + Boolean override, String module, @JsonProperty("default-for") String defaultFor, From ba22a17e8f7581f629de3ec012563add9c0dcd47 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 30 Oct 2024 14:25:09 +0100 Subject: [PATCH 09/23] Use jackson to parse index file when fetching latest version --- .../internal/tck/harness/TckExtension.java | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) 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 c5300f2cb..76f7c58d4 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 @@ -6,6 +6,12 @@ */ package org.graalvm.internal.tck.harness; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import org.graalvm.internal.tck.CoordinateUtils; +import org.graalvm.internal.tck.model.MetadataVersionsIndexEntry; import org.gradle.api.Project; import org.gradle.api.file.Directory; import org.gradle.api.file.DirectoryProperty; @@ -17,6 +23,7 @@ import javax.inject.Inject; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.net.URI; import java.nio.charset.StandardCharsets; @@ -349,21 +356,34 @@ List getMetadataFileList(Path directory) throws IOException { } @SuppressWarnings("unchecked") - String getLatestLibraryVersion(String module) { - String libraryIndex = module.replace(":", "/"); - List allTested = new ArrayList<>(); - List> index = (List>) readIndexFile(metadataRoot().resolve(libraryIndex)); - for (Map entry : index) { - List testedVersions = (List) entry.get("tested-versions"); - allTested.addAll(testedVersions); - } + String getLatestLibraryVersion(String libraryModule) { + try { + List coordinates = List.of(libraryModule.split(":")); + String group = coordinates.get(0); + String artifact = coordinates.get(1); + + File coordinatesMetadataIndex = new File("metadata/" + group + "/" + artifact +"/index.json"); + ObjectMapper objectMapper = new ObjectMapper() + .enable(SerializationFeature.INDENT_OUTPUT) + .setSerializationInclusion(JsonInclude.Include.NON_NULL); + + List entries = objectMapper.readValue(coordinatesMetadataIndex, new TypeReference<>() { + }); + + List allTested = new ArrayList<>(); + for (MetadataVersionsIndexEntry entry : entries) { + allTested.addAll(entry.testedVersions()); + } - if (allTested.isEmpty()) { - throw new RuntimeException("Cannot find any tested version for: " + module); - } + if (allTested.isEmpty()) { + throw new IllegalStateException("Cannot find any tested version for: " + libraryModule); + } - allTested.sort(Comparator.comparing(VersionNumber::parse)); - return allTested.get(allTested.size() - 1); + allTested.sort(Comparator.comparing(VersionNumber::parse)); + return allTested.get(allTested.size() - 1); + } catch (IOException e) { + throw new RuntimeException(e); + } } List getNewerVersionsFromLibraryIndex(String index, String startingVersion, String libraryName) { From 2a338c92301576d355ebfd787e2553375be3a456 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 30 Oct 2024 14:27:54 +0100 Subject: [PATCH 10/23] Remove unused import --- .../groovy/org/graalvm/internal/tck/harness/TckExtension.java | 1 - 1 file changed, 1 deletion(-) 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 76f7c58d4..981faae8d 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 @@ -10,7 +10,6 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import org.graalvm.internal.tck.CoordinateUtils; import org.graalvm.internal.tck.model.MetadataVersionsIndexEntry; import org.gradle.api.Project; import org.gradle.api.file.Directory; From 0841c013654f8a932353faaceba10fb7e0972a97 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 30 Oct 2024 14:36:31 +0100 Subject: [PATCH 11/23] Improve workflow steps titles --- .github/workflows/check-new-library-versions.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/check-new-library-versions.yml b/.github/workflows/check-new-library-versions.yml index 556fa7fab..1bcdf9867 100644 --- a/.github/workflows/check-new-library-versions.yml +++ b/.github/workflows/check-new-library-versions.yml @@ -17,7 +17,7 @@ concurrency: jobs: get-all-libraries: if: github.repository == 'oracle/graalvm-reachability-metadata' - name: "πŸ“‹ Get list of all supported libraries" + name: "πŸ“‹ Get list of all supported libraries with newer versions" permissions: write-all runs-on: "ubuntu-20.04" timeout-minutes: 5 @@ -39,13 +39,13 @@ jobs: id: set-matrix run: | ./gradlew getExistingLibrariesWithNewVersions - - name: "Create branch" + - name: "πŸ”¨ Create branch" run: | git config --local user.email "actions@github.com" git config --local user.name "Github Actions" git switch -C libraryVersionsDependabot/$(date '+%Y-%m-%d') git push origin libraryVersionsDependabot/$(date '+%Y-%m-%d') - - name: "Create issue" + - name: "πŸ”¨ Create issue" id: set-issue run: | git config --local user.email "actions@github.com" @@ -109,11 +109,11 @@ jobs: export GVM_TCK_LV=$TESTING_VERSION ./gradlew test -Pcoordinates=${{ env.TEST_COORDINATES }} - - name: "New library is supported" + - name: "βœ”οΈ New library is supported" if: success() run: | sh ./.github/workflows/tryPushVersionsUpdate.sh ${{ matrix.coordinates }} ${{ env.LATEST_VERSION }} - - name: "New library is not supported" + - name: "❗ New library is not supported" if: failure() run: | git config --local user.email "actions@github.com" @@ -133,7 +133,7 @@ jobs: steps: - name: "☁️ Checkout repository" uses: actions/checkout@v4 - - name: "PR for supported versions" + - name: "✏️ PR for supported versions" run: | git config --local user.email "actions@github.com" git config --local user.name "Github Actions" From 2f8cac8f4f12c5116be56caac558f9485db6c8c7 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 30 Oct 2024 15:03:58 +0100 Subject: [PATCH 12/23] Remove suppress warnings after refactoring --- .../groovy/org/graalvm/internal/tck/harness/TckExtension.java | 1 - 1 file changed, 1 deletion(-) 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 981faae8d..52ac4997d 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 @@ -354,7 +354,6 @@ List getMetadataFileList(Path directory) throws IOException { } } - @SuppressWarnings("unchecked") String getLatestLibraryVersion(String libraryModule) { try { List coordinates = List.of(libraryModule.split(":")); From 39b989889a913c1dc15b84097034e5da4520d805 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Tue, 5 Nov 2024 16:38:13 +0100 Subject: [PATCH 13/23] Extract github limitations as parameter of the gradle task --- .github/workflows/check-new-library-versions.yml | 2 +- .../org.graalvm.internal.tck-harness.gradle | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check-new-library-versions.yml b/.github/workflows/check-new-library-versions.yml index 1bcdf9867..afe436838 100644 --- a/.github/workflows/check-new-library-versions.yml +++ b/.github/workflows/check-new-library-versions.yml @@ -38,7 +38,7 @@ jobs: - name: "πŸ•ΈοΈ Populate matrix" id: set-matrix run: | - ./gradlew getExistingLibrariesWithNewVersions + ./gradlew getExistingLibrariesWithNewVersions -PlibraryMatrixLimit=200 - name: "πŸ”¨ Create branch" run: | git config --local user.email "actions@github.com" 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 c332c8fdd..fa3c25bab 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 @@ -117,15 +117,22 @@ Provider getExistingLibrariesWithNewVersions = tasks.register("getExisting task.setDescription("Returns list of all libraries coordinates") task.setGroup(METADATA_GROUP) task.doFirst { + if (!project.hasProperty("libraryMatrixLimit")) { + throw new IllegalArgumentException("Please provide the maximum number of libraries versions!") + } + + // get all existing libraries Set libraries = [] matchingCoordinates.forEach { libraries.add(it.substring(0, it.lastIndexOf(":"))) } + // foreach existing library find newer versions than the latest one tested except for infrastructure tests + List infrastructureTests = List.of("samples", "org.example") List newerVersions = new ArrayList<>() libraries.forEach { String libraryName = it - if (!libraryName.contains("samples") && !libraryName.contains("example")) { + if (infrastructureTests.stream().noneMatch(testName -> libraryName.startsWith(testName))) { List versions = getNewerVersionsFor(libraryName, tck.getLatestLibraryVersion(libraryName)) versions.forEach { newerVersions.add(libraryName.concat(":").concat(it)) @@ -133,9 +140,10 @@ Provider getExistingLibrariesWithNewVersions = tasks.register("getExisting } } - // save github resources as workflows has limitation to only accept up to 255 parallel jobs - if (newerVersions.size() > 200) { - newerVersions = newerVersions.subList(0, 200) + // number of discovered versions is potentially huge and we want to limit it + int limit = Integer.parseInt((String) project.findProperty("libraryMatrixLimit")) + if (newerVersions.size() > limit) { + newerVersions = newerVersions.subList(0, limit) } def matrix = [ From e9f0783b07a10192bc6a393807d7c669b39ce27c Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 6 Nov 2024 13:55:33 +0100 Subject: [PATCH 14/23] Remove unused suppress --- .../java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java index 9c7d14533..09b0cca6b 100644 --- a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java +++ b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java @@ -38,7 +38,6 @@ void setLastSupportedVersion(String version) { private String lastSupportedVersion; - @SuppressWarnings("unchecked") @TaskAction void run() throws IllegalStateException, IOException { List GAVCoordinates = Arrays.stream(coordinates.split(":")).toList(); From fd7370034b96d5aa4e1e748289ef344de14b7b7b Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Thu, 7 Nov 2024 14:04:37 +0100 Subject: [PATCH 15/23] Use different PR branch name --- .github/workflows/check-new-library-versions.yml | 8 ++++---- .github/workflows/tryPushVersionsUpdate.sh | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check-new-library-versions.yml b/.github/workflows/check-new-library-versions.yml index afe436838..dd70702f4 100644 --- a/.github/workflows/check-new-library-versions.yml +++ b/.github/workflows/check-new-library-versions.yml @@ -43,8 +43,8 @@ jobs: run: | git config --local user.email "actions@github.com" git config --local user.name "Github Actions" - git switch -C libraryVersionsDependabot/$(date '+%Y-%m-%d') - git push origin libraryVersionsDependabot/$(date '+%Y-%m-%d') + git switch -C check-new-library-versions/$(date '+%Y-%m-%d') + git push origin check-new-library-versions/$(date '+%Y-%m-%d') - name: "πŸ”¨ Create issue" id: set-issue run: | @@ -137,6 +137,6 @@ jobs: run: | git config --local user.email "actions@github.com" git config --local user.name "Github Actions" - git fetch origin libraryVersionsDependabot/$(date '+%Y-%m-%d') - git checkout libraryVersionsDependabot/$(date '+%Y-%m-%d') + git fetch origin check-new-library-versions/$(date '+%Y-%m-%d') + git checkout check-new-library-versions/$(date '+%Y-%m-%d') gh pr create --title "Update supported library versions" --body "This pull request updates supported versions of the existing libraries in the repo" \ No newline at end of file diff --git a/.github/workflows/tryPushVersionsUpdate.sh b/.github/workflows/tryPushVersionsUpdate.sh index 9b8a8e8df..090511ead 100644 --- a/.github/workflows/tryPushVersionsUpdate.sh +++ b/.github/workflows/tryPushVersionsUpdate.sh @@ -4,7 +4,7 @@ set -x git config --local user.email "actions@github.com" git config --local user.name "Github Actions" -BRANCH="libraryVersionsDependabot/$(date '+%Y-%m-%d')" +BRANCH="check-new-library-versions/$(date '+%Y-%m-%d')" git fetch origin "$BRANCH" git checkout "$BRANCH" From 678eff620a683b7380254719f3124b0d145b3622 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Thu, 7 Nov 2024 14:16:40 +0100 Subject: [PATCH 16/23] Use bash instead of sh to invoke push script --- .github/workflows/check-new-library-versions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-new-library-versions.yml b/.github/workflows/check-new-library-versions.yml index dd70702f4..b8085016a 100644 --- a/.github/workflows/check-new-library-versions.yml +++ b/.github/workflows/check-new-library-versions.yml @@ -112,7 +112,7 @@ jobs: - name: "βœ”οΈ New library is supported" if: success() run: | - sh ./.github/workflows/tryPushVersionsUpdate.sh ${{ matrix.coordinates }} ${{ env.LATEST_VERSION }} + bash ./.github/workflows/tryPushVersionsUpdate.sh ${{ matrix.coordinates }} ${{ env.LATEST_VERSION }} - name: "❗ New library is not supported" if: failure() run: | From a133fc4a139c428f36d4d90eec21c78da76f1e1d Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Thu, 7 Nov 2024 14:24:32 +0100 Subject: [PATCH 17/23] Add comments into the tryPush script --- .github/workflows/tryPushVersionsUpdate.sh | 27 +++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/.github/workflows/tryPushVersionsUpdate.sh b/.github/workflows/tryPushVersionsUpdate.sh index 090511ead..4d807c3bd 100644 --- a/.github/workflows/tryPushVersionsUpdate.sh +++ b/.github/workflows/tryPushVersionsUpdate.sh @@ -1,4 +1,11 @@ #!/bin/bash +:' This script tries to run addTestedVersion gradle task which adds new version in the tested-versions list of the proper index.json file. +Since the script could be executed from multiple parallel jobs, we want to avoid two things here: overwriting of previous changes and merge conflicts. +To prevent overwriting of changes that some job already created, we only push changes from the current job if we are 0 commits behind the origin branch. +Once that is achieved, we can try to push changes. +If the push was rejected because of a merge conflict, we are: removing changes of the current job, rebasing, and doing the process again until it succeeds. +' + set -x git config --local user.email "actions@github.com" @@ -10,19 +17,27 @@ git checkout "$BRANCH" while [ true ] do + # update the list of tested versions ./gradlew addTestedVersion --coordinates="$1" --lastSupportedVersion="$2" + + # commit changes git add -u git commit -m "$1" + + # only push changes if we are not behind the remote branch if [ "$(git rev-list --count origin/$BRANCH --not $BRANCH)" -eq 0 ] then - git push origin "$BRANCH" - PUSH_RETVAL=$? - if [ "$PUSH_RETVAL" -eq 0 ] - then - break - fi + # try to push changes + git push origin "$BRANCH" + PUSH_RETVAL=$? + if [ "$PUSH_RETVAL" -eq 0 ] + then + # if the push was successful, we can exit the loop + break + fi fi + # we are either behind the remote branch or we have a merge conflict => remove changes and rebase accepting incoming changes git reset --hard HEAD~1 git fetch origin "$BRANCH" git rebase -X theirs "origin/$BRANCH" From fbba24291b62fef1194f38ee6500cdc8ce678961 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Thu, 7 Nov 2024 14:27:54 +0100 Subject: [PATCH 18/23] Always extract coordinates part in the same way --- .../groovy/org.graalvm.internal.tck-harness.gradle | 5 +++-- .../graalvm/internal/tck/harness/TckExtension.java | 6 +++--- .../internal/tck/TestedVersionUpdaterTask.java | 11 +++++------ 3 files changed, 11 insertions(+), 11 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 fa3c25bab..d1271fad2 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 @@ -105,8 +105,9 @@ final String METADATA_GROUP = "Metadata" List getNewerVersionsFor(String library, String startingVersion) { def baseUrl = "https://repo1.maven.org/maven2" - String group = library.split(":")[0].replace(".", "/") - String artifact = library.split(":")[1] + String[] libraryParts = library.split(":") + String group = libraryParts[0].replace(".", "/") + String artifact = libraryParts[1] def data = new URL(baseUrl + "/" + group + "/" + artifact + "/" + "maven-metadata.xml").getText() return tck.getNewerVersionsFromLibraryIndex(data, startingVersion, library) 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 52ac4997d..d6ae9edcc 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 @@ -356,9 +356,9 @@ List getMetadataFileList(Path directory) throws IOException { String getLatestLibraryVersion(String libraryModule) { try { - List coordinates = List.of(libraryModule.split(":")); - String group = coordinates.get(0); - String artifact = coordinates.get(1); + String[] coordinates = libraryModule.split(":"); + String group = coordinates[0]; + String artifact = coordinates[1]; File coordinatesMetadataIndex = new File("metadata/" + group + "/" + artifact +"/index.json"); ObjectMapper objectMapper = new ObjectMapper() diff --git a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java index 09b0cca6b..ad39ab896 100644 --- a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java +++ b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java @@ -40,14 +40,13 @@ void setLastSupportedVersion(String version) { @TaskAction void run() throws IllegalStateException, IOException { - List GAVCoordinates = Arrays.stream(coordinates.split(":")).toList(); - if (GAVCoordinates.size() != 3) { + String[] coordinatesParts = coordinates.split(":"); + if (coordinatesParts.length != 3) { throw new IllegalArgumentException("Maven coordinates should have 3 parts"); } - - String group = GAVCoordinates.get(0); - String artifact = GAVCoordinates.get(1); - String version = GAVCoordinates.get(2); + String group = coordinatesParts[0]; + String artifact = coordinatesParts[1]; + String version = coordinatesParts[2]; Coordinates c = new Coordinates(group, artifact, version); addToMetadataIndexJson(c); } From d76a418792322fe63ebe1feceb87fa6f954be58b Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Fri, 8 Nov 2024 13:48:20 +0100 Subject: [PATCH 19/23] Extract gradle task for fetching newer versions --- .../workflows/check-new-library-versions.yml | 2 +- .../org.graalvm.internal.tck-harness.gradle | 63 ++------- ...hExistingLibrariesWithNewerVersions.groovy | 130 ++++++++++++++++++ .../internal/tck/harness/TckExtension.java | 63 +-------- 4 files changed, 142 insertions(+), 116 deletions(-) create mode 100644 tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tasks/FetchExistingLibrariesWithNewerVersions.groovy diff --git a/.github/workflows/check-new-library-versions.yml b/.github/workflows/check-new-library-versions.yml index b8085016a..f94046584 100644 --- a/.github/workflows/check-new-library-versions.yml +++ b/.github/workflows/check-new-library-versions.yml @@ -38,7 +38,7 @@ jobs: - name: "πŸ•ΈοΈ Populate matrix" id: set-matrix run: | - ./gradlew getExistingLibrariesWithNewVersions -PlibraryMatrixLimit=200 + ./gradlew fetchExistingLibrariesWithNewerVersions --matrixLimit=200 - name: "πŸ”¨ Create branch" run: | git config --local user.email "actions@github.com" 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 d1271fad2..5d7dec14d 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 @@ -10,6 +10,7 @@ plugins { } import groovy.json.JsonOutput +import org.graalvm.internal.tasks.FetchExistingLibrariesWithNewerVersions import org.graalvm.internal.tck.DockerTask import org.graalvm.internal.tck.ConfigFilesChecker import org.graalvm.internal.tck.ScaffoldTask @@ -103,60 +104,6 @@ def matrixDefault = [ final String METADATA_GROUP = "Metadata" -List getNewerVersionsFor(String library, String startingVersion) { - def baseUrl = "https://repo1.maven.org/maven2" - String[] libraryParts = library.split(":") - String group = libraryParts[0].replace(".", "/") - String artifact = libraryParts[1] - def data = new URL(baseUrl + "/" + group + "/" + artifact + "/" + "maven-metadata.xml").getText() - - return tck.getNewerVersionsFromLibraryIndex(data, startingVersion, library) -} - -// gradle getExistingLibrariesWithNewVersions -Provider getExistingLibrariesWithNewVersions = tasks.register("getExistingLibrariesWithNewVersions", DefaultTask) { task -> - task.setDescription("Returns list of all libraries coordinates") - task.setGroup(METADATA_GROUP) - task.doFirst { - if (!project.hasProperty("libraryMatrixLimit")) { - throw new IllegalArgumentException("Please provide the maximum number of libraries versions!") - } - - // get all existing libraries - Set libraries = [] - matchingCoordinates.forEach { - libraries.add(it.substring(0, it.lastIndexOf(":"))) - } - - // foreach existing library find newer versions than the latest one tested except for infrastructure tests - List infrastructureTests = List.of("samples", "org.example") - List newerVersions = new ArrayList<>() - libraries.forEach { - String libraryName = it - if (infrastructureTests.stream().noneMatch(testName -> libraryName.startsWith(testName))) { - List versions = getNewerVersionsFor(libraryName, tck.getLatestLibraryVersion(libraryName)) - versions.forEach { - newerVersions.add(libraryName.concat(":").concat(it)) - } - } - } - - // number of discovered versions is potentially huge and we want to limit it - int limit = Integer.parseInt((String) project.findProperty("libraryMatrixLimit")) - if (newerVersions.size() > limit) { - newerVersions = newerVersions.subList(0, limit) - } - - def matrix = [ - "coordinates" : newerVersions, - "version" : ["17"], - "os" : ["ubuntu-latest"] - ] - - println "::set-output name=matrix::${JsonOutput.toJson(matrix)}" - } -} - // gradle generateMatrixMatchingCoordinates -Pcoordinates= Provider generateMatrixMatchingCoordinates = tasks.register("generateMatrixMatchingCoordinates", DefaultTask) { task -> task.setDescription("Returns matrix definition populated with all matching coordinates") @@ -216,6 +163,14 @@ Provider generateMatrixDiffCoordinates = tasks.register("generateMatrixDif } } +// groovy tasks +tasks.register("fetchExistingLibrariesWithNewerVersions", FetchExistingLibrariesWithNewerVersions.class) { task -> + task.setGroup(METADATA_GROUP) + task.setDescription("Returns list of all libraries coordinates") + task.setAllLibraryCoordinates(matchingCoordinates) +} + +// java tasks tasks.register("checkAllowedDockerImages", GrypeTask.class) { task -> task.setDescription("Returns list of allowed docker images") task.setGroup(METADATA_GROUP) diff --git a/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tasks/FetchExistingLibrariesWithNewerVersions.groovy b/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tasks/FetchExistingLibrariesWithNewerVersions.groovy new file mode 100644 index 000000000..455f23223 --- /dev/null +++ b/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tasks/FetchExistingLibrariesWithNewerVersions.groovy @@ -0,0 +1,130 @@ +package org.graalvm.internal.tasks + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.core.type.TypeReference +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.SerializationFeature +import groovy.json.JsonOutput +import org.graalvm.internal.tck.model.MetadataVersionsIndexEntry +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.options.Option +import org.gradle.util.internal.VersionNumber + +import java.util.regex.Matcher +import java.util.regex.Pattern + + +abstract class FetchExistingLibrariesWithNewerVersions extends DefaultTask { + + @Input + List allLibraryCoordinates + + @Input + @Option(option = "matrixLimit", description = "Sets the maximum number of coordinates in the final matrix") + Integer matrixLimit + + private static final List INFRASTRUCTURE_TESTS = List.of("samples", "org.example") + + @TaskAction + void action() { + // get all existing libraries + Set libraries = [] + allLibraryCoordinates.forEach { + libraries.add(it.substring(0, it.lastIndexOf(":"))) + } + + // foreach existing library find newer versions than the latest one tested except for infrastructure tests + List newerVersions = new ArrayList<>() + libraries.forEach { + String libraryName = it + if (INFRASTRUCTURE_TESTS.stream().noneMatch(testName -> libraryName.startsWith(testName))) { + List versions = getNewerVersionsFor(libraryName, getLatestLibraryVersion(libraryName)) + versions.forEach { + newerVersions.add(libraryName.concat(":").concat(it)) + } + } + } + + if (newerVersions.size() > getMatrixLimit()) { + newerVersions = newerVersions.subList(0, getMatrixLimit()) + } + + def matrix = [ + "coordinates": newerVersions, + "version" : ["17"], + "os" : ["ubuntu-latest"] + ] + + println "::set-output name=matrix::${JsonOutput.toJson(matrix)}" + } + + static List getNewerVersionsFor(String library, String startingVersion) { + def baseUrl = "https://repo1.maven.org/maven2" + String[] libraryParts = library.split(":") + String group = libraryParts[0].replace(".", "/") + String artifact = libraryParts[1] + def data = new URL(baseUrl + "/" + group + "/" + artifact + "/" + "maven-metadata.xml").getText() + + return getNewerVersionsFromLibraryIndex(data, startingVersion, library) + } + + static List getNewerVersionsFromLibraryIndex(String index, String startingVersion, String libraryName) { + Pattern pattern = Pattern.compile("(.*)"); + Matcher matcher = pattern.matcher(index); + List allVersions = new ArrayList<>(); + + if (matcher.groupCount() < 1) { + throw new RuntimeException("Cannot find versions in the given index file: " + libraryName); + } + + while (matcher.find()) { + allVersions.add(matcher.group(1)); + } + + int indexOfStartingVersion = allVersions.indexOf(startingVersion); + if (indexOfStartingVersion < 0) { + System.out.println("Cannot find starting version in index file: " + libraryName + " for version " + startingVersion); + return new ArrayList<>(); + } + + allVersions = allVersions.subList(indexOfStartingVersion, allVersions.size()); + if (allVersions.size() <= 1) { + System.out.println("Cannot find newer versions for " + libraryName + " after the version " + startingVersion); + } + + return allVersions.subList(1, allVersions.size()); + } + + static String getLatestLibraryVersion(String libraryModule) { + try { + String[] coordinates = libraryModule.split(":"); + String group = coordinates[0]; + String artifact = coordinates[1]; + + File coordinatesMetadataIndex = new File("metadata/" + group + "/" + artifact +"/index.json"); + ObjectMapper objectMapper = new ObjectMapper() + .enable(SerializationFeature.INDENT_OUTPUT) + .setSerializationInclusion(JsonInclude.Include.NON_NULL); + + List entries = objectMapper.readValue(coordinatesMetadataIndex, new TypeReference>() { + }); + + List allTested = new ArrayList<>(); + for (MetadataVersionsIndexEntry entry : entries) { + allTested.addAll(entry.testedVersions()); + } + + if (allTested.isEmpty()) { + throw new IllegalStateException("Cannot find any tested version for: " + libraryModule); + } + + allTested.sort(Comparator.comparing(VersionNumber::parse)); + return allTested.get(allTested.size() - 1); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} 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 d6ae9edcc..bf2c4fc38 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 @@ -301,9 +301,7 @@ List getMatchingCoordinates(String coordinateFilter) { String artifactId = strings.get(1); String version = strings.get(2); - Set matchingCoordinates = new HashSet<>(); - for (String directory : getMatchingMetadataDirs(groupId, artifactId)) { Path index = metadataRoot().resolve(directory).resolve("index.json"); List> metadataIndex = (List>) extractJsonFile(index); @@ -324,7 +322,8 @@ List getMatchingCoordinates(String coordinateFilter) { } } } - return matchingCoordinates.stream().collect(Collectors.toList()); + + return new ArrayList<>(matchingCoordinates); } /** @@ -353,62 +352,4 @@ List getMetadataFileList(Path directory) throws IOException { return foundFiles; } } - - String getLatestLibraryVersion(String libraryModule) { - try { - String[] coordinates = libraryModule.split(":"); - String group = coordinates[0]; - String artifact = coordinates[1]; - - File coordinatesMetadataIndex = new File("metadata/" + group + "/" + artifact +"/index.json"); - ObjectMapper objectMapper = new ObjectMapper() - .enable(SerializationFeature.INDENT_OUTPUT) - .setSerializationInclusion(JsonInclude.Include.NON_NULL); - - List entries = objectMapper.readValue(coordinatesMetadataIndex, new TypeReference<>() { - }); - - List allTested = new ArrayList<>(); - for (MetadataVersionsIndexEntry entry : entries) { - allTested.addAll(entry.testedVersions()); - } - - if (allTested.isEmpty()) { - throw new IllegalStateException("Cannot find any tested version for: " + libraryModule); - } - - allTested.sort(Comparator.comparing(VersionNumber::parse)); - return allTested.get(allTested.size() - 1); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - List getNewerVersionsFromLibraryIndex(String index, String startingVersion, String libraryName) { - Pattern pattern = Pattern.compile("(.*)"); - Matcher matcher = pattern.matcher(index); - List allVersions = new ArrayList<>(); - - if (matcher.groupCount() < 1) { - throw new RuntimeException("Cannot find versions in the given index file: " + libraryName); - } - - while (matcher.find()) { - allVersions.add(matcher.group(1)); - } - - int indexOfStartingVersion = allVersions.indexOf(startingVersion); - if (indexOfStartingVersion < 0) { - System.out.println("Cannot find starting version in index file: " + libraryName + " for version " + startingVersion); - return new ArrayList<>(); - } - - allVersions = allVersions.subList(indexOfStartingVersion, allVersions.size()); - if (allVersions.size() <= 1) { - System.out.println("Cannot find newer versions for " + libraryName + " after the version " + startingVersion); - } - - return allVersions.subList(1, allVersions.size()); - } - } From 7a7824d762b9878d509f4ff1837c6d3ccc8c3473 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Fri, 8 Nov 2024 14:43:49 +0100 Subject: [PATCH 20/23] Properly add Input and Output anotations to the updater task --- .../org.graalvm.internal.tck-harness.gradle | 4 +- ...tingLibrariesWithNewerVersionsTask.groovy} | 5 +- .../tck/TestedVersionUpdaterTask.java | 57 +++++++++---------- 3 files changed, 33 insertions(+), 33 deletions(-) rename tests/tck-build-logic/src/main/groovy/org/graalvm/internal/{tasks/FetchExistingLibrariesWithNewerVersions.groovy => tck/harness/tasks/FetchExistingLibrariesWithNewerVersionsTask.groovy} (97%) 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 5d7dec14d..e26864c9b 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 @@ -10,13 +10,13 @@ plugins { } import groovy.json.JsonOutput -import org.graalvm.internal.tasks.FetchExistingLibrariesWithNewerVersions import org.graalvm.internal.tck.DockerTask import org.graalvm.internal.tck.ConfigFilesChecker import org.graalvm.internal.tck.ScaffoldTask import org.graalvm.internal.tck.GrypeTask import org.graalvm.internal.tck.TestedVersionUpdaterTask import org.graalvm.internal.tck.harness.tasks.CheckstyleInvocationTask +import org.graalvm.internal.tck.harness.tasks.FetchExistingLibrariesWithNewerVersionsTask import org.graalvm.internal.tck.harness.tasks.TestInvocationTask @@ -164,7 +164,7 @@ Provider generateMatrixDiffCoordinates = tasks.register("generateMatrixDif } // groovy tasks -tasks.register("fetchExistingLibrariesWithNewerVersions", FetchExistingLibrariesWithNewerVersions.class) { task -> +tasks.register("fetchExistingLibrariesWithNewerVersions", FetchExistingLibrariesWithNewerVersionsTask.class) { task -> task.setGroup(METADATA_GROUP) task.setDescription("Returns list of all libraries coordinates") task.setAllLibraryCoordinates(matchingCoordinates) diff --git a/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tasks/FetchExistingLibrariesWithNewerVersions.groovy b/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/tasks/FetchExistingLibrariesWithNewerVersionsTask.groovy similarity index 97% rename from tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tasks/FetchExistingLibrariesWithNewerVersions.groovy rename to tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/tasks/FetchExistingLibrariesWithNewerVersionsTask.groovy index 455f23223..67dbf2bfc 100644 --- a/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tasks/FetchExistingLibrariesWithNewerVersions.groovy +++ b/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/tasks/FetchExistingLibrariesWithNewerVersionsTask.groovy @@ -1,4 +1,5 @@ -package org.graalvm.internal.tasks +package org.graalvm.internal.tck.harness.tasks + import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.core.type.TypeReference @@ -16,7 +17,7 @@ import java.util.regex.Matcher import java.util.regex.Pattern -abstract class FetchExistingLibrariesWithNewerVersions extends DefaultTask { +abstract class FetchExistingLibrariesWithNewerVersionsTask extends DefaultTask { @Input List allLibraryCoordinates diff --git a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java index ad39ab896..26726a7b2 100644 --- a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java +++ b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java @@ -7,58 +7,57 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import org.graalvm.internal.tck.model.MetadataVersionsIndexEntry; + import org.gradle.api.DefaultTask; +import org.gradle.api.file.RegularFileProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.OutputFiles; import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.options.Option; import org.gradle.util.internal.VersionNumber; import java.io.File; import java.io.IOException; -import java.util.Arrays; import java.util.Comparator; import java.util.List; public abstract class TestedVersionUpdaterTask extends DefaultTask { - private final ObjectMapper objectMapper = new ObjectMapper() - .enable(SerializationFeature.INDENT_OUTPUT) - .setSerializationInclusion(JsonInclude.Include.NON_NULL); - @Option(option = "coordinates", description = "GAV coordinates of the library") - void setCoordinates(String coordinates) { - this.coordinates = coordinates; - } - - @Option(option = "lastSupportedVersion", description = "Last version of the library that passed tests") - void setLastSupportedVersion(String version) { - this.lastSupportedVersion = version; - } - - private String coordinates; - private String lastSupportedVersion; - - - @TaskAction - void run() throws IllegalStateException, IOException { - String[] coordinatesParts = coordinates.split(":"); + void setCoordinates(String c) { + String[] coordinatesParts = c.split(":"); if (coordinatesParts.length != 3) { throw new IllegalArgumentException("Maven coordinates should have 3 parts"); } String group = coordinatesParts[0]; String artifact = coordinatesParts[1]; String version = coordinatesParts[2]; - Coordinates c = new Coordinates(group, artifact, version); - addToMetadataIndexJson(c); + Coordinates coordinates = new Coordinates(group, artifact, version); + + getIndexFile().set(getProject().file(CoordinateUtils.replace("metadata/$group$/$artifact$/index.json", coordinates))); + getNewVersion().set(version); } - private void addToMetadataIndexJson(Coordinates c) throws IOException { - File coordinatesMetadataIndex = getProject().file(CoordinateUtils.replace("metadata/$group$/$artifact$/index.json", c)); - List entries = objectMapper.readValue(coordinatesMetadataIndex, new TypeReference<>() { - }); + @Input + @Option(option = "lastSupportedVersion", description = "Last version of the library that passed tests") + protected abstract Property getLastSupportedVersion(); + + @Input + protected abstract Property getNewVersion(); + + @OutputFiles + protected abstract RegularFileProperty getIndexFile(); + + @TaskAction + void run() throws IllegalStateException, IOException { + File coordinatesMetadataIndex = getIndexFile().get().getAsFile(); + ObjectMapper objectMapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT).setSerializationInclusion(JsonInclude.Include.NON_NULL); + List entries = objectMapper.readValue(coordinatesMetadataIndex, new TypeReference<>() {}); for (MetadataVersionsIndexEntry entry : entries) { - if (entry.testedVersions().contains(lastSupportedVersion)) { - entry.testedVersions().add(c.version()); + if (entry.testedVersions().contains(getLastSupportedVersion().get())) { + entry.testedVersions().add(getNewVersion().get()); entry.testedVersions().sort(Comparator.comparing(VersionNumber::parse)); } } From 055b61adee67cd5f05a639fdbaad534b5d7059ff Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Fri, 8 Nov 2024 14:47:19 +0100 Subject: [PATCH 21/23] Rename function that extracts information from provided coordinates --- .../java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java index 26726a7b2..87163c3bf 100644 --- a/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java +++ b/tests/tck-build-logic/src/main/java/org/graalvm/internal/tck/TestedVersionUpdaterTask.java @@ -25,7 +25,7 @@ public abstract class TestedVersionUpdaterTask extends DefaultTask { @Option(option = "coordinates", description = "GAV coordinates of the library") - void setCoordinates(String c) { + void extractInformationFromCoordinates(String c) { String[] coordinatesParts = c.split(":"); if (coordinatesParts.length != 3) { throw new IllegalArgumentException("Maven coordinates should have 3 parts"); From 2c2ad05bba38a3a3331c56854febe6724a343523 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Fri, 8 Nov 2024 14:58:05 +0100 Subject: [PATCH 22/23] Use abstract getters for properties in the fetching task --- ...etchExistingLibrariesWithNewerVersionsTask.groovy | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/tasks/FetchExistingLibrariesWithNewerVersionsTask.groovy b/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/tasks/FetchExistingLibrariesWithNewerVersionsTask.groovy index 67dbf2bfc..fed4c2776 100644 --- a/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/tasks/FetchExistingLibrariesWithNewerVersionsTask.groovy +++ b/tests/tck-build-logic/src/main/groovy/org/graalvm/internal/tck/harness/tasks/FetchExistingLibrariesWithNewerVersionsTask.groovy @@ -8,6 +8,8 @@ import com.fasterxml.jackson.databind.SerializationFeature import groovy.json.JsonOutput import org.graalvm.internal.tck.model.MetadataVersionsIndexEntry import org.gradle.api.DefaultTask +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.options.Option @@ -20,11 +22,11 @@ import java.util.regex.Pattern abstract class FetchExistingLibrariesWithNewerVersionsTask extends DefaultTask { @Input - List allLibraryCoordinates + abstract ListProperty getAllLibraryCoordinates() @Input @Option(option = "matrixLimit", description = "Sets the maximum number of coordinates in the final matrix") - Integer matrixLimit + abstract Property getMatrixLimit() private static final List INFRASTRUCTURE_TESTS = List.of("samples", "org.example") @@ -32,7 +34,7 @@ abstract class FetchExistingLibrariesWithNewerVersionsTask extends DefaultTask { void action() { // get all existing libraries Set libraries = [] - allLibraryCoordinates.forEach { + getAllLibraryCoordinates().get().forEach { libraries.add(it.substring(0, it.lastIndexOf(":"))) } @@ -48,8 +50,8 @@ abstract class FetchExistingLibrariesWithNewerVersionsTask extends DefaultTask { } } - if (newerVersions.size() > getMatrixLimit()) { - newerVersions = newerVersions.subList(0, getMatrixLimit()) + if (newerVersions.size() > getMatrixLimit().get()) { + newerVersions = newerVersions.subList(0, getMatrixLimit().get()) } def matrix = [ From 2d614b8b7098c02d7d9aaab72bbb4a4cd534cd9a Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Tue, 12 Nov 2024 12:43:31 +0100 Subject: [PATCH 23/23] Add a doc file that explains how the scan works --- .../workflows/check-new-library-versions.yml | 4 +- .../check-new-versions-of-libraries.md | 51 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 docs/Infrastructure/check-new-versions-of-libraries.md diff --git a/.github/workflows/check-new-library-versions.yml b/.github/workflows/check-new-library-versions.yml index f94046584..d88780c8f 100644 --- a/.github/workflows/check-new-library-versions.yml +++ b/.github/workflows/check-new-library-versions.yml @@ -1,5 +1,7 @@ name: "Check new library versions" +# The workflow runs bi-weekly alternating with the scheduled release workflow. This way we have enough time to provide metadata for failing tests. +# In case we need more scans, there is a possibility to trigger the workflow manually. on: schedule: - cron: "0 0 8 * *" @@ -139,4 +141,4 @@ jobs: git config --local user.name "Github Actions" git fetch origin check-new-library-versions/$(date '+%Y-%m-%d') git checkout check-new-library-versions/$(date '+%Y-%m-%d') - gh pr create --title "Update supported library versions" --body "This pull request updates supported versions of the existing libraries in the repo" \ No newline at end of file + gh pr create --title "Update supported library versions" --body "This pull request updates supported versions of the existing libraries in the repo" diff --git a/docs/Infrastructure/check-new-versions-of-libraries.md b/docs/Infrastructure/check-new-versions-of-libraries.md new file mode 100644 index 000000000..79c97e54b --- /dev/null +++ b/docs/Infrastructure/check-new-versions-of-libraries.md @@ -0,0 +1,51 @@ +# Check new versions of existing libraries in the repository + +As the number of libraries in the repository grow fast, it is hard to track new library versions for every library manually. +Instead of doing this process manually, we provided a mechanism (through [a GitHub workflow](https://github.com/oracle/graalvm-reachability-metadata/blob/master/.github/workflows/check-new-library-versions.yml)) +that automatically scans MavenCentral repository for new versions of the libraries that we currently have. + +## How it works + +The workflow gets triggered every two weeks automatically (alternating to the automatic release weeks). Besides that, the job can be triggered manually from the GitHub actions. +The whole process consists of the following parts: +* Scanning of the MavenCentral +* Running existing tests with newer versions of the library +* Creating a pull-request that updates `tested-versions` field of the `index.json` file for libraries that passed tests with a new version +* Creating an issue that lists all versions of libraries that failed their existing tests. + +As a preparation for the whole process, we are creating a branch for all successful tests, and a single issue for all failed tests. + +### Scanning the MavenCentral + +At first, the workflow runs gradle task called `fetchExistingLibrariesWithNewerVersions`. +The task itself does the following: +1. Gets the list of all existing libraries in the repository +2. For each library, it searches for the latest tested version in the corresponding library `index.json` file +3. For the given library name, it fetches `maven-metadata.xml` file from the MavenCentral repository +4. In the fetched `maven-metadata.xml` file, it finds the position of the latest tested version (gathered in the step 3) and returns all the versions after it +5. As a last step, the task returns list of maven coordinates of libraries with newer versions (alongside java version and os version required for testing) + +### Running existing tests with newer versions + +Now that we have coordinates list, we are spawning a new job in GitHub workflow for each coordinate in the list. +Each of the spawned jobs: +1. Extracts the following parts from the given maven coordinates: + 1. Latest version that we have tests written for + 2. Path to the latest tests we have + 3. Maven coordinates of the latest tests +2. Sets `GVM_TCK_LV` env variable to the version we want to test. This way the executed tests will use library version specified in the env variable. +3. Run the latest test with `./gradlew test -Pcoordinates=` (with `testCoordinates` calculated in the step 1) + +### Aggregating results of the tests + +Based on the outcome of the test we: +* Update the list of `tested-versions` in the proper library `index.json` file and commit changes to the previously created branch, if the test passed +* Add a comment that explains which library version cannot pass the tests, in the issue we previously created + +Note: since the spawned jobs run tests in parallel, we have to make some kind of synchronization to avoid merge conflicts if two tests are populating the same `index.json` file. +The whole process of synchronization is driven by the [tryPushVersionsUpdate](https://github.com/oracle/graalvm-reachability-metadata/blob/master/.github/workflows/tryPushVersionsUpdate.sh) script. + +At the end, when all jobs have finished their executions, the workflow just creates a pull-request based on a branch the jobs committed to. +As a final result, we have: +* a pull-request with updates of all new tested versions +* an issue with list of all versions that doesn't work with existing metadata