Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
with:
distribution: 'temurin'
java-version: 21
- name: Set up JDK ${{ matrix.java.version }}
- name: Set up JDK ${{ matrix.jdk }}
uses: actions/setup-java@v5
with:
distribution: 'temurin'
Expand All @@ -33,5 +33,50 @@ jobs:
run: mkdir ~/.gradle && echo "org.gradle.java.home=$JAVA_HOME_21_X64" >> ~/.gradle/gradle.properties
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v6

# Build conformance test artifacts locally.
- name: Create publish-helper init script
run: |
cat > "$RUNNER_TEMP/publish-helper.gradle" <<'INIT'
allprojects {
pluginManager.apply('maven-publish')
tasks.withType(Sign).configureEach { enabled = false }
}
INIT
# conformance-tests (the assertions/samples ZIP) comes from the main JSpecify repo.
- name: Check out JSpecify
uses: actions/checkout@v6
with:
repository: jspecify/jspecify
path: jspecify
- name: Build and install conformance-tests
working-directory: jspecify
run: ./gradlew --init-script "$RUNNER_TEMP/publish-helper.gradle" :conformance-tests:publishToMavenLocal
# conformance-test-framework (the test driver) comes from the JSpecify reference checker.
- name: Check out JSpecify reference checker
uses: actions/checkout@v6
with:
repository: jspecify/jspecify-reference-checker
path: jspecify-reference-checker
# The settings.gradle isolates the sub-project and avoids building the CF.
- name: Build and install conformance-test-framework
working-directory: jspecify-reference-checker
run: |
cat > conformance-test-framework/settings.gradle <<'SETTINGS'
rootProject.name = 'conformance-test-framework'
dependencyResolutionManagement {
versionCatalogs {
libs {
library('guava', 'com.google.guava:guava:33.6.0-jre')
library('jspecify', 'org.jspecify:jspecify:1.0.0')
library('truth', 'com.google.truth:truth:1.4.5')
library('junit', 'junit:junit:4.13.2')
}
}
}
SETTINGS
./gradlew --project-dir conformance-test-framework \
--init-script "$RUNNER_TEMP/publish-helper.gradle" publishToMavenLocal

- name: Build and Test
run: gradle build test
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ with the [EISOP Nullness Checker](https://eisop.github.io/cf/manual/#nullness-ch

2. Gradle Assemble:
```bash
./gradlew assmble
./gradlew assemble
```

3. Run the Tests:
Expand Down
30 changes: 28 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,23 @@ plugins {
}

repositories {
// Snapshot repository for JSpecify conformance test framework
maven { url = 'https://central.sonatype.com/repository/maven-snapshots/' }
// The JSpecify conformance test framework and test suite are only ever published as
// 'org.jspecify.conformance:*:0.0.0-SNAPSHOT'. Central Portal snapshots are deleted after
// 90 days (https://central.sonatype.org/publish/publish-portal-snapshots/), so this remote
// snapshot can disappear whenever upstream stops re-publishing it. mavenLocal() lets us fall
// back to a copy that the build (see the CI workflow) publishes from a JSpecify checkout,
// which keeps the build reproducible regardless of the remote snapshot's lifetime.
mavenLocal()
// Snapshot repository for the JSpecify conformance test framework and test suite. Scope it to
// the 'org.jspecify.conformance' group so this repository is never consulted (or able to serve
// stale/unexpected artifacts) for any other dependency.
maven {
name = 'Central Portal Snapshots'
url = 'https://central.sonatype.com/repository/maven-snapshots/'
content {
includeGroup('org.jspecify.conformance')
}
}
mavenCentral()
}

Expand All @@ -33,6 +48,10 @@ dependencies {

testImplementation libs.jspecify.conformance.framework
jSpecifyConformanceTests libs.jspecify.conformance.tests

// The conformance test directly uses Guava (Splitter, ImmutableList/Set/SortedSet). Depend on it
// explicitly rather than relying on it leaking in transitively from the conformance framework.
testImplementation libs.guava
}

// To use a locally-built Checker Framework, run gradle with "-PcfLocal".
Expand Down Expand Up @@ -146,6 +165,13 @@ test {
exceptionFormat = "full"
}

// NOTE: addTestListener is NOT honored when the configuration cache is enabled
// (see https://github.com/gradle/gradle/issues/25311). Because this project enables the
// configuration cache in gradle.properties, the diagnostics below only run when the build is
// invoked with --no-configuration-cache. The `testLogging` block above is the configuration-cache
// -safe way to surface failures; this listener adds the extra "code around the failure" context
// for local debugging runs. A future change could move this to a BuildService-based
// OperationCompletionListener to make it configuration-cache compatible.
addTestListener(new TestListener() {
void beforeSuite(TestDescriptor suite) {}
void afterSuite(TestDescriptor suite, TestResult result) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private void runConformanceTests(
Path reportPath = getSystemPropertyPath(reportPathProperty);
ImmutableList<Path> deps =
depsProperty != null
? Splitter.on(":").splitToList(depsProperty).stream()
? Splitter.on(':').omitEmptyStrings().splitToList(depsProperty).stream()
.map(Paths::get)
.collect(toImmutableList())
: ImmutableList.of(); // for conformance samples, creates an empty immutable list
Expand Down