Release

A release is a Git tag. Pushing the tag starts the release workflows. This repository releases two packages: arcadedb-jvm (the JVM build) with release-jvm.yml, and arcadedb (the native build) with release-native.yml. Each release workflow calls the test workflow of its build (test-jvm.yml, test-native.yml), checks the wheels and publishes them to PyPI with trusted publishing. The workflows store no token. The sections below describe release-jvm.yml; the native release is in Native release.

Version numbering

The tag is the bare version, with no v. The tag, the wheel version and the PyPI version are the same string.

Version Meaning

26.11.1.dev0, 26.11.1.dev1, …​

A preview of engine release 26.11.1, built from the upstream snapshot jars. devN starts at 0.

26.11.1

The release. The wheels ship the 26.11.1 engine jar.

26.11.1.post1, 26.11.1.post2, …​

A fix in the Python code of the released 26.11.1. The wheels still ship the 26.11.1 engine jar. postN starts at 1.

The rule has five parts:

  • The order for one base A.B.C is A.B.C.dev0, .dev1, …​, then A.B.C, then A.B.C.post1, .post2, …​.

  • aN, bN and rcN are never used, previews included.

  • devN starts again at 0 when the base A.B.C changes.

  • A number is never reused and never skipped. PyPI refuses a version it has seen, even after a delete. The next number is one above the highest published number of that base.

  • A devN of a released base is refused, because it would sort before the release. A postN of a base that is not released is refused.

The base is the version of the engine. The workflow compares the tag with the version of the engine jar in the wheels, and it refuses a devN tag for a release jar and a release tag for a snapshot jar.

How the rule is enforced

scripts/check_version.py checks the rule. It reads the published versions from the Git tags of the repository and from PyPI, and it never changes anything:

python3 scripts/check_version.py 26.11.1.dev0 --git-remote origin --pypi arcadedb-jvm

It exits 0 when the version is the correct next one, 1 when it is not, and 2 when a source cannot be read. Exit 2 is a failure, not a pass: the check fails closed.

The first job of each release workflow runs the same command on the pushed tag. When it fails, the workflow builds and publishes nothing. Run it by hand before you push the tag. Running the whole workflow again for a version that is already on PyPI fails the check on purpose. To retry a failed upload, re-run only the publish job.

The tests of the script are in tests/test_check_version.py.

After the tag push

scripts/after_tag_verify.sh checks the finished arcadedb-jvm release (the run of release-jvm.yml). It only reads from GitHub and PyPI:

scripts/after_tag_verify.sh 26.11.1 26.10.1 <release-run-id>

The second argument is the previous release. Use - for the first release of the package. The script checks:

  • The workflow run, and the conclusion of the publish job and of its upload step.

  • The files on PyPI: one py3-none wheel for each platform (the same file for every Python version), each under 100 MB, none yanked.

  • The sha256 of every file on PyPI against the wheels the workflow checked.

  • A pip download for each of the four platforms, and a fresh install on Python 3.12 and 3.14 that opens a database and runs one SQL and one openCypher query.

It prints PASS or FAIL for each step, and its exit code is the number of failures.

Native release

The two packages release from two workflows with two PyPI environments:

Package Workflow GitHub environment

arcadedb-jvm

release-jvm.yml

pypi-jvm

arcadedb (native)

release-native.yml

pypi

The version rule above holds for both packages. One tag starts both release workflows, and each one checks the tag against its own PyPI project.

release-native.yml has four jobs:

  1. Validate tag checks that the tag is a bare version and the next one (scripts/check_version.py).

  2. test calls test-native.yml with the full matrix: four platforms, each on Python 3.11 to 3.14. It builds the native image and the wheel on each platform and runs the test suite of this repository against the installed wheel.

  3. Verify what may be published reads which legs passed, applies the readiness gate below and collects the wheels.

  4. Publish to PyPI uploads the wheels through the environment pypi. It refuses any wheel that is not the distribution arcadedb.

arcadedb has one trusted publisher on PyPI (release-native.yml with the environment pypi) for dev, final and post releases, and one publish job in the workflow. arcadedb-jvm has one trusted publisher (release-jvm.yml with the environment pypi-jvm). PyPI matches the workflow file name, so renaming either file means changing the publisher on PyPI first. There is no separate pre-release environment; the readiness gate below is what keeps a final release back.

  • A native pre-release (26.11.1.devN) publishes when the builds on linux-x86_64, linux-aarch64 and macos-arm64 pass.

  • A FINAL native release (A.B.C or A.B.C.postN) needs two more things:

    • The repository variable ARCADEDB_NATIVE_READINESS_BAR_MET is true. A maintainer sets it after checking the readiness bar: the correctness fixes are merged; the full suite is green on every platform, Windows included, and on Python 3.11 to 3.14; the fault and concurrency probes pass; and the documented API raises no NotOnNativeYet.

    • The parity run of every platform and every Python version passes with zero NotOnNativeYet skips.

  • Speed parity with the JVM build is not part of the bar.