Skip to content

Commit f467d37

Browse files
committed
Add build arguments to ci.json
1 parent d1b88d0 commit f467d37

File tree

4 files changed

+91
-86
lines changed

4 files changed

+91
-86
lines changed

.github/workflows/test-all-metadata.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ name: "Test all metadata"
22

33
on:
44
workflow_dispatch:
5+
pull_request:
6+
branches:
7+
- master
8+
paths:
9+
- 'ci.json'
510

611
concurrency:
712
group: "workflow = ${{ github.workflow }}, ref = ${{ github.event.ref }}, pr = ${{ github.event.pull_request.id }}"
@@ -56,7 +61,7 @@ jobs:
5661
native-image-job-reports: 'true'
5762
- name: "Pull allowed docker images"
5863
run: |
59-
./gradlew pullAllowedDockerImagesMatching -Pcoordinates=${{ matrix.coordinates }}
64+
./gradlew pullAllowedDockerImages -Pcoordinates=${{ matrix.coordinates }}
6065
- name: "Disable docker networking"
6166
run: bash ./.github/workflows/disable-docker.sh
6267
- name: "🧪 Run '${{ matrix.coordinates }}' tests"

ci.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"buildArgs": ["-verbose", "-Ob"],
23
"generateMatrixBatchedCoordinates": {
34
"java": ["17", "21", "25", "latest-ea"],
45
"os": ["ubuntu-latest"]

tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck-harness.gradle

Lines changed: 61 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import org.graalvm.internal.tck.ContributionTask
1515
import org.graalvm.internal.tck.DockerTask
1616
import org.graalvm.internal.tck.ConfigFilesChecker
1717
import org.graalvm.internal.tck.DockerUtils
18-
import org.graalvm.internal.tck.PullImagesFromFileTask
1918
import org.graalvm.internal.tck.ScaffoldTask
2019
import org.graalvm.internal.tck.GrypeTask
2120
import org.graalvm.internal.tck.TestedVersionUpdaterTask
@@ -28,6 +27,7 @@ import org.graalvm.internal.tck.harness.tasks.NativeTestCompileInvocationTask
2827
import org.graalvm.internal.tck.updaters.FetchExistingLibrariesWithNewerVersionsTask
2928
import org.graalvm.internal.tck.updaters.GroupUnsupportedLibraries
3029
import org.gradle.util.internal.VersionNumber
30+
import org.graalvm.internal.tck.PullImagesFromFileTask
3131

3232

3333
import static org.graalvm.internal.tck.Utils.generateTaskName
@@ -47,28 +47,28 @@ def writeGithubOutput(String key, String value) {
4747
String coordinateFilter = Objects.requireNonNullElse(project.findProperty("coordinates"), "")
4848

4949
// Support fractional batching coordinates in the form "k/n" (e.g., "1/16")
50-
boolean isFractionalBatch(String s) {
50+
static boolean isFractionalBatch(String s) {
5151
return s != null && (s ==~ /\d+\/\d+/)
5252
}
5353

54-
List<Integer> parseFraction(String s) {
54+
static List<Integer> parseFraction(String s) {
5555
def m = s =~ /(\d+)\/(\d+)/
5656
if (!m.matches()) return null
5757
int k = (m[0][1] as int)
5858
int n = (m[0][2] as int)
5959
return [k, n]
6060
}
6161

62-
List<String> computeBatchedCoordinates(List<String> allCoords, int k, int n) {
63-
if (n <= 0) throw new GradleException("Invalid batches denominator: ${n}")
64-
if (k < 1 || k > n) throw new GradleException("Invalid batch index: ${k}/${n}")
65-
def sorted = new ArrayList<String>(allCoords)
66-
java.util.Collections.sort(sorted)
67-
int target = (k - 1)
62+
static List<String> computeBatchedCoordinates(List<String> coordinates, int index, int batches) {
63+
if (batches <= 0) throw new GradleException("Invalid batches denominator: ${batches}")
64+
if (index < 1 || index > batches) throw new GradleException("Invalid batch index: ${index}/${batches}")
65+
def sorted = new ArrayList<String>(coordinates)
66+
Collections.sort(sorted)
67+
int target = (index - 1)
6868
def result = []
6969
int i = 0
7070
for (String c : sorted) {
71-
if ((i % n) == target) {
71+
if ((i % batches) == target) {
7272
result.add(c)
7373
}
7474
i++
@@ -79,10 +79,8 @@ List<String> computeBatchedCoordinates(List<String> allCoords, int k, int n) {
7979
List<String> matchingCoordinates
8080
if (isFractionalBatch(coordinateFilter)) {
8181
def frac = parseFraction(coordinateFilter)
82-
int k = frac[0]
83-
int n = frac[1]
8482
List<String> all = tck.getMatchingCoordinates("all")
85-
matchingCoordinates = computeBatchedCoordinates(all, k, n)
83+
matchingCoordinates = computeBatchedCoordinates(all, frac[0], frac[1])
8684
} else {
8785
matchingCoordinates = tck.getMatchingCoordinates(coordinateFilter)
8886
}
@@ -123,76 +121,8 @@ tasks.named("check").configure {
123121

124122
final String METADATA_GROUP = "Metadata"
125123

126-
Provider<Task> pullAllowedDockerImagesMatching = tasks.register("pullAllowedDockerImagesMatching", DefaultTask) { task ->
127-
task.setDescription("Pull allowed docker images for all matching coordinates")
128-
task.setGroup(METADATA_GROUP)
129-
task.doFirst {
130-
if (matchingCoordinates == null || matchingCoordinates.isEmpty()) {
131-
throw new GradleException("No matching coordinates found for property 'coordinates'. Provide -Pcoordinates=<filter> or a fractional batch 'k/n'.")
132-
}
133-
println "Pulling allowed docker images for ${matchingCoordinates.size()} coordinate(s):"
134-
matchingCoordinates.each { c -> println(" - ${c}") }
135-
}
136-
}
137124

138-
// Collect unique required images across matching coordinates and filter by allowed list
139-
tasks.register("collectRequiredAllowedDockerImagesMatching", DefaultTask) { task ->
140-
task.setDescription("Collect unique allowed docker images required by matching coordinates into a file")
141-
task.setGroup(METADATA_GROUP)
142-
File out = new File(buildDir, "required-docker-images-union.txt")
143-
// Declare the output so Gradle can track it
144-
task.outputs.file(out)
145-
task.doFirst {
146-
if (matchingCoordinates == null || matchingCoordinates.isEmpty()) {
147-
throw new GradleException("No matching coordinates found for property 'coordinates'. Provide -Pcoordinates=<filter> or a fractional batch 'k/n'.")
148-
}
149-
Set<String> unionRequired = new LinkedHashSet<>()
150-
matchingCoordinates.each { c ->
151-
def parts = c.split(":")
152-
if (parts.length < 3) {
153-
logger.warn("Skipping invalid coordinates: ${c}")
154-
return
155-
}
156-
def group = parts[0]
157-
def artifact = parts[1]
158-
def version = parts[2]
159-
File f = project.file("tests/src/${group}/${artifact}/${version}/required-docker-images.txt")
160-
if (f.exists()) {
161-
f.readLines()
162-
.collect { it?.trim() }
163-
.findAll { it && !it.startsWith("#") }
164-
.each { unionRequired.add(it) }
165-
}
166-
}
167125

168-
Set<String> allowed = DockerUtils.getAllAllowedImages()
169-
def notAllowed = unionRequired.findAll { !allowed.contains(it) }
170-
if (!notAllowed.isEmpty()) {
171-
throw new GradleException("The following images are not in the allowed list: ${notAllowed}. " +
172-
"If you need them, add Dockerfiles under tests/tck-build-logic/src/main/resources/allowed-docker-images " +
173-
"per CONTRIBUTING.md, or adjust required-docker-images.txt files.")
174-
}
175-
176-
out.parentFile.mkdirs()
177-
def finalList = unionRequired.findAll { allowed.contains(it) }.toList()
178-
out.text = finalList.join(System.lineSeparator())
179-
println "Collected ${finalList.size()} required allowed image(s):"
180-
finalList.each { println(" - ${it}") }
181-
}
182-
}
183-
184-
// Pull the collected unique images (once)
185-
tasks.register("pullRequiredAllowedDockerImagesMatching", PullImagesFromFileTask.class) { task ->
186-
task.setDescription("Pull unique allowed docker images required by matching coordinates")
187-
task.setGroup(METADATA_GROUP)
188-
task.dependsOn("collectRequiredAllowedDockerImagesMatching")
189-
task.imagesFile.set(new File(buildDir, "required-docker-images-union.txt"))
190-
}
191-
192-
// Rewire the aggregate to depend on the unique pull task
193-
pullAllowedDockerImagesMatching.configure {
194-
dependsOn("pullRequiredAllowedDockerImagesMatching")
195-
}
196126

197127
// Here we want to configure all test and checkstyle tasks for all filtered subprojects
198128
for (String coordinates in matchingCoordinates) {
@@ -422,9 +352,57 @@ tasks.register("checkAllowedDockerImages", GrypeTask.class) { task ->
422352
task.setGroup(METADATA_GROUP)
423353
}
424354

425-
tasks.register("pullAllowedDockerImages", DockerTask.class) { task ->
426-
task.setDescription("Pull allowed docker images from list.")
355+
def imagesFileProvider = project.layout.buildDirectory.file("tck/required-docker-images.txt")
356+
357+
def computeImages = tasks.register("computeAllowedDockerImagesFile", DefaultTask) { task ->
358+
task.setDescription("Computes allowed docker images required by matching coordinates and writes them to a file")
359+
task.setGroup(METADATA_GROUP)
360+
task.outputs.file(imagesFileProvider)
361+
task.doFirst {
362+
if (matchingCoordinates == null || matchingCoordinates.isEmpty()) {
363+
throw new GradleException("No matching coordinates found for property 'coordinates'. Provide -Pcoordinates=<filter> or a fractional batch 'k/n'.")
364+
}
365+
Set<String> unionRequired = new LinkedHashSet<>()
366+
matchingCoordinates.each { c ->
367+
def parts = c.split(":")
368+
if (parts.length < 3) {
369+
logger.warn("Skipping invalid coordinates: ${c}")
370+
return
371+
}
372+
def group = parts[0]
373+
def artifact = parts[1]
374+
def version = parts[2]
375+
File f = project.file("tests/src/${group}/${artifact}/${version}/required-docker-images.txt")
376+
if (f.exists()) {
377+
f.readLines()
378+
.collect { it?.trim() }
379+
.findAll { it && !it.startsWith("#") }
380+
.each { unionRequired.add(it) }
381+
}
382+
}
383+
384+
Set<String> allowed = DockerUtils.getAllAllowedImages()
385+
def notAllowed = unionRequired.findAll { !allowed.contains(it) }
386+
if (!notAllowed.isEmpty()) {
387+
throw new GradleException("The following images are not in the allowed list: ${notAllowed}. " +
388+
"If you need them, add Dockerfiles under tests/tck-build-logic/src/main/resources/allowed-docker-images " +
389+
"per CONTRIBUTING.md, or adjust required-docker-images.txt files.")
390+
}
391+
392+
def finalList = unionRequired.findAll { allowed.contains(it) }.toList()
393+
println "Collected ${finalList.size()} required allowed image(s)"
394+
File outFile = imagesFileProvider.get().asFile
395+
outFile.parentFile.mkdirs()
396+
outFile.text = finalList.join(System.lineSeparator())
397+
}
398+
}
399+
400+
tasks.register("pullAllowedDockerImages", PullImagesFromFileTask.class) { task ->
401+
task.setDescription("Pull allowed docker images required by matching coordinates")
427402
task.setGroup(METADATA_GROUP)
403+
task.getImagesFile().set(imagesFileProvider)
404+
}.configure { t ->
405+
t.dependsOn(computeImages)
428406
}
429407

430408

tests/tck-build-logic/src/main/groovy/org.graalvm.internal.tck.gradle

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*/
77

88

9+
import groovy.json.JsonSlurper
10+
911
plugins {
1012
id 'org.graalvm.internal.tck-base'
1113
id 'checkstyle'
@@ -51,6 +53,26 @@ String overrideVal = System.getenv("GVM_TCK_EXCLUDE") ?: providers.gradlePropert
5153
overrideVal = overrideVal ?: "false"
5254
boolean override = overrideVal.toBoolean()
5355

56+
// Determine native-image build arguments from ci.json.
57+
def ciJsonFile = rootProject.file("ci.json")
58+
def nativeImageArgs = []
59+
if (ciJsonFile.exists()) {
60+
try {
61+
def parsed = new JsonSlurper().parse(ciJsonFile)
62+
def argsFromCi = parsed?.buildArgs
63+
if (argsFromCi instanceof Collection && !argsFromCi.isEmpty()) {
64+
nativeImageArgs = argsFromCi.collect { it.toString() }
65+
// Post-process placeholders in args
66+
nativeImageArgs = nativeImageArgs.collect { arg ->
67+
arg.replace('{{library.version}}', libraryVersion)
68+
.replace('{{library.coordinates}}', libraryGAV)
69+
}
70+
}
71+
} catch (Exception ignored) {
72+
throw new GradleException("ci.json must contain the buildArgs")
73+
}
74+
}
75+
5476
tck.testedLibraryVersion = libraryVersion
5577
// This value can be used to request specific library version to test with.
5678

@@ -78,8 +100,7 @@ graalvmNative {
78100
if (override) {
79101
excludeConfig.put(libraryGAV, [".*"])
80102
}
81-
verbose = true
82-
quickBuild = true
103+
buildArgs.addAll(nativeImageArgs)
83104
}
84105
}
85106
}

0 commit comments

Comments
 (0)