2020 pull_request :
2121 types : [opened, synchronize, reopened]
2222 branches : [master]
23+
24+ # Java Version Strategy:
25+ # - BUILD: Requires Java 17+ (JUnit 6 dependency)
26+ # - RUNTIME: Supports Java 11+ (javac.version=11 produces Java 11 bytecode)
27+ #
28+ # The 'build' job verifies bytecode compilation for both Java 11 and 17 targets.
29+ # The 'runtime-java11' job verifies the built artifacts actually run on Java 11.
30+ # The 'tests' job runs on JDK 17 (required by JUnit 6) with the default
31+ # javac.version=11 bytecode target for backward compatibility.
32+
2333jobs :
2434 javadoc :
2535 strategy :
4353 ${{ runner.os }}-ivy-
4454 - name : Javadoc
4555 run : ant clean javadoc -buildfile build.xml
56+
4657 rat :
4758 strategy :
4859 matrix :
@@ -73,19 +84,108 @@ jobs:
7384 - name : Fail if any unknown licenses
7485 if : ${{ env.UNKNOWN_LICENSES != '0 Unknown Licenses' }}
7586 run : exit 1
87+
88+ # Build verification with Java bytecode target matrix
89+ # Verifies bytecode compatibility for both Java 11 and Java 17 targets
90+ build :
91+ strategy :
92+ fail-fast : false
93+ matrix :
94+ javac-version : ['11', '17']
95+ os : [ubuntu-latest]
96+ runs-on : ${{ matrix.os }}
97+ name : build (javac.version=${{ matrix.javac-version }})
98+ steps :
99+ - uses : actions/checkout@v5
100+ - name : Set up JDK 17
101+ uses : actions/setup-java@v5
102+ with :
103+ java-version : ' 17'
104+ distribution : ' temurin'
105+ - name : Cache Ivy dependencies
106+ uses : actions/cache@v4
107+ with :
108+ path : ~/.ivy2/cache
109+ key : ${{ runner.os }}-ivy-${{ hashFiles('ivy/ivy.xml', 'src/plugin/**/ivy.xml') }}
110+ restore-keys : |
111+ ${{ runner.os }}-ivy-
112+ - name : Build with javac.version=${{ matrix.javac-version }}
113+ run : ant clean runtime -Djavac.version=${{ matrix.javac-version }} -buildfile build.xml
114+ - name : Verify bytecode version
115+ run : |
116+ # Extract and verify the bytecode version of compiled classes
117+ # Java 11 = major version 55, Java 17 = major version 61
118+ EXPECTED_VERSION=${{ matrix.javac-version == '11' && '55' || '61' }}
119+ echo "Expected major version: $EXPECTED_VERSION (Java ${{ matrix.javac-version }})"
120+
121+ # Find a real class file (exclude package-info.class which may have different version)
122+ cd build/classes
123+ CLASS_FILE=$(find . -name "*.class" ! -name "package-info.class" | head -1)
124+ if [ -n "$CLASS_FILE" ]; then
125+ echo "Checking: $CLASS_FILE"
126+ ACTUAL_VERSION=$(javap -verbose "$CLASS_FILE" 2>/dev/null | grep "major version" | awk '{print $NF}')
127+ echo "Actual major version: $ACTUAL_VERSION"
128+ if [ "$ACTUAL_VERSION" != "$EXPECTED_VERSION" ]; then
129+ echo "ERROR: Bytecode version mismatch!"
130+ exit 1
131+ fi
132+ echo "Bytecode version verified successfully"
133+ else
134+ echo "ERROR: No class files found"
135+ exit 1
136+ fi
137+
138+ # Verify runtime compatibility on Java 11
139+ # This ensures the built artifacts can actually run on Java 11
140+ runtime-java11 :
141+ needs : build
142+ runs-on : ubuntu-latest
143+ steps :
144+ - uses : actions/checkout@v5
145+ - name : Set up JDK 17 for building
146+ uses : actions/setup-java@v5
147+ with :
148+ java-version : ' 17'
149+ distribution : ' temurin'
150+ - name : Cache Ivy dependencies
151+ uses : actions/cache@v4
152+ with :
153+ path : ~/.ivy2/cache
154+ key : ${{ runner.os }}-ivy-${{ hashFiles('ivy/ivy.xml', 'src/plugin/**/ivy.xml') }}
155+ restore-keys : |
156+ ${{ runner.os }}-ivy-
157+ - name : Build with Java 11 target
158+ run : ant clean runtime -Djavac.version=11 -buildfile build.xml
159+ - name : Set up JDK 11 for runtime verification
160+ uses : actions/setup-java@v5
161+ with :
162+ java-version : ' 11'
163+ distribution : ' temurin'
164+ - name : Verify runtime on Java 11
165+ run : |
166+ echo "Verifying Nutch can run on Java 11..."
167+ java -version
168+ cd runtime/local
169+ # Actually load Java classes by running showproperties
170+ # This invokes org.apache.nutch.tools.ShowProperties and verifies the JAR loads
171+ bin/nutch showproperties | head -20
172+ echo "Java 11 runtime verification complete"
173+
174+ # Tests run on JDK 17 (required by JUnit 6) with default javac.version=11
175+ # Java 11 runtime compatibility is verified by the runtime-java11 job
76176 tests :
77177 strategy :
178+ fail-fast : false
78179 matrix :
79- java : ['17']
80180 os : [ubuntu-latest, macos-latest]
81181 runs-on : ${{ matrix.os }}
82182 timeout-minutes : 45
83183 steps :
84184 - uses : actions/checkout@v5
85- - name : Set up JDK ${{ matrix.java }}
185+ - name : Set up JDK 17
86186 uses : actions/setup-java@v5
87187 with :
88- java-version : ${{ matrix.java }}
188+ java-version : ' 17 '
89189 distribution : ' temurin'
90190 - name : Cache Ivy dependencies
91191 uses : actions/cache@v4
@@ -104,6 +204,8 @@ jobs:
104204 - 'src/testresources/**'
105205 plugins:
106206 - 'src/plugin/**'
207+ indexer_plugins:
208+ - 'src/plugin/indexer-*/**'
107209 buildconf:
108210 - 'build.xml'
109211 - 'ivy/ivy.xml'
@@ -120,16 +222,35 @@ jobs:
120222 - name : test plugins
121223 if : ${{ steps.filter.outputs.plugins == 'true' && steps.filter.outputs.core == 'false' && steps.filter.outputs.buildconf == 'false' }}
122224 run : ant clean test-plugins -buildfile build.xml
123- # fallback: run all tests if no specific filter matched (e.g., docs-only changes)
124- - name : test all (fallback)
125- if : ${{ steps.filter.outputs.buildconf == 'false' && steps.filter.outputs.core == 'false' && steps.filter.outputs.plugins == 'false' }}
126- run : ant clean test -buildfile build.xml
225+ # run indexer integration tests when indexer plugin files change (Docker required, ubuntu-latest only)
226+ - name : test indexer integration
227+ if : ${{ steps.filter.outputs.indexer_plugins == 'true' && matrix.os == 'ubuntu-latest' }}
228+ run : ant clean test-indexer-integration -buildfile build.xml
229+ - name : Check for test results
230+ id : check_tests
231+ if : always() && matrix.os == 'ubuntu-latest'
232+ run : |
233+ shopt -s globstar nullglob
234+ files=(./build/test/TEST-*.xml ./build/**/test/TEST-*.xml)
235+ if [ ${#files[@]} -gt 0 ]; then
236+ echo "has_results=true" >> $GITHUB_OUTPUT
237+ else
238+ echo "has_results=false" >> $GITHUB_OUTPUT
239+ fi
127240 - name : Upload Test Report
128241 uses : actions/upload-artifact@v4
129- if : always()
242+ if : always() && matrix.os == 'ubuntu-latest' && steps.check_tests.outputs.has_results == 'true'
130243 with :
131244 name : junit-test-results-${{ matrix.os }}
132245 path : |
133246 ./build/test/TEST-*.xml
134247 ./build/**/test/TEST-*.xml
135- retention-days : 1
248+ retention-days : 1
249+ - name : Upload Coverage Data
250+ uses : actions/upload-artifact@v4
251+ if : always() && matrix.os == 'ubuntu-latest'
252+ with :
253+ name : coverage-data
254+ path : ./build/coverage/*.exec
255+ retention-days : 1
256+ if-no-files-found : ignore
0 commit comments