From e6b215f197b9fdf8ed3e95bd23b39c19f6d8cc99 Mon Sep 17 00:00:00 2001 From: venkat1701 Date: Mon, 5 Oct 2026 05:23:46 +0530 Subject: [PATCH 1/3] ci: build release archives and images when a version tag is pushed Runs only on v* tags. Builds the Linux native executable and a JVM bundle, pushes the amd64 image to ghcr.io, joins it with an arm64 image when one was pushed for the same version, and drafts the GitHub release with checksums. --- .github/workflows/release.yml | 127 ++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a20f3b5 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,127 @@ +name: release + +on: + push: + tags: ['v*'] + +permissions: + contents: write + packages: write + +env: + IMAGE: ghcr.io/${{ github.repository }} + +jobs: + binaries: + runs-on: ubuntu-latest + timeout-minutes: 40 + steps: + - uses: actions/checkout@v4 + - uses: graalvm/setup-graalvm@v1 + with: + java-version: '25' + distribution: 'graalvm-community' + cache: 'maven' + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Check the tag matches the project version + run: | + version="${GITHUB_REF_NAME#v}" + project="$(./mvnw -q -B -ntp help:evaluate -Dexpression=project.version -DforceStdout)" + [ "$project" = "$version" ] || { echo "tag $GITHUB_REF_NAME does not match project version $project"; exit 1; } + echo "VERSION=$version" >> "$GITHUB_ENV" + - name: Build + run: | + ./mvnw -B -ntp -DskipTests install + ./mvnw -B -ntp -Pnative -DskipTests package -pl server + - name: Package + run: | + mkdir dist + linux="hstore-$VERSION-linux-amd64" + mkdir "$linux" + cp server/target/hstore LICENSE README.md "$linux/" + tar -czf "dist/$linux.tar.gz" "$linux" + jvm="hstore-$VERSION-jvm" + mkdir -p "$jvm/lib" "$jvm/bin" + cp "engine/target/hstore-engine-$VERSION.jar" "database/target/hstore-db-$VERSION.jar" \ + "server/target/hstore-server-$VERSION.jar" "$jvm/lib/" + printf '#!/bin/sh\nexec java -p "$(dirname "$0")/../lib" -m io.hstore.server "$@"\n' > "$jvm/bin/hstore" + chmod +x "$jvm/bin/hstore" + cp LICENSE README.md "$jvm/" + tar -czf "dist/$jvm.tar.gz" "$jvm" + - name: Smoke test + run: | + data="$RUNNER_TEMP/hstore" + "hstore-$VERSION-linux-amd64/hstore" init "$data" --superuser admin --password ci + "hstore-$VERSION-linux-amd64/hstore" exec "$data" examples/clinical-claims.hql > /dev/null + "hstore-$VERSION-jvm/bin/hstore" check "$data" + - uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ + + image: + runs-on: ubuntu-latest + timeout-minutes: 40 + steps: + - uses: actions/checkout@v4 + - run: echo "VERSION=${GITHUB_REF_NAME#v}" >> "$GITHUB_ENV" + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - uses: docker/setup-buildx-action@v3 + - name: Build the amd64 image + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64 + load: true + tags: ${{ env.IMAGE }}:${{ env.VERSION }}-amd64 + labels: | + org.opencontainers.image.title=HStore + org.opencontainers.image.source=https://github.com/${{ github.repository }} + org.opencontainers.image.version=${{ env.VERSION }} + org.opencontainers.image.revision=${{ github.sha }} + org.opencontainers.image.licenses=PolyForm-Noncommercial-1.0.0 + cache-from: type=gha + cache-to: type=gha,mode=max + - name: Start the container and wait for health + run: | + docker run -d --name hstore -e HSTORE_PASSWORD=ci -p 7480:7480 "$IMAGE:$VERSION-amd64" + for _ in $(seq 1 30); do + [ "$(docker inspect -f '{{.State.Health.Status}}' hstore)" = healthy ] && break + sleep 2 + done + docker inspect -f '{{.State.Health.Status}}' hstore | grep -q healthy + curl -fsS http://127.0.0.1:7480/api/info + docker stop hstore + - name: Push and tag the release + run: | + docker push "$IMAGE:$VERSION-amd64" + sources="$IMAGE:$VERSION-amd64" + if docker buildx imagetools inspect "$IMAGE:$VERSION-arm64" > /dev/null 2>&1; then + sources="$sources $IMAGE:$VERSION-arm64" + fi + tags=(-t "$IMAGE:$VERSION") + if [[ "$VERSION" != *-* ]]; then + tags+=(-t "$IMAGE:${VERSION%.*}" -t "$IMAGE:latest") + fi + docker buildx imagetools create "${tags[@]}" $sources + + release: + runs-on: ubuntu-latest + needs: [binaries, image] + timeout-minutes: 10 + steps: + - uses: actions/download-artifact@v4 + with: + name: dist + path: dist + - name: Create a draft release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + (cd dist && sha256sum * > SHA256SUMS) + gh release create "$GITHUB_REF_NAME" dist/* --repo "$GITHUB_REPOSITORY" --draft --verify-tag \ + --title "HStore ${GITHUB_REF_NAME#v}" --generate-notes From 004e28cac4de3fd41690081e696ccfbc1a20bac7 Mon Sep 17 00:00:00 2001 From: venkat1701 Date: Mon, 5 Oct 2026 05:23:46 +0530 Subject: [PATCH 2/3] build: set the version to 0.1.0 --- benchmarks/pom.xml | 2 +- database/pom.xml | 2 +- engine/pom.xml | 2 +- pom.xml | 2 +- server/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index aabc698..5c274f2 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -7,7 +7,7 @@ io.hstore hstore-parent - 0.1.0-SNAPSHOT + 0.1.0 hstore-benchmarks diff --git a/database/pom.xml b/database/pom.xml index ba62eb3..2d6dee4 100644 --- a/database/pom.xml +++ b/database/pom.xml @@ -7,7 +7,7 @@ io.hstore hstore-parent - 0.1.0-SNAPSHOT + 0.1.0 hstore-db diff --git a/engine/pom.xml b/engine/pom.xml index adcd458..7f4140b 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -7,7 +7,7 @@ io.hstore hstore-parent - 0.1.0-SNAPSHOT + 0.1.0 hstore-engine diff --git a/pom.xml b/pom.xml index ac8598e..b0b4b26 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.hstore hstore-parent - 0.1.0-SNAPSHOT + 0.1.0 pom HStore diff --git a/server/pom.xml b/server/pom.xml index acf0787..2a70029 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -7,7 +7,7 @@ io.hstore hstore-parent - 0.1.0-SNAPSHOT + 0.1.0 hstore-server From bbb54efc556275c4b91e174de0084aa3522c5c46 Mon Sep 17 00:00:00 2001 From: venkat1701 Date: Mon, 5 Oct 2026 05:23:46 +0530 Subject: [PATCH 3/3] docs: explain release downloads, images and how to cut a release --- README.md | 19 +++++++++++++++++-- docs/development.md | 23 +++++++++++++++++++++++ docs/operations/docker.md | 15 +++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f0432ef..bfee9a2 100644 --- a/README.md +++ b/README.md @@ -40,15 +40,19 @@ It is written in Java 25 and ships as one GraalVM native executable, `hstore`. ## Quick start with Docker +Images for linux/amd64 and linux/arm64 are published to the GitHub Container Registry with every release: + ``` -docker build -t hstore . docker run -d --name hstore \ -e HSTORE_USER=admin -e HSTORE_PASSWORD=change-me \ -v "$PWD/examples/clinical-claims.hql:/docker-entrypoint-initdb.d/01-clinical-claims.hql:ro" \ -p 7432:7432 -p 7480:7480 \ - hstore + ghcr.io/metacoglabs/hypergraph:0.1.0 ``` +While the repository is private, run `docker login ghcr.io` first with a token that has `read:packages`. To +build the image yourself instead, run `docker build -t hstore .` and use `hstore` as the image name. + * Open **http://localhost:7480** and sign in as `admin` / `change-me` to use HStore Studio. * Open a shell over the wire protocol: `docker exec -it hstore hstore connect 127.0.0.1:7432`. * Follow the server log: `docker logs -f hstore`. @@ -130,6 +134,17 @@ try (HypergraphDatabase database = HypergraphDatabase.open(Path.of("data"))) { } ``` +## Release downloads + +Each [release](https://github.com/metacoglabs/hypergraph/releases) has: + +| File | Contents | +|---|---| +| `hstore--linux-amd64.tar.gz` | native executable for Linux x86-64 | +| `hstore--darwin-arm64.tar.gz` | native executable for Apple silicon Macs | +| `hstore--jvm.tar.gz` | the three module jars and `bin/hstore`, for any OS with Java 25 | +| `SHA256SUMS` | checksums of the archives | + ## Building from source Requires GraalVM for JDK 25. diff --git a/docs/development.md b/docs/development.md index 972751f..c1a1ac5 100644 --- a/docs/development.md +++ b/docs/development.md @@ -196,6 +196,29 @@ java -p engine/target/classes:database/target/classes:server/target/classes \ Reload the browser after each edit. Check syntax with `for f in $(find server/src/main/resources/studio/js -name '*.js'); do node --check "$f"; done`. +## Releasing + +Releases come from a `v` tag on `main`, and the tag has to match the version in the POMs. + +1. Merge a PR that sets the release version in all five POMs and in `Main.VERSION`. +2. Build and push the arm64 image from that commit on an Apple silicon machine. GitHub has no free arm64 runners + for private repositories, and building the native image under emulation takes too long: + + ``` + docker build --platform linux/arm64 -t ghcr.io/metacoglabs/hypergraph:-arm64 . + docker push ghcr.io/metacoglabs/hypergraph:-arm64 + ``` + +3. Push the tag: `git tag -a v -m "HStore " && git push origin v`. + `.github/workflows/release.yml` then: + * builds the Linux native executable and the JVM bundle, and smoke-tests both; + * builds, health-checks and pushes the amd64 image; + * points ``, `.` and `latest` at both architectures (pre-release versions, the ones + containing `-`, only get ``); + * creates a draft release with the archives, `SHA256SUMS` and generated notes. +4. On the Mac, build the native executable and attach it to the draft as `hstore--darwin-arm64.tar.gz`. + Update `SHA256SUMS`, edit the notes and publish. + ## Benchmarks against HyperGraphDB The `benchmarks` module is excluded from the default build because HyperGraphDB is not published to Maven diff --git a/docs/operations/docker.md b/docs/operations/docker.md index 47a4532..356c489 100644 --- a/docs/operations/docker.md +++ b/docs/operations/docker.md @@ -22,6 +22,21 @@ Inside the container, `hstore connect` takes the password from `HSTORE_PASSWORD` environment, so no prompt appears. The user comes from `--user` or `HSTORE_USER`. When `HSTORE_USER` was passed to `docker run`, `docker exec -it hstore hstore connect 127.0.0.1:7432` needs no options at all. +## Getting the image + +Releases are published as `ghcr.io/metacoglabs/hypergraph`, for linux/amd64 and linux/arm64: + +| Tag | Points at | +|---|---| +| `0.1.0` | that exact release | +| `0.1` | the newest `0.1.x` release | +| `latest` | the newest release | +| `0.1.0-amd64`, `0.1.0-arm64` | the single-architecture images behind `0.1.0` | + +While the repository is private, the package is private too: `docker login ghcr.io` with a personal access token +that has `read:packages`. The examples on this page use the name `hstore`, which is what `docker build -t hstore .` +produces. Substitute the registry name to use a released image. + ## Image layout | Path / item | Value |