diff --git a/.github/workflows/conformance.yml b/.github/workflows/conformance.yml
new file mode 100644
index 0000000..8bf9afc
--- /dev/null
+++ b/.github/workflows/conformance.yml
@@ -0,0 +1,31 @@
+name: Zarr Conformance Tests
+
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: '17 3 * * 0'
+ pull_request:
+ branches: [ "main" ]
+
+jobs:
+ conformance-tests:
+ runs-on: ubuntu-latest
+ env:
+ GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
+ steps:
+ - uses: actions/checkout@v5
+
+ - name: Set up JDK
+ uses: actions/setup-java@v4
+ with:
+ java-version: '11'
+ distribution: 'temurin'
+ cache: maven
+
+ - name: Build
+ run: mvn package -DskipTests
+
+ - name: Run Conformance Tests
+ uses: Bisaloo/zarr-conformance-tests@v0.0.1
+ with:
+ zarr-cli: "java -jar target/zarr-java-0.0.9.jar"
diff --git a/.gitignore b/.gitignore
index fcafa91..4c52107 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,4 +45,5 @@ build/
/main.py
/pyproject.toml
/uv.lock
-**/__pycache__
\ No newline at end of file
+**/__pycache__
+/dependency-reduced-pom.xml
diff --git a/pom.xml b/pom.xml
index 3df9b78..5adcaa9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -121,6 +121,12 @@
4.13.1
test
+
+
+ info.picocli
+ picocli
+ 4.7.6
+
@@ -231,6 +237,26 @@
true
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.5.0
+
+
+ package
+
+ shade
+
+
+
+
+ dev.zarr.zarrjava.cli.Main
+
+
+
+
+
+
diff --git a/src/main/java/dev/zarr/zarrjava/cli/Main.java b/src/main/java/dev/zarr/zarrjava/cli/Main.java
new file mode 100644
index 0000000..1d18cfb
--- /dev/null
+++ b/src/main/java/dev/zarr/zarrjava/cli/Main.java
@@ -0,0 +1,44 @@
+package dev.zarr.zarrjava.cli;
+
+import dev.zarr.zarrjava.core.Array;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.concurrent.Callable;
+
+@Command(name = "zarr-java-cli", mixinStandardHelpOptions = true, version = "1.0", description = "CLI wrapper for zarr-java conformance tests.")
+public class Main implements Callable {
+
+ @Option(names = { "--array_path" }, description = "Path to the Zarr array", required = true)
+ private String arrayPath;
+
+ @Override
+ public Integer call() throws Exception {
+ try {
+ Path path = Paths.get(arrayPath);
+ // Attempt to open the array. This should throw if the array is invalid or
+ // cannot be opened.
+ Array array = Array.open(path);
+
+ // Read the entire array
+ ucar.ma2.Array data = array.read();
+
+ // Print the array values using ucar.ma2.Array's string representation.
+ System.out.println(data.toString());
+
+ return 0;
+ } catch (Exception e) {
+ System.err.println("Failed to open array at " + arrayPath);
+ e.printStackTrace();
+ return 1;
+ }
+ }
+
+ public static void main(String[] args) {
+ int exitCode = new CommandLine(new Main()).execute(args);
+ System.exit(exitCode);
+ }
+}