From b45154d31e3d9ebe2d736c43154918b45d3a391f Mon Sep 17 00:00:00 2001 From: Davide Angelocola Date: Sun, 28 Jun 2026 08:25:47 +0200 Subject: [PATCH 1/3] ci: smoke-test published releases on every supported OS/arch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a manually-triggered workflow that pulls a released version from Maven Central and runs a JBang smoke test on one GitHub-hosted runner per native classifier: linux-x86_64 (ubuntu-latest), linux-aarch64 (ubuntu-24.04-arm), osx-x86_64 (macos-13), osx-aarch64 (macos-14), windows-x86_64 (windows-latest), windows-aarch64 (windows-11-arm). The smoke (.github/smoke/Smoke.java) exercises a core compress/decompress round-trip plus a dictionary train + round-trip, so it proves the bundled native library actually loads and works on real hardware for each arch — not a source build (no zig, no submodule), exactly what users consume. Verified locally end-to-end on osx-aarch64 against 0.6 (core 40000 -> 38 bytes, dictionary round-trip passed, zstd 1.5.7). Co-Authored-By: Claude Opus 4.8 --- .github/smoke/Smoke.java | 56 +++++++++++++++++++++++++++++ .github/workflows/release-smoke.yml | 51 ++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 .github/smoke/Smoke.java create mode 100644 .github/workflows/release-smoke.yml diff --git a/.github/smoke/Smoke.java b/.github/smoke/Smoke.java new file mode 100644 index 0000000..fee1f38 --- /dev/null +++ b/.github/smoke/Smoke.java @@ -0,0 +1,56 @@ +///usr/bin/env jbang "$0" "$@" ; exit $? +//JAVA 25 +//RUNTIME_OPTIONS --enable-native-access=ALL-UNNAMED +// Dependencies are supplied at run time via `jbang --deps ...` so the workflow +// can pin the released version and the per-arch native jar from the matrix. + +import io.github.dfa1.zstd.Zstd; +import io.github.dfa1.zstd.ZstdCompressCtx; +import io.github.dfa1.zstd.ZstdDecompressCtx; +import io.github.dfa1.zstd.ZstdDictionary; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/// Smoke test for a published zstd-java release: proves the bundled native +/// library loads on the host OS/arch and the core + dictionary paths work. +/// Run against a release from Maven Central, one arch per CI matrix leg. +public class Smoke { + + public static void main(String[] args) { + String platform = System.getProperty("os.name") + "/" + System.getProperty("os.arch"); + + // 1. Core round-trip — proves the native library loaded and compress/decompress work. + byte[] original = "the quick brown fox ".repeat(2000).getBytes(); + byte[] compressed = Zstd.compress(original, 9); + byte[] restored = Zstd.decompress(compressed); + if (!Arrays.equals(original, restored)) { + throw new AssertionError("core round-trip mismatch on " + platform); + } + if (compressed.length >= original.length) { + throw new AssertionError("expected compression to shrink the input on " + platform); + } + + // 2. Dictionary round-trip — exercises the ZDICT training path (the library's differentiator). + List samples = new ArrayList<>(); + for (int i = 0; i < 2000; i++) { + samples.add(("{\"id\":" + i + ",\"user\":\"user_" + (i % 100) + "\",\"event\":\"click\"}").getBytes()); + } + ZstdDictionary dict = ZstdDictionary.train(samples, 8 * 1024); + try (ZstdCompressCtx cctx = new ZstdCompressCtx(); + ZstdDecompressCtx dctx = new ZstdDecompressCtx()) { + byte[] message = samples.get(7); + byte[] dictCompressed = cctx.compress(message, dict); + byte[] dictRestored = dctx.decompress(dictCompressed, message.length, dict); + if (!Arrays.equals(message, dictRestored)) { + throw new AssertionError("dictionary round-trip mismatch on " + platform); + } + } + + System.out.println("OK " + platform + + " | zstd " + Zstd.version() + + " | core " + original.length + " -> " + compressed.length + " bytes" + + " | dictionary round-trip passed"); + } +} diff --git a/.github/workflows/release-smoke.yml b/.github/workflows/release-smoke.yml new file mode 100644 index 0000000..b37f955 --- /dev/null +++ b/.github/workflows/release-smoke.yml @@ -0,0 +1,51 @@ +name: Release smoke test + +# Verifies a PUBLISHED release on Maven Central actually loads and runs on every +# supported OS/arch — one runner per native classifier. Pulls the release jars +# from Central (no source build, no submodule, no zig), so it tests exactly what +# users consume. Trigger manually and pass the version to check. + +on: + workflow_dispatch: + inputs: + version: + description: Released version to smoke-test (as published to Maven Central) + required: true + default: "0.6" + +permissions: + contents: read + +jobs: + smoke: + name: ${{ matrix.classifier }} + strategy: + fail-fast: false + matrix: + include: + - { os: ubuntu-latest, classifier: linux-x86_64 } + - { os: ubuntu-24.04-arm, classifier: linux-aarch64 } + - { os: macos-13, classifier: osx-x86_64 } + - { os: macos-14, classifier: osx-aarch64 } + - { os: windows-latest, classifier: windows-x86_64 } + - { os: windows-11-arm, classifier: windows-aarch64 } + runs-on: ${{ matrix.os }} + steps: + - name: Checkout (smoke sources only) + uses: actions/checkout@v4 + + - name: Set up JDK 25 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '25' + + - name: Set up JBang + uses: jbangdev/setup-jbang@main + + - name: Smoke-test ${{ inputs.version }} on ${{ matrix.classifier }} + shell: bash + run: | + jbang --java 25 \ + --deps "io.github.dfa1.zstd:zstd:${{ inputs.version }},io.github.dfa1.zstd:zstd-native-${{ matrix.classifier }}:${{ inputs.version }}" \ + .github/smoke/Smoke.java From 71a92b8bb82f3a37ad1e2c5e4842b70559e8a6b0 Mon Sep 17 00:00:00 2001 From: Davide Angelocola Date: Sun, 28 Jun 2026 08:27:46 +0200 Subject: [PATCH 2/3] ci: default release smoke to the latest Maven Central version Make the version input optional: leave it blank to auto-resolve the latest release from zstd's maven-metadata.xml (), or pass a specific version to override. A resolve job picks the version and feeds it to the matrix. Verified the metadata fetch returns 0.6. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/release-smoke.yml | 36 +++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release-smoke.yml b/.github/workflows/release-smoke.yml index b37f955..10e3a8a 100644 --- a/.github/workflows/release-smoke.yml +++ b/.github/workflows/release-smoke.yml @@ -9,16 +9,40 @@ on: workflow_dispatch: inputs: version: - description: Released version to smoke-test (as published to Maven Central) - required: true - default: "0.6" + description: Version to smoke-test. Leave blank to use the latest release on Maven Central. + required: false + default: "" permissions: contents: read jobs: + resolve: + name: resolve version + runs-on: ubuntu-latest + outputs: + version: ${{ steps.pick.outputs.version }} + steps: + - name: Resolve version (input, else latest on Maven Central) + id: pick + shell: bash + run: | + version="${{ inputs.version }}" + if [ -z "$version" ]; then + # in maven-metadata.xml is the latest non-snapshot release. + version=$(curl -fsSL https://repo1.maven.org/maven2/io/github/dfa1/zstd/zstd/maven-metadata.xml \ + | grep -oE '[^<]+' | sed -E 's/<\/?release>//g') + fi + if [ -z "$version" ]; then + echo "could not resolve a version from Maven Central" >&2 + exit 1 + fi + echo "Smoke-testing version: $version" + echo "version=$version" >> "$GITHUB_OUTPUT" + smoke: name: ${{ matrix.classifier }} + needs: resolve strategy: fail-fast: false matrix: @@ -43,9 +67,11 @@ jobs: - name: Set up JBang uses: jbangdev/setup-jbang@main - - name: Smoke-test ${{ inputs.version }} on ${{ matrix.classifier }} + - name: Smoke-test ${{ needs.resolve.outputs.version }} on ${{ matrix.classifier }} shell: bash + env: + VERSION: ${{ needs.resolve.outputs.version }} run: | jbang --java 25 \ - --deps "io.github.dfa1.zstd:zstd:${{ inputs.version }},io.github.dfa1.zstd:zstd-native-${{ matrix.classifier }}:${{ inputs.version }}" \ + --deps "io.github.dfa1.zstd:zstd:${VERSION},io.github.dfa1.zstd:zstd-native-${{ matrix.classifier }}:${VERSION}" \ .github/smoke/Smoke.java From 712d3ae4720de43e9ffd80823e0c1be877defaea Mon Sep 17 00:00:00 2001 From: Davide Angelocola Date: Sun, 28 Jun 2026 08:28:50 +0200 Subject: [PATCH 3/3] ci: run the release smoke test weekly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a Monday 06:00 UTC schedule. Scheduled runs carry no input, so the resolve job auto-picks the latest Maven Central release — catching Central or runner-image drift against the published artifact without a manual run. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/release-smoke.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/release-smoke.yml b/.github/workflows/release-smoke.yml index 10e3a8a..b617150 100644 --- a/.github/workflows/release-smoke.yml +++ b/.github/workflows/release-smoke.yml @@ -12,6 +12,11 @@ on: description: Version to smoke-test. Leave blank to use the latest release on Maven Central. required: false default: "" + schedule: + # Weekly, Mondays 06:00 UTC. No input on scheduled runs, so the resolve job + # picks the latest release on Maven Central — catches Central / runner-image + # drift against the published release without a manual trigger. + - cron: "0 6 * * 1" permissions: contents: read