From 5b8a0618d08f757d41ede27feecdebaee1423149 Mon Sep 17 00:00:00 2001 From: Mathieu Bastian Date: Sun, 8 Nov 2026 20:16:06 +0100 Subject: [PATCH] Use gephi-plugins-tests 1.2.0 and report its warnings (#374) Checks that only warn (a layout adding nodes, a statistics without a user interface...) don't fail the run: run.sh turns the warnings the tests write to contract-warnings.tsv into ::warning:: annotations and, on GitHub Actions, a table in the job summary. The jars of the modules that depend on the tested one are put on the test classpath, so a plugin whose user interface is in another module (e.g. BoundingDiameters) has it found. Co-authored-by: Claude Sonnet 5.5 --- .github/contract-tests/pom.xml | 4 +- .github/contract-tests/run.sh | 68 +++++++++++++++++++++++++++++++++- AGENTS.md | 3 +- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/.github/contract-tests/pom.xml b/.github/contract-tests/pom.xml index 6872d46cf..d70d903a7 100644 --- a/.github/contract-tests/pom.xml +++ b/.github/contract-tests/pom.xml @@ -14,7 +14,7 @@ UTF-8 - 1.1.0 + 1.2.0 ${plugin.artifactId}-${plugin.version}.jar + + ${project.build.directory}/contract-warnings.tsv org.gephi:gephi-plugins-tests diff --git a/.github/contract-tests/run.sh b/.github/contract-tests/run.sh index 724cbed58..2adc2836b 100755 --- a/.github/contract-tests/run.sh +++ b/.github/contract-tests/run.sh @@ -6,7 +6,9 @@ # # With no arguments, every module in the root pom.xml's list is tested. Otherwise only # NBM modules under the given folders are; a folder outside the reactor (e.g. a disabled plugin) -# is skipped with a warning. Modules must be installed in the local Maven repository first +# is skipped with a warning. Checks that are only advisory (e.g. a layout adding nodes) don't fail +# the run: they are reported as warning annotations, and in the job summary when running on GitHub +# Actions. Modules must be installed in the local Maven repository first # (mvn install): a module that is missing there, or was rebuilt since, fails instead of testing a # stale jar. set -euo pipefail @@ -75,6 +77,44 @@ if [ ${#TARGETS[@]} -eq 0 ]; then exit 0 fi +# Advisory test warnings, one "plugincheckmessage" entry each +WARNINGS_FILE="$HARNESS_DIR/target/contract-warnings.tsv" +WARNINGS=() + +# Workflow command data can't contain %, the warnings are single lines already +annotation_escape() { + printf '%s' "$1" | sed -e 's/%/%25/g' +} + +# Plugin names and messages come from the plugin's code, so don't let them format the summary +markdown_escape() { + printf '%s' "$1" | sed -e 's/&/\&/g' -e 's//\>/g' -e 's/|/\\|/g' -e 's/`/\\`/g' +} + +collect_warnings() { + [ -f "$WARNINGS_FILE" ] || return 0 + local check message + while IFS=$'\t' read -r check message; do + WARNINGS+=("$1"$'\t'"$check"$'\t'"$message") + echo "::warning title=SPI contract test warning::$(annotation_escape "$1: $check: $message")" + done < "$WARNINGS_FILE" +} + +# The jars of the modules that depend on the one being tested, installed in the local repository. A plugin split in +# modules keeps parts of it (e.g. its user interface) in modules that depend on the main one, and the tests look +# those up too. +dependent_jars() { + local packaging group artifact version basedir repo jar + while IFS='|' read -r packaging group artifact version basedir _ repo; do + [ "$packaging" = nbm ] || continue + [ "$artifact" != "$1" ] || continue + grep -q "$1" "$basedir/pom.xml" || continue + jar="$repo/${group//.//}/$artifact/$version/$artifact-$version.jar" + [ -f "$jar" ] && echo "$jar" + done <<< "$PROJECTS" + return 0 +} + PASSED=() FAILED=() for target in "${TARGETS[@]}"; do @@ -92,20 +132,44 @@ for target in "${TARGETS[@]}"; do continue fi + EXTRA_ARGS=() + EXTRA_JARS=$(dependent_jars "$artifact" | paste -sd, -) + if [ -n "$EXTRA_JARS" ]; then + EXTRA_ARGS=(-Dmaven.test.additionalClasspath="$EXTRA_JARS") + fi + rm -rf "$HARNESS_DIR/target" echo "::group::Contract tests: $gav" if mvn -B -ntp -f "$HARNESS_DIR/pom.xml" test -Dgephi.version="$GEPHI_VERSION" \ - -Dplugin.groupId="$group" -Dplugin.artifactId="$artifact" -Dplugin.version="$version"; then + -Dplugin.groupId="$group" -Dplugin.artifactId="$artifact" -Dplugin.version="$version" \ + ${EXTRA_ARGS[@]+"${EXTRA_ARGS[@]}"}; then echo "::endgroup::" else echo "::endgroup::" echo "::error::SPI contract tests failed for $gav" + collect_warnings "$gav" FAILED+=("$gav") continue fi + collect_warnings "$gav" PASSED+=("$gav") done +if [ ${#WARNINGS[@]} -gt 0 ] && [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then + { + echo "### SPI contract test warnings" + echo + echo "These checks don't fail the build, but are worth a look in review." + echo + echo "| Plugin | Check | Warning |" + echo "| --- | --- | --- |" + for warning in "${WARNINGS[@]}"; do + IFS=$'\t' read -r gav check message <<< "$warning" + echo "| $(markdown_escape "$gav") | $(markdown_escape "$check") | $(markdown_escape "$message") |" + done + } >> "$GITHUB_STEP_SUMMARY" +fi + if [ ${#PASSED[@]} -gt 0 ]; then echo "SPI contract tests passed for: ${PASSED[*]}" fi diff --git a/AGENTS.md b/AGENTS.md index 83d1be150..616df2c2c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -25,7 +25,8 @@ Requires JDK 17 and Maven. - Build/test a single plugin module: `mvn -pl modules/ clean package` - Run a single module's unit tests only: `mvn -pl modules/ test` - Run the SPI contract tests CI runs (from `gephi-plugins-tests`) on a module, after `mvn install`: - `.github/contract-tests/run.sh modules/` + `.github/contract-tests/run.sh modules/`. A failing check fails the run; advisory checks + (e.g. a layout adding nodes) only print `::warning::` lines and, in CI, a job summary table. - Run Gephi with the module(s) installed (build first): `mvn org.gephi:gephi-maven-plugin:run` - IDE run/debug configs are defined in `nbactions.xml`; the IntelliJ debug setup (remote debugger + `-Drun.params.debug` VM option) is documented in `README.md`.